=== Multiple Category Selection Widget === Contributors: zackdesign Donate link: https://zackdesign.biz Tags: widget, category, post, subcategory, filter Requires at least: 6.0 Tested up to: 6.9.1 Stable tag: 4.0.0 Requires PHP: 7.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Filter posts by selecting multiple categories using dropdown menus. Available as a widget, block, or shortcode. == Description == Turn your WordPress post categories into a search powerhouse! This plugin gives you a set of dropdown menus based on parent categories and their sub-categories. Users select one sub-category per parent, and the plugin filters posts matching the selected combination. **Available as:** * **Gutenberg Block** — "Multi-Category Filter" in the block inserter (new in v4) * **Classic Widget** — "Multi-Category Selection" in Appearance > Widgets * **Shortcode** — `[mcsw]` on any page or post **Features:** * AND / OR category filtering — find posts matching ALL or ANY selected categories * AJAX chained drilldown — selecting a parent dynamically loads its children * Pretty permalink URLs (`/categories/3,5/search_type/and/order/title/`) * Ordering by title or default * Configurable blank search behavior * Exclude specific categories * Lightweight — no jQuery, no external dependencies * Pagination support * Display form above results on category pages (optional) **Sample use case:** Real estate — set up parent categories like "Bedrooms", "Bathrooms", "Price Range" with sub-categories beneath them. Users filter listings by selecting from each dropdown. **Upgrading from v3.x:** * PHP sessions have been removed entirely — the URL now carries all state, which means better compatibility with caching plugins, load balancers, and modern hosting * jQuery has been replaced with vanilla JavaScript * CSS classes have changed from `wpmcsw`/`wpmm` to BEM-style `mcsw-*` classes — update any custom CSS * The old `select-chain.js` in the plugin root has been replaced by `js/select-chain.js` == Installation == 1. Upload the plugin folder to `/wp-content/plugins/` 2. Activate through the Plugins menu 3. Create parent categories with sub-categories beneath them 4. Add posts and assign them to the sub-categories **As a block:** In the block editor, search for "Multi-Category Filter" and add it. **As a widget:** Go to Appearance > Widgets and add "Multi-Category Selection" to a sidebar. **As a shortcode:** Add `[mcsw]` to any page or post. Configure the shortcode form settings under Settings > Multiple Category Selection. **AJAX chaining example:** Create a category hierarchy like: Country - Australia - State - Vic - NSW - New Zealand - State - Auckland - Wellington Enable "AJAX Chaining" in Settings > Multiple Category Selection. Selecting "Australia" will dynamically show the Australian states. == Frequently Asked Questions == = ANY vs ALL is not working? = Click the "Reset" button first to clear the current filter, then try again. = The dropdowns aren't appearing = Dropdowns only appear for parent categories that have sub-categories with published posts. Make sure your categories have posts assigned. = Can I style the dropdowns? = Yes. The form uses `.mcsw-form`, each dropdown is in `.mcsw-select-wrap`, and AJAX-chained results use `.mcsw-chained`. See the plugin's `css/style.css` for the full class list. == Screenshots == 1. Widget settings in Appearance > Widgets 2. Category filter form on the frontend 3. Block settings in the editor sidebar == Changelog == = 4.0.0 = * New: Gutenberg block — "Multi-Category Filter" available in the block editor * New: Lightweight CSS file with clean BEM-style classes * Removed: PHP sessions — all search state now carried in URL query parameters * Removed: jQuery dependency — AJAX chaining rewritten in vanilla JavaScript * Fixed: AJAX chaining now sends the nonce (was broken since v3.2.0) * Fixed: Shortcode now returns output instead of echoing (proper shortcode behavior) * Fixed: Rewrite rules no longer flushed on every page load (only on activation) * Fixed: AJAX handler uses wp_send_json_success() instead of print/die * Changed: Admin settings page uses dedicated slug instead of __FILE__ * Changed: All redirect calls use wp_safe_redirect() * Changed: Requires WordPress 6.0+ * Security: Tightened input validation with sanitize_key(), absint(), whitelist checks = 3.2.0 = * PHP 8.x compatibility: replaced create_function() with anonymous function * Security: ABSPATH guards, nonce verification, input sanitization, output escaping * Replaced get_bloginfo('url') with home_url() = 3.1.6 = * Tested in WP 4.3.1 * Updated widget implementation to PHP 5 methodology = 3.1.5 = * Tested in WP 3.8 * Fixed overriding the navigation menu WP script = 3.1.4 = * Tested in WP 3.7 * Fixed media library files missing after plugin search = 3.1.3 = * Tested in WP 3.5.2 * Fixed AND/IN rewrite rules = 3.1.1 = * Extensive testing on any/all search * Reverted select box layout = 3.1 = * Created admin settings page * Added shortcode [mcsw] * AJAX on/off toggle * Form display above results toggle = 3.0 = * Support for multiple forms on a page * Shortcode support * Rewrite rule fixes = 2.4 = * Rewrite rules only flush on activation = 2.3 = * Fixed variable checking * Added title ordering = 2.2 = * AJAX chained select boxes = 2.1 = * WordPress 2.8+ widget class with multiple instances = 2.0 = * Fixed permalink issues * All-in-one-SEO and WP Smart Sort compatibility = 1.0 = * First release