I had this same issue of needing two archive pages for a custom post type. I was able to accomplish this fairly cleanly using four WP hooks
For the example my custom post type is “member”. I need a second archive url for members that have a custom meta_key “plus” set to true.
First we need to define the URL for the second archive url. Notice passing the “plus_member” var in the query string.
add_filter('rewrite_rules_array', function($rules) {
return array_merge(array(
'plus-members/?$' => 'index.php?post_type=member&archive_type=archive&plus_member=1',
'plus-members/page/([0-9]{1,})/?$' => 'index.php?post_type=member&archive_type=archive&plus_member=1&paged=$matches[1]',
), $rules);
});
Next we need to allow the “plus_member” we are passing along
add_filter('query_vars', function($vars) {
$vars[] = 'plus_member';
return $vars;
});
Next we need to tell WP to use a different template file for this request instead of the default “archive-member.php”
add_filter('template_include', function($template) {
global $wp_query;
if ($wp_query->get('post_type') == 'member' && $wp_query->get('plus_member')) {
$template = locate_template('archive-plus-member.php');
}
return $template;
});
Finally we need to alter the main query so we are not showing all members but only plus members.
add_filter('pre_get_posts', function($query) {
if ($query->is_main_query() && $query->is_archive() && $query->get('post_type') == 'business') {
if ($query->get('plus_member')) {
$query->set('meta_key', 'plus');
$query->set('meta_value', true);
}
}
return $query;
});
This should produce the result:
/members/ (loads) archive-member.php (showing) all members
/plus-members/ (loads) archive-plus-member.php (showing) all members where meta_key plus == true