Loading experience
Docs/Djia Filters
Djia Filters Module

Djia Filters

AJAX filter system for any Bricks Query Loop. 15 filter elements, 9 filter types, pre-built index, shared cache and URL sync — for any CPT or WooCommerce archive.

15 filter elements
9 filter types
Any CPT + WooCommerce
Overview

Djia Filters adds a complete AJAX filtering system to Bricks Builder. Drag filter elements onto your page, connect them to a Query Loop and every interaction refreshes results without a page reload — URL synced, indexed and cached.

📌
Djia Filters works with any registered public post type. WooCommerce-specific filter types (price, stock, attribute) require WooCommerce to be active.
🔧
Filter Container Setup

The Filter Container element is the parent wrapper for all filter elements. It connects to your Query Loop via a CSS selector.

1

Add a Filter Container

Drag the Filter Container element anywhere on your page — above, beside or below your listing.

2

Set the target selector

In the Filter Container controls, set Target Selector to the CSS class or ID of your Bricks Query Loop wrapper — e.g. .my-listing. Add a custom class to your Query Loop section first if needed.

3

Add filter elements inside

Place any of the 15 filter elements inside the Filter Container. Configure each one — choose the taxonomy, meta key or WooCommerce attribute.

4

Build the index (recommended)

For best performance run the index builder once. Go to Djia Bricks → Index → Rebuild or use WP-CLI. The index updates automatically on post save.

WP-CLI
# Build index for products wp djia index rebuild --post-type=product # Build for a custom post type wp djia index rebuild --post-type=listing # Check index status wp djia index status # Flush cache wp djia cache flush
🧩
Filter Elements Reference

All 15 filter elements are available in the Bricks element panel under the Djia Filters category.

ElementDescriptionFilter Types
CheckboxesMulti-select filter with result counts per termTaxonomy, Meta
RadioSingle-select filter for taxonomy and meta facetsTaxonomy, Meta
SelectDropdown with optional multi-select modeTaxonomy, WooCommerce
Color SwatchVisual color circles per term — circle or square shapeTaxonomy, Woo attribute
Image SwatchImage per term for fabric, texture or pattern filteringTaxonomy, Woo attribute
Range SliderSingle dual-handle slider for numeric or price rangeMeta, Woo price
Min / Max InputTwo number inputs for precise range entryMeta, Woo price
Toggle ButtonButton group for single or multi-selectTaxonomy, Meta
SearchKeyword search on post title and contentKeyword
Sort / OrderOrder-by dropdown — date, title, price, custom metaSort
Active TagsDisplays active filters with individual clear buttonsAll
Reset / Clear AllClears all active filters in the containerAll
Apply ButtonManual mode — results refresh only on clickManual mode
Offcanvas PanelMobile slide-out filter drawerContainer
Filter GroupCollapsible wrapper for grouping related filtersContainer
🔢
Results & Pagination

These elements display and paginate the filtered results. Place them next to your Query Loop — they update together with the filters, without a page reload.

ElementDescriptionNotes
Results CountShows the number of matching results — e.g. “128 products found”Custom label & “no results” text
PaginationNumbered page links for the filtered result setSyncs with the URL (?paged=2)
Load MoreAppends the next page of results on clickAlternative to numbered pagination
Per PageDropdown to let visitors choose results per pagee.g. 12 / 24 / 48
Use either Pagination or Load More inside one listing — not both. Both read the same query, so combining them can double-render results.
🔀
Filter Types
TypeSourceNotes
TaxonomyAny registered taxonomyAND/OR relation, hide empty, count display
Post MetaAny post meta keyString, numeric or date comparison. ACF, Meta Box, Pods compatible
Woo AttributeWooCommerce attribute (pa_color…)Variation-aware stock counting
Woo Price_price metaAuto min/max boundary detection from indexed data
Woo Stockstock_statusIn stock, out of stock, on backorder
Woo Rating_wc_average_ratingMinimum star rating filter
KeywordPost title + contentConfigurable debounce delay
SortWP_Query orderbyRelevance, date, title, price, or any meta_value
ConditionalOther filter stateShow/hide filter elements based on active filter values
🔗
Hierarchical & Dependent Filters

Djia Filters supports parent → child relationships, so a second filter narrows to only the options that exist under the current selection — e.g. Brand → Model or Region → City. Selecting a parent implies all of its descendants, and the full path is written to the URL.

1

Use a hierarchical taxonomy

Point the filter at a taxonomy that has parent/child terms (e.g. a brand taxonomy where “Giulia” is a child of “Alfa Romeo”).

2

Enable Hierarchy mode

In the filter element controls set Display to Hierarchy (dependent dropdowns). Child options load only after a parent is chosen.

3

Choose depth behaviour

Selecting a parent matches the parent and every descendant. Counts are calculated from the index for the deepest selected term, so they stay accurate at every level.

SettingDescription
RelationParent implies descendants (default) or exact-term-only
Full-path URLWrites the whole path to the URL, e.g. ?brand=alfa-romeo,giulia
Depth labelsOptional label per level (Brand, Model, Trim…)
📌
Hierarchical counts come from the index, not get_term_children(). If counts look wrong after adding terms, rebuild the index (wp djia index rebuild).
Index & Cache

