Supercharge your custom post type archives by letting visitors filter posts by their terms/categories. This plugin handles the whole thing for you!
The Beautiful Taxonomy Filters plugin is an easy and good-looking way to provide your visitors with filtering for your post types. With this you get a complete solution for adding filtering based on custom taxonomy terms/categories/tags. It will also automatically add rewrite rules for pretty looking filter URLs. It’s completely automatic, works without javascript and is based on the WordPress Plugin boilerplate for a standardized, organized and object-oriented codebase. It uses select2 for pretty looking and user friendly dropdowns but will fall back to ordinary ones if javascript is not supported.
No more horrible looking URLs or hacky Javascript solutions
Do you want to translate this plugin to another language? I recommend using POEdit (http://poedit.net/) or if you prefer to do it straight from the WordPress admin interface (https://wordpress.org/plugins/loco-translate/). When you’re done, send us the file(s) to [email protected] and we’ll add it to the official plugin!
These are the filters available to modify the behavior of the plugin. These all take at least 1 parameter which you must return
$args is an array of the arguments put into the wp_dropdown_categories function.
$taxonomy is the current taxonomy.
function modify_categories_dropdown( $args, $taxonomy ) { return $args; } add_filter( 'beautiful_filters_dropdown_categories', 'modify_categories_dropdown’, 10, 2 );
$post_types is an array. Modifies the selected post types before being used.
function modify_post_types( $post_types ) { return $post_types; } add_filter( 'beautiful_filters_post_types', 'modify_post_types', 10, 1 );
$taxonomies is an array. Modifies the excluded taxonomies before being used.
function modify_categories_dropdown( $taxonomies ) { return $taxonomies; } add_filter( 'beautiful_filters_taxonomies', 'modify_categories_dropdown', 10, 1 );
$taxonomies is an array of the taxonomies slugs. $current_post_type is the post type we’re using the filter on. This must return the $taxonomies array.
function moveElement(&$array, $a, $b) { $out = array_splice($array, $a, 1); array_splice($array, $b, 0, $out); } function custom_tax_ordering($taxonomies, $current_post_type){ moveElement($taxonomies, 2, 0); return $taxonomies; } add_filter('beautiful_filters_taxonomy_order', 'custom_tax_ordering');
$placeholder is the string used for the placeholder.
$taxonomy is the current taxonomy.
In order to change the placeholders you must use this filter rather than the modify_categories_dropdown argument “show_option_all”.
function modify_dropdown_placeholder( $placeholder, $taxonomy ) { return 'New placeholder'; } add_filter( 'beautiful_filters_dropdown_placeholder', 'modify_dropdown_placeholder', 10, 2 );
Changes the language code for the current page load.
function modify_current_language( $language ) { return 'sv'; } add_filter( 'beautiful_filters_language', 'modify_current_language' );
Changes wether the page is RTL or not.
function modify_current_language( $rtl ) { return true; } add_filter( 'beautiful_filters_rtl', 'modify_rtl' );
Disables select2 fuzzy search. particularly useful for terms that are all numbers.
function disable_fuzzy_search( $boolean ) { return true; } add_filter('beautiful_filters_disable_fuzzy', 'disable_fuzzy_search', 10, 1);
$bool is a boolean which decides if the ”Clear all” link should be used or not. $current_post_type is the current post type being filtered
function modify_clear_all( $bool, $current_post_type ) { //Only add the clear all link to a specific posttype if($current_post_type == 'movies'){ $bool = true; } return $bool; } add_filter( 'beautiful_filters_clear_all', 'modify_clear_all', 10, 2 );
$bool is a boolean which decides if empty terms should be displayed or not. $current_post_type is the current post type being filtered
function modify_hide_empty( $bool, $current_post_type ) { return $bool; } add_filter( 'beautiful_filters_show_empty', 'modify_hide_empty', 10, 2 );
$bool is a boolean which decides if post count should be displayed or not. $current_post_type is the current post type being filtered
function modify_show_count( $bool, $current_post_type ) { return $bool; } add_filter( 'beautiful_filters_show_empty', 'modify_show_count', 10, 2 );
$bool is a boolean which decides if term description should be displayed or not. $current_post_type is the current post type being filtered
function modify_show_description( $bool, $current_post_type ) { return $bool; } add_filter( 'beautiful_filters_show_description', 'modify_show_description', 10, 2 );
$order is a string which defaults to ASC, other possible value is DESC. $taxonomy is the current taxonomy slug
function modify_dropdown_order( $order, $taxonomy) { return $order; } add_filter( 'beautiful_filters_dropdown_order', 'modify_dropdown_order', 10, 2 );
$order is a string which defaults to NAME, other possible value is ID or SLUG. $taxonomy is the current taxonomy slug
function modify_dropdown_orderby( $orderby, $taxonomy) { return $orderby; } add_filter( 'beautiful_filters_dropdown_orderby', 'modify_dropdown_orderby', 10, 2 );
$behaviour is a string that should be either show_all_option or show_placeholder_option. $current_post_type is the current posttype name.
Use this to modify the dropdown behaviour per posttype or just manually from functions.php
function modify_dropdown_behaviour( $behaviour, $current_post_type) { return $orderby; } add_filter( 'beautiful_filters_dropdown_behaviour', 'modify_dropdown_behaviour', 10, 2 );
$term_name is a string that have to be returned. $category is the term object. $depth is the level of depth for the current term starting at 0 (no parent).
Use this to alter the output of the term name inside the dropdowns.
//Add visual information when a terms are children/grandchildren etc. add_filter('beautiful_filters_term_name', 'custom_term_name', 10, 3); function custom_term_name($term_name, $category, $depth){ //We have indentation if($depth !== 0){ $indent = ''; //Add one – for each step down the hierarchy, like WP does in admin. for($i = 0; $i < $depth; $i++){ $indent .= '–'; } return $indent . ' ' . $term_name; } return $term_name; }
$label is the name of the taxonomy used as label to the dropdown.
function modify_labels($label){ return $label; } add_filter('beautiful_filters_taxonomy_label', 'modify_labels', 10, 1);
$string is the default string of the apply filters button.
function modify_filter_button($string){ return 'Hej världen'; } add_filter('beautiful_filters_apply_button', 'modify_filter_button', 10, 1);
$string is the default string of the apply filters button.
function modify_clear_button($string){ return 'Hej världen'; } add_filter('beautiful_filters_clear_button', 'modify_clear_button', 10, 1);
function my_custom_loader( $loader, $taxonomy, $posttype ){ return $loader; // $loader is an img tag } add_filter('beautiful_filters_loader', 'my_custom_loader', 10, 3);
$terms is the terms string for the active filter info
$taxonomy is the current taxonomy name
function modify_active_taxonomy($terms, $taxonomy){ return $terms; } add_filter('beautiful_filters_active_terms', 'modify_active_taxonomy', 10, 2);
$bool is a boolean of either true (hide filterinfo heading) or false (show filterinfo heading)
function toggle_filterinfo_heading($bool){ return true; } add_filter('beautiful_filters_disable_heading', 'toggle_filterinfo_heading');
$filter_heading is the default heading string
function modify_filter_heading($filter_heading){ $filter_heading = 'Hej världen'; return $filter_heading; } add_filter('beautiful_filters_info_heading', 'modify_filter_heading');
$bool is a boolean of either true (hide filterinfo postcount) or false (show filterinfo postcount)
function toggle_filterinfo_postcount($bool){ return true; } add_filter('beautiful_filters_disable_postcount', 'toggle_filterinfo_postcount');
$postcount_paragraph is the default postcount string. You MUST add %d somewhere in the new string in order for the resulting number to appear.
function modify_filterinfo_postcount($postcount_paragraph){ return 'Hej världen '; } add_filter('beautiful_filters_info_postcount', 'modify_filterinfo_postcount');
Use this filter to manipulate the URL string of the filtered archive page that the visitor will be directed to.
function modify_new_url($url){ return $url . '?filtered=yes'; } add_filter('beautiful_filters_new_url', 'modify_new_url');
$min_search is an integer.
function change_minsearch_value($min_search){ //always show search return 1; } add_filter('beautiful_filters_selec2_minsearch', 'change_minsearch_value');
$bool is a boolean value of either true of false. Setting this to false disables the ability to remove the selection with the x-icon.
function change_allowclear_value($bool){ //Disables the allow clear. return false; } add_filter('beautiful_filters_selec2_allowclear', 'change_allowclear_value');
These are the actions you may use to extend the filter component.
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
function add_markup_before_form($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_before_form', 'add_markup_before_form' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
function add_markup_after_form($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_after_form', 'add_markup_after_form' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
This action is very usable if you for some reason need to add inputs to be send with the form
function add_markup_beginning_form($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_beginning_form', 'add_markup_beginning_form' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
This action is very usable if you for some reason need to add inputs to be send with the form.
function add_markup_ending_form($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_ending_form', 'add_markup_ending_form' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
This action can be used to add inputs etc to the beginning of the inner div of the filter module.
function add_markup_beginning_form_inner($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_beginning_form_inner', 'add_markup_beginning_form_inner' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
This action can be used to add inputs etc to the end of the inner div of the filter module.
function add_markup_ending_form_inner($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_ending_form_inner', 'add_markup_ending_form_inner' );
$current_post_type is the post type which the filter component are currently using. Use this variable as a conditional if needed.
This action can be used to add your own stuff or manipulate something before the page is redirected to the new filtered page but after the page has reloaded.
function custom_stuff_before_redirection($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_before_redirection', 'custom_stuff_before_redirection' );
$current_post_type is the post type which the filterinfo component are currently using. Use this variable as a conditional if needed.
This action is very usable if you for some reason need to add markup at the beginning of the filterinfo module
function add_markup_beginning_filterinfo($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_beginning_filterinfo', 'add_markup_beginning_filterinfo' );
$current_post_type is the post type which the filterinfo component are currently using. Use this variable as a conditional if needed.
This action is very usable if you for some reason need to add markup at the end of the filterinfo module
function add_markup_ending_filterinfo($current_post_type){ echo 'Hej världen'; } add_action('beautiful_actions_ending_filterinfo', 'add_markup_ending_filterinfo' );
beautiful-taxonomy-filters
folder to the /wp-content/plugins/
directoryBasic options.
Advanced options.
The filter module using the light material look in WordPress twentyfifteen theme.
The filter module with a dropdown open and using descriptions for terms.
The filter widget in WordPress twentyfifteen theme.
The filter widget settings.
Example of a beautified permalink structure (4 different taxonomies/terms).
Yes. Either use the widget and set a specific post type in it’s settings or add a parameter of your custom post type slug to the show_beautiful_filters
action. This “hardcodes” the filter module to that post type and lets you use it pretty much anywhere in your theme. Hardcore right..
<?php do_action( 'show_beautiful_filters', 'posttypeslug' ); ?>
Well of course! You can either change the order in which you register your taxonomies OR you can use the filter
function moveElement( &$array, $a, $b ) { $out = array_splice($array, $a, 1); array_splice($array, $b, 0, $out); } function custom_tax_ordering( $taxonomies, $current_post_type ) { moveElement( $taxonomies, 2, 0 ); return $taxonomies; } add_filter( 'beautiful_filters_taxonomy_order', 'custom_tax_ordering' );
No. In a future release we will look into if it’s possible to support this AND having beautiful permalinks. If that doesn’t work we will likely add an option where you can opt out of beautiful permalinks and enjoy the power of multiple terms filtering instead.
A Taxonomy will not appear in the filter until at least one post has been connected to one of the terms.
Just start tagging up your posts and you’ll see it shows up! Also, make sure that your custom post type has an archive (in the arguments for the custom post type) since this plugin uses the builtin WordPress functionality for archives.
Posts are not supported because we haven’t been able to create proper rewrite rules for the multiple filtering to work. Posts are handled differently by WordPress than other custom post types (you have probably noticed that there’s no /posts/ in the permalink for example). Due to this the same rewrite rules that works for custom post types doesn’t work for posts. If you’re just looking to filter your posts by their categories with a dropdown you can use this function wp_dropdown_categories. It’s good practice to use a custom post type when you’re not going to use it as news/blog -posts so perhaps you should create a Custom post type instead and make use of this beautiful plugin!
Since v 2.2 this has been fixed. Make sure you keep BTF updated
In order for the rewrite rules to work with a taxonomy that has a rewrite slug you also have to add the same slug to the query_var
parameter of register_taxonomy. It wont have any visible impact for you but it’s what’s needed for the filtered urls to work!
It is 100% compatible with Polylang. WPML is a bit wonky but might work depending on your setup. In order for this to work properly you should set the post types and all connected taxonomies to be translatable. The filtered urls will still work even if you don’t set the post type to be translatable but when switching language Polylang still think it should add the new language to the URL which means it’ll throw a 404 error. This is to be expected and NOT due to this plugin. If you experience 404 errors make sure you flush your rewrite rules by going to settings > permalinks in the admin dashboard.
You will be able to use this plugin with any public registered custom post type regardless if it’s been created by yourself or a plugin. However the displaying of the CPT must be via it’s archive template. That means that a plugin that uses shortcodes to display the entire post listing on a static page will not work out of the box. It will also not work out of the box with plugins that in some way alter the permalink to the CPT archive WPMU Devs Events+ for example.
Why thank you! We don’t have proper donate link but if you want to you can send us a giftcard on fancy. We will use it to buy cool stuff for the office! Make it out to [email protected]
[show_beautiful_filters post_type="yourcptslug"]
where you want!is_btf_filtered()
which will return true or false if the current page is filtered by BTF. Not currently in use everywhere in the code tho so don’t peak..btf-archive
and btf-filtered
are added to the body class. Use these however you want!FEATURE: Disable fuzzy search in select2. It’s as easy as adding this filter:
function disable_fuzzy_search( $boolean ) {
return true;
}
add_filter(‘beautiful_filters_disable_fuzzy’, ‘disable_fuzzy_search’, 10, 1);
(Thanks to babouz44 for the help).
IMPROVEMENT: Select2 will now automatically detect RTL languages. You can also set this manually using the filter:
function modify_rtl( $rtl ) {
return true;
}
add_filter( ‘beautiful_filters_rtl’, ‘modify_rtl’ );
IMPROVEMENT: Select2 will now automatically detect current language (if using Polylang or WPML) and apply the correct translation file. You can also set this manually yourself using the new filter:
function modify_current_language( $language ) {
return ‘sv’;
}
add_filter( ‘beautiful_filters_language’, ‘modify_current_language’ );
IMPROVEMENT: Some overall improvement to the select2 JS script. Just a bit of refactoring.
A loader will appear and the dropdowns will be disabled while the AJAX works its magic if it takes longer than 800ms. any new AJAX triggered before the previous has finished will also abort the previous one.
You can replace the default loader .gif (WordPress spinner) using the new filter:
function my_custom_loader( $loader, $taxonomy, $posttype ){ return $loader; // $loader is an img tag } add_filter('beautiful_filters_loader', 'my_custom_loader', 10, 3);
.select2-results__option .level-1{ padding-left: 1em; }
.Just a minor update right now.. bigger things to come. carry on!
.change
event not happening on original select element.IMPORTANT: In this update we’ve done a big overhaul of the settings page. This was important to be able to keep improving BTF settings and features. Unfortunately this means that any of your advanced settings will have to be reset. After updating please take a look at the “Advanced options” tab to make sure everything is set as you want.
beautiful_filters_clear_button
. Takes the string and requires a return of a string.Now go punch a shark!
<?php if(function_exists('show_beautiful_filters')){ show_beautiful_filters(); } ?>
you can now just do <?php do_action('show_beautiful_filters'); ?>
and of course <?php do_action('show_beautiful_filters_info'); ?>
for the info module. This means less code, cleaner look and you wont see a white screen of death if you’ve failed to do a function_exists call and disabled the plugin. NOTE: The old way will still work so don’t worry.. you don’t have to do anything if you don’t want to… More info.A new resource for information about how to use BTF and it’s filters will soon emerge from the mist…
Note: in order for the filtering to work with a rewrite slug for your taxonomies you need to set query_var to the same value as your rewrite slug.
For example: you have a taxonomy registered with the slug “product_color” but you want the url slug to be “color”. Add “color” to both the query_var
value and rewrite['slug']
value.
show_beautiful_filters()
function can now take a parameter of a custom post type name. Doing so enables you to show the filter module anywhere in your theme for a specific post type. Much like the widget except you can place the function pretty much anywhere without having to use a widget. Pretty sweet.