{"id":373681,"date":"2026-09-25T03:28:19","date_gmt":"2026-09-25T03:28:19","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/fast-filter-for-woocommerce\/"},"modified":"2026-09-25T03:27:47","modified_gmt":"2026-09-25T03:27:47","slug":"fast-filter-for-woocommerce","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/fast-filter-for-woocommerce\/","author":18610184,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"3.0.1","stable_tag":"3.0.1","tested":"7.1.2","requires":"6.0","requires_php":"8.2","requires_plugins":null,"header_name":"Fast Filter for WooCommerce","header_author":"Sina Ashrafi","header_description":"Fast, accurate, faceted product filter (category hierarchy, attribute range sliders, colour swatches, attribute lists) built for Elementor Pro Loop Grid and WooCommerce archives.","assets_banners_color":"7a70df","last_updated":"2026-09-25 03:27:47","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/fast-filter-for-woocommerce\/","header_author_uri":"https:\/\/profiles.wordpress.org\/ssiinnaa\/","rating":5,"author_block_rating":0,"active_installs":0,"downloads":53,"num_ratings":1,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","changelog"],"tags":{"3.0.1":{"tag":"3.0.1","author":"ssiinnaa","date":"2026-09-25 03:27:47","revision":3712296}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3712296,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3712296,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3712296,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3712296,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3712296,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["3.0.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3712296,"resolution":"1","location":"assets","locale":"","width":1280,"height":1000},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3712296,"resolution":"2","location":"assets","locale":"","width":1280,"height":860},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3712296,"resolution":"3","location":"assets","locale":"","width":390,"height":844},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3712296,"resolution":"4","location":"assets","locale":"","width":1280,"height":900}},"screenshots":{"1":"Sidebar layout: category tree, size sliders (from shipping dimensions), colour swatches and live counts next to a filtered product grid.","2":"Popup layout (Elementor popup \/ off-canvas): OR inside a filter, AND between filters; the Apply button always shows the exact number of matching products.","3":"Mobile: inner-scroll layout with sticky Reset \/ Apply buttons.","4":"Settings page (WooCommerce \u2192 Fast Filter): filters are auto-detected from your product data and can be re-ordered, renamed or added."}},"plugin_section":[],"plugin_tags":[76538,28913,2236,6033,286],"plugin_category":[45],"plugin_contributors":[282620],"plugin_business_model":[],"class_list":["post-373681","plugin","type-plugin","status-publish","hentry","plugin_tags-elementor","plugin_tags-faceted-search","plugin_tags-filter","plugin_tags-product-filter","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-ssiinnaa","plugin_committers-ssiinnaa"],"banners":{"banner":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/banner-772x250.png?rev=3712296","banner_2x":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/banner-1544x500.png?rev=3712296","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/icon.svg?rev=3712296","icon":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/icon.svg?rev=3712296","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/screenshot-1.png?rev=3712296","caption":"Sidebar layout: category tree, size sliders (from shipping dimensions), colour swatches and live counts next to a filtered product grid."},{"src":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/screenshot-2.png?rev=3712296","caption":"Popup layout (Elementor popup \/ off-canvas): OR inside a filter, AND between filters; the Apply button always shows the exact number of matching products."},{"src":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/screenshot-3.png?rev=3712296","caption":"Mobile: inner-scroll layout with sticky Reset \/ Apply buttons."},{"src":"https:\/\/ps.w.org\/fast-filter-for-woocommerce\/assets\/screenshot-4.png?rev=3712296","caption":"Settings page (WooCommerce \u2192 Fast Filter): filters are auto-detected from your product data and can be re-ordered, renamed or added."}],"raw_content":"<!--section=description-->\n<ul>\n<li><strong>Accordion UI<\/strong> \u2013 category tree (hierarchical), size sliders (length \/ width), shape, colour swatches, production type, material. Any source can be added as a list, swatch or range filter from the settings page.<\/li>\n<li><strong>Reads every kind of product data<\/strong> \u2013 global attributes (taxonomies), custom per-product attributes (the text ones on the product edit screen), and shipping dimensions \/ weight (including variations) through a small product index that is kept fresh on every product save.<\/li>\n<li><strong>Full-height layout<\/strong> by default (the Elementor popup scrolls); optional inner-scroll layout with sticky buttons.<\/li>\n<li><strong>Instant Apply<\/strong> \u2013 the result page is prefetched (or prerendered) in the background while the user is still choosing.<\/li>\n<li><strong>OR inside a filter, AND between filters.<\/strong> Counts next to every option are live (facet counts respect all <em>other<\/em> filters) so users never pick an empty combination.<\/li>\n<li><strong>Apply reloads the page<\/strong> with clean URL parameters (<code>?ffwc_color=red,navy&amp;ffwc_length=80-200<\/code>) and filters every Elementor Loop Grid \/ Posts widget whose <em>Query ID<\/em> matches, plus the main WooCommerce product query.<\/li>\n<li><strong>Category aware<\/strong> \u2013 on a category page the category is pre-selected; choosing a sub-category (or another category) navigates to that category URL so the main route stays in sync. Multiple categories inside one branch stay on the branch URL with <code>ffwc_cat=<\/code>; categories from different branches go to the shop page.<\/li>\n<li><strong>Fast<\/strong> \u2013 all counts are grouped SQL, cached in transients and auto-invalidated whenever products or terms change.<\/li>\n<li><strong>Dynamic<\/strong> \u2013 terms, categories, colours and min\/max values are read from the store, never hardcoded.<\/li>\n<\/ul>\n\n<h3>Setup<\/h3>\n\n<ol>\n<li>Activate the plugin (requires WooCommerce; Elementor is optional).<\/li>\n<li>WooCommerce \u2192 Fast Filter: check the auto-detected attribute mapping (length, width, shape, colour, production type, material) and adjust if needed.<\/li>\n<li>In Elementor, add the <strong>Fast Filter<\/strong> widget (category \"Fast Filter\") inside a Popup or any container \u2014 or use the <code>[fast_filter]<\/code> shortcode.<\/li>\n<li>In the Loop Grid widget: Query \u2192 <strong>Query ID<\/strong> = <code>fast_filter<\/code> (configurable).<\/li>\n<li>Optional: Products \u2192 Attributes \u2192 Colour \u2192 edit a term \u2192 \"Swatch colour\" to override the auto-detected colour.<\/li>\n<\/ol>\n\n<h3>Shortcode<\/h3>\n\n<pre><code>[fast_filter filters=\"cat,length,width,shape,color,production_type,material\" nav=\"auto\" counts=\"1\" chips=\"1\" title=\"Filters\"]&lt;h3&gt;Developer hooks&lt;\/h3&gt;\n<\/code><\/pre>\n\n<p>* <code>fast_filter_query_tax_query<\/code> \u2013 filter the tax_query clauses applied to product queries.\n* <code>fast_filter_facet_tax_query<\/code> \/ <code>fast_filter_facet_base_where<\/code> \u2013 adjust facet counting SQL.\n* <code>fast_filter_js_config<\/code> \u2013 adjust the front-end configuration.\n* JS event <code>fastfilter:apply<\/code> on <code>document<\/code> (detail: <code>{ url, state }<\/code>) fires right before navigation.\n* <code>elementor\/query\/{query_id}<\/code> is used for Loop Grid integration; <code>woocommerce_product_query<\/code> for the main query.<\/p>\n\n<!--section=changelog-->\n<h4>3.0.1<\/h4>\n\n<ul>\n<li>WordPress.org review: every option, transient, cron hook, query var and URL parameter now uses the <code>ffwc_<\/code> prefix (URLs read <code>?ffwc_color=red<\/code>), <code>Requires Plugins: woocommerce<\/code> header added, and the settings option declares an array sanitize callback.<\/li>\n<\/ul>\n\n<h4>3.0.0<\/h4>\n\n<ul>\n<li>Requires PHP 8.2+ (tested on PHP 8.5). Code base modernised: strict types, enums, readonly value objects, first-class callables.<\/li>\n<li>Smart queries: one id-set query per request feeds every unselected facet (one grouped query for all flat taxonomies, one per category tree, one for custom attributes); the product count is derived from the same id set.<\/li>\n<li>All filter term lists are stored in a single cache entry, so a page load does one cache read instead of one per filter.<\/li>\n<li>Facet cache entries are keyed by the effective clauses, so the live-count request and the resulting page share the same entry.<\/li>\n<\/ul>\n\n<h4>2.2.2<\/h4>\n\n<ul>\n<li>Fewer per-request queries: no table check \/ status lookups on normal page loads, category link map cached, no id precompute for the empty selection.<\/li>\n<\/ul>\n\n<h4>2.2.1<\/h4>\n\n<ul>\n<li>Index table: prefix indexes + InnoDB so creation no longer fails with \"Specified key was too long\" on utf8mb4\/MyISAM hosts.<\/li>\n<li>No translation calls before <code>init<\/code> (WP 6.7 _load_textdomain_just_in_time notice).<\/li>\n<\/ul>\n\n<h4>2.2.0<\/h4>\n\n<ul>\n<li>Matching product ids are precomputed while the shopper is choosing, so the Loop Grid \/ shop query after Apply is a plain \"ID IN (\u2026)\".<\/li>\n<li>Live counts use a light early-exit endpoint (\/?ffwc_facets=1) instead of the REST API; REST stays as fallback.<\/li>\n<li>Cache warming: sitemap of filter URLs for cache crawlers (\/?ffwc_sitemap=1) and an optional built-in WP-Cron warmer.<\/li>\n<\/ul>\n\n<h4>2.1.0<\/h4>\n\n<ul>\n<li>Shipping dimensions \/ weight are read directly from product meta (variations included) \u2014 no index table required.<\/li>\n<li>Attribute terms with no products are listed greyed out instead of hidden.<\/li>\n<li>Index table creation is verified; failures are shown in admin with the DB error. Index self-builds after plugin updates (no activation needed) and continues without WP-Cron.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Product index: custom (per-product) attributes and shipping dimensions\/weight, incl. variations, as filter sources.<\/li>\n<li>Auto-detection of sources in English and Persian; \"Reset filters to auto-detected defaults\".<\/li>\n<li>Full-height layout by default; inner-scroll layout optional.<\/li>\n<li>Prefetch \/ prerender of the result page for near-instant Apply.<\/li>\n<li>Fixes: Reset kept the old parameters; Apply was disabled when the count was 0; Elementor popup re-initialisation.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Fast, accurate, faceted product filter built for Elementor Pro Loop Grid and WooCommerce archives.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/373681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=373681"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/ssiinnaa"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=373681"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=373681"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=373681"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=373681"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=373681"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=373681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}