How Filtering Works
When a visitor changes a filter on your site, WPEnhanced Ajax Filter Blocks updates the result list in place. The page shell, header, and footer stay loaded; only the Archive Loop region (and related UI such as pagination or result counts) is replaced. This page explains that flow from the front-end event to the database query.
High-level flow
sequenceDiagram
participant Visitor
participant FilterUI as Filter Posts UI
participant JS as Plugin JavaScript
participant REST as WordPress REST API
participant PHP as Plugin PHP
participant DB as WordPress DB
Visitor->>FilterUI: Change category / search / price
FilterUI->>JS: Collect active filter values
JS->>REST: POST filter + loop parameters
REST->>PHP: Validate and build WP_Query args
PHP->>DB: Run query
DB-->>PHP: Matching posts/products
PHP-->>REST: Rendered loop HTML + metadata
REST-->>JS: JSON response
JS->>Visitor: Replace loop markup, update URL
The important design choice: filtering is server-authoritative. The browser does not guess which posts match. WordPress runs a real query (via WP_Query or WooCommerce product queries) and returns fresh HTML for the loop template you configured in the Archive Loop block.
The three blocks in the pipeline
| Block | Role in the pipeline |
|---|---|
| Filter Posts Item | Renders a control (select, checkboxes, range slider, search field). Outputs name/value pairs the script reads when filters change. |
| Filter Posts | Aggregates all child items, decides when to trigger an update (on change vs button click), and sends the combined filter payload. |
| Archive Loop | Defines the baseline query (post type, sort, includes/excludes, layout) and receives updated HTML after each successful request. |
Filter items never query the database directly on their own—they declare constraints. The Archive Loop block defines what is being listed. The plugin merges loop settings + active filters into one query per update.
REST-based AJAX
Updates travel through the WordPress REST API, not ad-hoc admin-ajax handlers alone. Benefits include:
- Structured requests and responses — Filter state, pagination, and rendered markup return in predictable JSON fields.
- Caching compatibility — REST routes can be tuned separately from admin endpoints.
- Security integration — Nonces and capability checks follow WordPress REST conventions.
The front-end script serializes:
- Active filter values from each Filter Posts Item
- Archive Loop configuration (post type, sort, template, pagination page)
- Optional selector ID when multiple loops exist on one page
The server responds with:
- HTML for the loop container (posts grid, list rows, empty state)
- Pagination markup when applicable
- Counts or option updates when “update counts” is enabled on the filter panel
- Metadata the script uses to sync the URL or reinitialize third-party scripts
Exact route names and parameters are documented for developers in JavaScript hooks and PHP hooks when those reference pages are available.
How filters become query arguments
Each Filter Posts Item maps to query logic based on its filter source:
| Source (examples) | Typical query effect |
|---|---|
| Category / tag / custom taxonomy | tax_query with selected term slugs or IDs |
| Custom meta key | meta_query with compare operators |
| Search | s search parameter |
| WooCommerce price | Price meta / lookup table constraints |
| WooCommerce attribute | Taxonomy query on pa_* attribute taxonomies |
| Stock / weight | Product meta or WooCommerce stock queries |
Multiple items on one Filter Posts block combine according to each item’s relation settings (for example AND vs OR for multi-select taxonomies). The Archive Loop’s own include/exclude rules (categories fixed at design time, author restrictions, etc.) still apply—they form the baseline query that filters further narrow.
When updates fire
The Filter Posts block Update type controls timing:
| Mode | Behavior |
|---|---|
| On change | Each meaningful interaction (select change, checkbox toggle, range release) triggers a request. Best for responsive UX. |
| Update button | Visitor adjusts several filters, then clicks Search (label customizable). Reduces request volume on heavy pages. |
Search fields often include a typing delay so requests are not sent on every keystroke. Range sliders typically update when the visitor releases the handle.
Pagination and filtering together
Pagination is part of the loop state, not the filter panel. When filters change:
- The query resets to page 1 (unless your configuration preserves page in specific cases).
- The REST response includes pagination markup for the new result set.
- Clicking page 2 sends the same active filters with an updated page number.
If pagination appears to drop filters, the loop and panel may not share the same post type or selector ID—see Filter panel and loop.
URL synchronization
Active filters can be mirrored in the browser address bar as query parameters. That allows:
- Sharing a link with a pre-applied filter set
- Using the back/forward buttons to move through filter history (when enabled)
- Reloading the page without losing the current filter view
Details are covered in URL sync.
Performance considerations
Each filter change runs a server-side query. On large catalogs:
- Keep post count per page reasonable in Archive Loop settings.
- Use Update button mode if a panel has many range or multi-select controls.
- Enable caching options under plugin settings where appropriate.
- WPEnhanced Ajax Filter Blocks Pro offers Catalog Index to speed up option counts and faceted availability on very large WooCommerce catalogs.
Free vs Pro in the pipeline
The AJAX pipeline is the same in free and Pro. Pro adds features that plug into the same request cycle—Load More append mode, conditional filter visibility, Auto Suggest endpoints, map radius constraints, and Catalog Index-backed counts—without replacing the core REST flow.
What's next
- URL sync — Shareable links and browser history
- Filter panel and loop — Wiring multiple panels and loops
- Feature overview — All filter sources and control types