You’ll have to add some new rewrite rules, thankfully WordPress makes it fairly straightforward using a few function calls.
// use the init action to modify rewrite rules
add_action( 'init', function() {
global $wp_rewrite;
// add rewrite tag for the post type
// - %posttype% is a new tag that will be replaced with the regex in the actual query
// - the regex will extract the post_type name from the URL and use it in the query
add_rewrite_tag( '%posttype%', '([^/]+)', 'post_type=" );
// create the new permastruct by combining the post type & taxonomy permastructs
// - custom taxonomies and post types are added to the extra_permastructs array in WP_Rewrite
// - change "category' to desired taxonomy
// - output will be '%posttype%/category/%category%'
$types_and_cats_permastruct="%posttype%" . $wp_rewrite->get_extra_permastruct( 'category' );
// add the permastruct for post type & taxonomy
add_permastruct( 'post_type_and_category', $types_and_cats_permastruct, array(
'with_front' => true, // - with_front (bool) - Should the structure be prepended with WP_Rewrite::$front? Default is true.
'ep_mask' => EP_ALL_ARCHIVES, // - ep_mask (int) - Endpoint mask defining what endpoints are added to the structure. Default is EP_NONE.
'paged' => true, // - paged (bool) - Should archive pagination rules be added for the structure? Default is true.
'feed' => true, // - feed (bool) - Should feed rewrite rules be added for the structure? Default is true.
'forcomments' => false, // - forcomments (bool) - Should the feed rules be a query for a comments feed? Default is false.
'walk_dirs' => false, // - walk_dirs (bool) - Should the 'directories' making up the structure be walked over and rewrite
// rules built for each in turn? Default is true.
'endpoints' => true // - endpoints (bool) - Should endpoints be applied to the generated rewrite rules? Default is true.
) );
} );
So to explain what I’m doing above:
- Adding a rewrite tag with
add_rewrite_tag()
so that when you put the custom post type name into the URL (eg. /events/location/uk/) it will be recognised by the regular expression and the resulting query WP runs would containpost_type=events
- Making a new permastruct to generate rules for using the tag we just added and the existing taxonomy permastruct, in your case this would be location so
/event/location/uk
will show uk events and/business/location/uk
will show uk businesses - Adding the new permastruct with
add_permastruct()
so that WP generates the new rewrite rules whenever permalinks are refreshed. In the 3rd parameter it’s very important to havewalk_dirs
set to false as you’ll get some undesirable aggressive rewrite rules with archives for/%posttype%/category/
and/%posttype%/
Gotchas
- Generating links – if you want to use
the_terms()
to output location links for a business or event that only shows the originating post type you’ll have to filter the URLs or write a custom function to output URLs to match your permastruct - If you never want an archive listing both events and businesses then 2 separate taxonomies is a better idea as you’ll more easily be able to tell if a term has any posts in it eg. when generating links and deciding whether to output a link to an empty archive or not. In that case @richard-howarth’s answer is correct