Djia Filters uses a pre-built flat index table to eliminate live taxonomy JOIN queries at filter time. The index auto-updates when posts are saved, updated or deleted.

Index
  • Built once — stored in a dedicated djia_filter_index table
  • Incremental updates — only changed posts are re-indexed on save
  • Supports all public post types and all registered taxonomies + meta keys
  • WP-CLI command for manual rebuilds and status checks
Cache
  • Every unique filter state (URL params) is cached as a transient or object cache entry
  • Shared anonymous cache — all visitors share the same cached response
  • Configurable TTL from 5 minutes to permanent
  • Uses the WordPress object cache when a persistent backend (Redis/Memcached) is available; otherwise falls back to transients
  • AJAX requests bypass full-page cache (WP Rocket, LiteSpeed, Cloudflare)
For stores with 10,000+ products, set cache TTL to 3600s+ and enable object cache (Redis). Repeat filter states will serve in 0ms from cache.
🚀
Cache Warming & Preload

Warming pre-generates cached responses for popular filter combinations so the very first visitor also gets an instant, cache-served result — not just repeat visitors. This is what makes filtering feel instant on large catalogs.

How it works
  • Real visitor filter combinations are recorded as “recipes”, ranked by popularity
  • A background worker replays due recipes and stores their responses in cache
  • Optionally, common combinations can be generated automatically up to a configurable cap
  • Stale entries are re-queued and regenerated on the next run — the cache stays warm without manual work
WP-CLI
# Warm the cache for recorded combinations wp djia preload run # Warm a specific post type wp djia preload run --post-type=product # Show preload status & queue size wp djia preload status # Clear recorded recipes and start fresh wp djia preload reset
Schedule wp djia preload run via server cron (every 15–60 min) on stores with heavy traffic. Combine it with an object cache (Redis) so warmed entries survive and serve in near-0ms.
🛒
WooCommerce Filtering

Djia Filters integrates directly with WooCommerce product archives and custom product loops built with the Bricks Query Loop element.

ℹ️
For WooCommerce price filtering on sites with thousands of products, always build the index first. Raw meta queries on large product tables can be slow without indexing.
📱
Mobile & Offcanvas

On smaller screens, filters can move into a slide-out drawer instead of taking up the top of the page. The Offcanvas Panel keeps the full filter set one tap away without pushing the listing down.

1

Add an Offcanvas Panel

Drop the Offcanvas Panel element on the page and place your filter elements inside it (it acts as a Filter Container too).

2

Set a trigger & breakpoint

Choose the “Filters” button that opens the drawer, and the breakpoint below which the drawer replaces the inline filters.

3

Add an Apply button

On mobile, enable manual mode with an Apply button showing a live result count (“Show 128 results”), so results refresh once instead of on every tap.

ℹ️
Add an Active Tags element inside the drawer so users can see and remove selections before applying.
🌐
Multilingual

Djia Filters works with the major translation plugins. The index and cache are stored per language, so filtering, counts and URLs all stay correct in each language.

PluginSupport
WPMLPer-language index, translated facet labels, language-aware URLs
PolylangPer-language index & cache buckets
TranslatePressActive language detected on every AJAX request
WeglotLanguage resolved from URL / cookie
📌
Facet labels, placeholders and widget texts are registered for translation. After adding a new language, run a full index rebuild so all language rows are populated.
⚙️
Settings Reference
SettingDefaultDescription
cache_ttl3600Seconds before a cache entry expires
cache_drivertransientstransients or object-cache
ajax_debounce300Milliseconds to wait after last interaction before firing AJAX
url_modepushStatepushState or replaceState for URL sync
index_batch200Posts per batch when rebuilding the index
count_displaytrueShow result counts next to filter terms
🧑‍💻
Developer Hooks & Events

Extend and customise filtering behaviour from PHP or JavaScript.

PHP filters
HookPurpose
djia/filter/query_argsModify the final query arguments before results are fetched
djia/filter/facet_optionsAlter the options (and counts) shown for a facet
djia/filter/cache_ttlOverride cache lifetime per request
djia/filter/indexable_metaAdd or remove meta keys included in the index
JavaScript events
  • djia:filter:beforeRefresh — fires before an AJAX request is sent
  • djia:filter:refresh — fires after new results are rendered
  • djia:filter:change — fires when any filter value changes
JavaScript
// Re-init a third-party script after results update document.addEventListener('djia:filter:refresh', function (e) { initMyLazyLoad(); });
🛠️
Troubleshooting & FAQ
ProblemCause & Fix
Filters don’t update the listingThe Target Selector doesn’t match your Query Loop wrapper. Add a custom class to the loop and set the same selector on the Filter Container.
Result counts are wrongIndex is out of date. Run wp djia index rebuild or Djia Bricks → Index → Rebuild.
Price min/max is offBoundaries are read from the index. Rebuild after bulk price changes or importing products.
Old results keep showingCache TTL too long, or a full-page cache is caching the AJAX response. Flush with wp djia cache flush and exclude the AJAX endpoint in your page-cache plugin.
Nothing filters on a custom post typeThe CPT must be public and indexed. Rebuild with --post-type=your_cpt.
Woo price/stock filter missingWooCommerce must be active — those facet types depend on it.
ℹ️
Still stuck? Include your WP + Woo version, the Query Loop’s Target Selector, and whether an object cache is active when you contact support.