JPKCom Post Filter
Faceted navigation and filtering of Posts, Pages, and Custom Post Types via WordPress taxonomies — SEO-friendly URLs, AJAX updates, and full screen reader support.
by Jean Pierre Kolb <jpk@jpkc.com> · github.com/jpkcom/jpkcom-post-filter · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/jpkcom/jpkcom-post-filter/releases/download/v1.4.4/jpkcom-post-filter.zipReadme
JPKCom Post Filter
Plugin Name: JPKCom Post Filter
Plugin URI: https://github.com/JPKCom/jpkcom-post-filter
Description: Faceted navigation and filtering of Posts, Pages, and Custom Post Types via WordPress taxonomies — SEO-friendly URLs, AJAX updates, and full screen reader support.
Version: 1.4.4
Author: Jean Pierre Kolb jpk@jpkc.com
Author URI: https://www.jpkc.com/
Contributors: JPKCom
Tags: filter, taxonomy, faceted search, custom post type, AJAX
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 8.3
Stable tag: 1.4.4
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: jpkcom-post-filter
Domain Path: /languages
Filter any post type by taxonomy terms — SEO-friendly URLs, AJAX, and shortcodes included.
Description
JPKCom Post Filter adds faceted taxonomy filtering to any WordPress archive page or via shortcodes. Visitors can narrow down posts, pages, or custom post types by one or more taxonomy terms, with every filter state reflected in the URL for bookmarking and sharing.
Key Features
- SEO-friendly URL schema — Filter state encoded in the URL path:
/blog/filter/category1+category2/tag1/ - Four filter layouts — Horizontal bar, columns, sidebar, or dropdown with active-count badge
- Three list layouts — Cards (grid), rows (list), or minimal (compact)
- Hybrid rendering — Server-side on first load; AJAX +
history.pushStatewhen JS is available; full page reload fallback when JS is disabled - Auto-inject mode — Automatically wraps theme archive loops with filter UI (no shortcode needed)
- Shortcode mode — Place filter, list, and pagination on archive pages via shortcodes
- Gutenberg Blocks — Three native blocks (Post Filter, Post List, Post Pagination) with live editor preview and full InspectorControls panel
- Elementor Widgets — Three widgets (Post Filter, Post List, Post Pagination) in a dedicated widget category, loaded only when Elementor is active
- Oxygen Builder Elements — Three elements (Post Filter, Post List, Post Pagination) in a custom toolbar section, loaded only when Oxygen Builder Classic is active
- Custom taxonomy creation — Register new WordPress taxonomies directly from the Filter Groups admin page
- Plus/Minus interaction mode — Additive (
+icon) or exclusive (label click) filter selection - Show More button — Collapse long filter lists behind a configurable threshold
- Four color schemes — Default, Dark, Contrast, Monochrome (all overridable)
- Three stylesheet modes — Full plugin CSS, CSS variables only, or fully disabled
- Four-layer caching — Object cache, transients, APCu, and PHP file cache for settings
- Full accessibility —
aria-liveregions,aria-pressedtoggle buttons, screen-reader-only counts - Multi-language — Ships with EN, de_DE, and de_DE_formal translations
- No dependencies — No ACF, no Bootstrap, no jQuery required
Installation
- Upload the
jpkcom-post-filterdirectory to/wp-content/plugins/. - Activate the plugin via Plugins → Installed Plugins.
- Go to Post Filter → General and select the post types to filter.
- Go to Post Filter → Filter Groups and add the taxonomies you want as filter dimensions.
- Go to Settings → Permalinks and click Save Changes to flush rewrite rules.
Configuration
General Settings
| Option | Description |
|---|---|
| Enabled Post Types | Which post types to activate filtering for |
| Auto-Inject Filter | Automatically add filter UI to archive/blog pages per post type |
| URL Endpoint | URL path segment for filter URLs (default: filter) |
| Bare Endpoint Behaviour | What happens when /filter/ is accessed without filter terms: 404, redirect to blog homepage, or custom URL |
| Max Filter Combinations | Maximum simultaneous active filter groups (affects URL and JS) |
| Max. Filters per Group | Maximum terms selectable within one filter group (0 = unlimited) |
| Debug Mode | Use debug-templates/ and write detailed logs to PHP error log |
After changing the URL endpoint go to Settings → Permalinks and click Save, or use the Flush Rewrite Rules button on the General page.
Filter Groups
Each filter group maps a taxonomy to a URL position. Groups are applied in the configured order:
/archive-base/filter/{group-1-slugs}/{group-2-slugs}/
/blog/filter/web-design+marketing/wordpress/
Configure groups at Post Filter → Filter Groups. Each group has:
| Field | Description |
|---|---|
| Taxonomy | Select an existing WP taxonomy, or enable "Register as new taxonomy" to create one |
| Label | Displayed in the filter bar (and as admin label for new taxonomies) |
| Post Types | Which archive pages this group appears on (empty = all enabled post types) |
| Order | Numeric sort position — determines URL segment order |
| Enabled | Toggle group on/off without deleting it |
Creating new taxonomies — When "Register as new WordPress taxonomy" is checked, additional fields appear:
| Field | Description |
|---|---|
| Taxonomy Slug | Unique identifier, lowercase letters and hyphens |
| Rewrite Slug | URL prefix for term archive pages |
| Hierarchical | Category-like (parent/child) or tag-like (flat) |
| Public | Enable frontend term archive pages |
| Admin Column | Show taxonomy as column in post list table |
| REST API | Expose in REST API (required for Gutenberg) |
Warning: Removing a filter group that registered a custom taxonomy will unregister that taxonomy and all term assignments on posts will be permanently lost.
Layout & Design
Post Filter → Layout & Design contains six tabs:
Tab: Global — Default filter layout (bar / columns / sidebar / dropdown), default list layout (cards / rows / minimal), and global spacing/typography variables.
Tab: Filter — Colors and dimensions for filter buttons (default, hover, active state), the reset button, and dropdown panel styling.
Tab: Posts — Card background, border, shadow, radius, padding; grid column counts for desktop, tablet, and mobile; typography and link colors.
Tab: Pagination — Colors for pagination buttons (default, hover, active), border radius, and font size.
Tab: Color Schemes — Choose a preset color scheme. Custom variable overrides from the other tabs are applied on top.
| Scheme | Description |
|---|---|
| Default | WordPress blue accent, light backgrounds |
| Dark | Dark backgrounds, light text, blue accent |
| Contrast | Red reset button for stronger visual differentiation |
| Monochrome | Black, white, and grey only — no color accent |
Tab: Advanced — Stylesheet mode, filter interaction, pagination position, and custom CSS.
| Setting | Options | Description |
|---|---|---|
| Stylesheet Mode | Full / Variables only / Disabled | Full loads the complete plugin CSS; Variables only outputs only the :root block as inline style; Disabled loads nothing |
| Reset Button Visibility | Always / On selection / Never | Controls when the "Reset filters" link is shown |
| Plus/Minus Mode | on/off | Adds +/– icons; clicking the label selects a filter exclusively, clicking + adds it to the current selection |
| Show More Button | on/off + threshold | Hides filters beyond the threshold behind a … toggle (not available in Dropdown layout) |
| Pagination Position | Below / Above / Both | Auto-inject only; shortcode pagination is placed manually |
| Custom CSS | textarea | Additional rules appended after the plugin stylesheet |
Cache & Performance
Enable or disable individual cache layers, set the transient TTL, and clear caches from Post Filter → Cache.
| Layer | Description |
|---|---|
| Object Cache | wp_cache_* for query results; invalidated on save_post / deleted_post |
| Transient Cache | get/set_transient for taxonomy term lists; invalidated on term changes |
| Settings File Cache | PHP include cache in .ht.jpkcom-post-filter-settings/; fastest for settings reads |
Cache TTL applies to transients. Object cache respects the TTL of the active object cache backend.
Import / Export
All plugin settings (general, layout, cache, filter_groups) can be exported as a JSON file and re-imported at Post Filter → Import / Export. Useful for migrating settings between environments.
Shortcodes
Important: Where shortcodes work
Shortcodes always connect to the WordPress archive of the configured post type. When a filter is activated the browser navigates to a URL like /news/filter/slug/ — the base URL is always the post type archive, not the page the shortcode is placed on.
Supported placements:
- Archive template — Embed shortcodes inside an archive template via a page builder or the Gutenberg Full Site Editor. The page IS the archive, so archive URL = current URL.
- Posts Page (post type only) — Assign a WordPress page as the "Posts Page" under Settings → Reading. WordPress treats that page as the blog archive, so
/blog/and the shortcode page are the same URL. - Auto-inject instead — Enable General → Auto-Inject Filter to have the plugin inject the filter UI into archive pages automatically, without any shortcode.
What does not work: Placing shortcodes on an arbitrary custom page (e.g. /test/) whose URL has nothing to do with the post type archive. Filter clicks, AJAX results, and pagination will all redirect to the archive URL, leaving the custom page behind.
[jpkcom_postfilter_filter]
Renders the filter bar.
| Attribute | Values | Default |
|---|---|---|
post_type |
any registered post type | post |
layout |
bar / columns / sidebar / dropdown |
backend setting |
groups |
comma-separated group slugs | all groups |
reset |
true / false / always |
backend setting |
class |
string | — |
The reset attribute overrides the global Reset Button Visibility setting: false forces "never", always forces "always", true uses the backend setting.
[jpkcom_postfilter_list]
Renders the filtered post list.
| Attribute | Values | Default |
|---|---|---|
post_type |
any registered post type | post |
layout |
cards / rows / minimal |
backend setting |
limit |
integer | -1 (all) |
orderby |
date / title / menu_order |
date |
order |
ASC / DESC |
DESC |
class |
string | — |
[jpkcom_postfilter_pagination]
Renders pagination for the filtered list. Must be placed after [jpkcom_postfilter_list]. Returns empty output when there is only one page.
| Attribute | Values | Default |
|---|---|---|
post_type |
any registered post type | post |
class |
string | — |
Example
[jpkcom_postfilter_filter post_type="portfolio" layout="dropdown"]
[jpkcom_postfilter_list post_type="portfolio" layout="cards" limit="12"]
[jpkcom_postfilter_pagination post_type="portfolio"]
Use the interactive shortcode builder at Post Filter → Shortcodes to generate snippets without writing code.
Gutenberg Blocks
Three native Gutenberg blocks are available under the JPKCom Post Filter block category. They work in the classic Block Editor and in the Full Site Editor (FSE).
Post Filter
Renders the filter/facets UI.
| Setting | Options | Default |
|---|---|---|
| Post Type | any registered post type | post |
| Layout | Bar / Sidebar / Dropdown / Columns | backend setting |
| Filter Groups | comma-separated slugs | all groups |
| Reset Button | Default / Always / Never | backend setting |
Post List
Renders the filtered post listing.
| Setting | Options | Default |
|---|---|---|
| Post Type | any registered post type | post |
| Layout | Cards / Rows / Minimal / Theme | backend setting |
| Posts per Page | -1 to 100 | 5 |
| Order By | Date / Title / Menu Order | date |
| Order | ASC / DESC | DESC |
Post Pagination
Renders pagination for the post listing. Can be placed both above and below the Post List block — the plugin pre-scans the block tree before rendering to ensure pagination works at any position. Shows a static preview with example pages in the editor.
| Setting | Options | Default |
|---|---|---|
| Post Type | any registered post type | post |
Block placement notes
- All three blocks must use the same Post Type setting to be paired correctly.
- The filter bar and results zone are paired via
data-jpkpf-post-typeattributes — AJAX filtering works across blocks on the same page. - Pagination blocks placed above the Post List block work correctly: the plugin pre-runs the list query before any block renders.
- In the editor, blocks show a live server-side preview. JS-driven features (Show More, Plus/Minus) are replicated server-side for accurate previews.
Building from source
Block editor scripts require a build step:
npm install
npm run build
Built files are output to blocks/build/. The plugin skips block registration when the build directory is missing.
Elementor Widgets
Three Elementor widgets are available under the JPKCom Post Filter widget category. They are only loaded when Elementor is active.
Post Filter
| Control | Type | Default |
|---|---|---|
| Post Type | Select | post |
| Layout | Select (Default / Bar / Sidebar / Dropdown / Columns) | backend setting |
| Filter Groups | Text (comma-separated slugs) | all groups |
| Reset Button | Select (Default / Always / Never) | backend setting |
| CSS Class | Text | — |
Read the full README on GitHub →
Releases
| Tag | Published | Asset | Downloads |
|---|---|---|---|
| v1.4.4 | Aug 20, 2026 | jpkcom-post-filter.zip | 10 |
| v1.4.4 | Aug 20, 2026 | jpkcom-post-filter.zip.sha256 | 2 |
| v1.4.3 | Aug 11, 2026 | jpkcom-post-filter.zip | 10 |
| v1.4.3 | Aug 11, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.4.2 | Aug 11, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.4.2 | Aug 11, 2026 | jpkcom-post-filter.zip | 2 |
| v1.4.1 | Aug 11, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.4.1 | Aug 11, 2026 | jpkcom-post-filter.zip | 0 |
| v1.4.0 | Aug 11, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.4.0 | Aug 11, 2026 | jpkcom-post-filter.zip | 1 |
| v1.3.1 | Aug 10, 2026 | jpkcom-post-filter.zip | 9 |
| v1.3.1 | Aug 10, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.3.0 | Aug 3, 2026 | jpkcom-post-filter.zip | 9 |
| v1.3.0 | Aug 3, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.2.3 | Jul 30, 2026 | jpkcom-post-filter.zip.sha256 | 1 |
| v1.2.3 | Jul 30, 2026 | jpkcom-post-filter.zip | 10 |
| v1.2.2 | Jul 29, 2026 | jpkcom-post-filter.zip | 6 |
| v1.2.2 | Jul 29, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.2.1 | Jul 28, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.2.1 | Jul 28, 2026 | jpkcom-post-filter.zip | 1 |
| v1.2.0 | Jul 28, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.2.0 | Jul 28, 2026 | jpkcom-post-filter.zip | 0 |
| v1.1.7 | Jul 27, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
| v1.1.7 | Jul 27, 2026 | jpkcom-post-filter.zip | 7 |
| v1.1.6 | Jul 27, 2026 | jpkcom-post-filter.zip.sha256 | 0 |
Active-site estimate ≈10 comes from the v1.4.3 cohort. Method.