What you are looking for is a custom search that can be created via rewrite rules. What I’m gonna do is to create a rule that adds some queries to the URL.
First, let’s define a rewrite tag so that WordPress recognizes our custom URL.
function my_rewrite_tag() {
add_rewrite_tag('%custom-categories%', '([^&]+)');
}
add_action('init', 'my_rewrite_tag', 10, 0);
Now, we create a rule to redirect our data to another path.
function my_rewrite_rule() {
add_rewrite_rule(
'^custom-categories/([^/]*)/([^/]*)/([^/]*)/([^/]*)/?',
'index.php?post_type=post&customCat=$matches[1]&customSubCat=$matches[2]&customTag1=$matches[3]&customTag2=$matches[4]',
'top'
);
}
add_action('init', 'my_rewrite_rule', 10, 0);
So if we try and access:
http://example.com/custom-categories/cat1/subcat1/tag/tag1
we will actually be redirected to:
http://example.com/index.php?post_type=post&customCat=cat1&customSubCat=subcat1&customTag1=tag&customTag2=tag1
Which is the archive for normal post types. Now is the trick. We will alter the query if these data are set:
// We only want to do this if every data is set, so let's check for them all
if(isset($_['customCat']) && isset($_['customSubCat']) && isset($_['customTag1']) && isset($_['customTag2'])) {
// Now alter the main query
function photogram_include_blog_posts($query) {
if ( !is_admin() && $query->is_main_query() && $query->is_archive() ) {
// Set the tags
$query->set('tag__in', array($_['customTag1'],$_['customTag2']));
// Set the categories
$query->set('category__in', array($_['customSubCat'],$_['customCat']));
}
}
add_action( 'pre_get_posts', 'photogram_include_blog_posts' );
}
So we are redirected to an archive page that runs our custom query. Done.