I ended up with this:
// Register Custom Taxonomy
function fixed_tags_taxonomy() {
$labels = array(
'name' => _x( 'Fixed Tags', 'Taxonomy General Name', 'text_domain' ),
'singular_name' => _x( 'Fixed Tag', 'Taxonomy Singular Name', 'text_domain' ),
);
$args = array(
'labels' => $labels,
'hierarchical'=>true,
);
register_taxonomy( 'fixed-tags', array( 'portfolio' ), $args );
}
add_action( 'init', __NAMESPACE__ . '\\' . 'fixed_tags_taxonomy', 2 );
// rewrite url portfolio post type
// we want something in this format -> portfolio/{fixed_tag_name}
// remember to visit wp-admin/options-permalink.php and click "save changes"
add_action('init', function() {
add_rewrite_tag( '%portfolio%', '([^&]+)' );
add_rewrite_rule( '^portfolio/([^/]*)/?', 'index.php?portfolio=$matches[1]&fixed_tags=$matches[1]','top' );
// add_rewrite_tag( '%portfolio%' );
add_rewrite_rule( '^portfolio$', 'index.php?pagename=portfolio','top' );
}, 10, 0);
// we need to register our query variable to wordpress
// will pass it's value back to us when we call get_query_var('fixed_tags'))
add_filter( 'query_vars', function( $query_vars )
{
$query_vars[] = 'fixed_tags';
return $query_vars;
});
add_filter('template_redirect', function ()
{
global $wp_query;
$fixed_tag = get_fixed_tag();
if ($fixed_tag) {
status_header( 200 );
$wp_query->is_404=false;
$wp_query->set('post_type', 'portfolio');
$wp_query->set('tax_query', [
'relation' => 'AND',
array(
'taxonomy' => 'fixed-tags',
'field' => 'slug',
'terms' => array( $fixed_tag ),
)
]);
}
});
add_filter( 'template_include', function ( $template )
{
$fixed_tag = get_fixed_tag();
if($fixed_tag){
return locate_template( ['page-portfolio-flex-layouts.php' ] );
}
return $template;
});
function get_fixed_tag()
{
$fixed_tag = sanitize_title(get_query_var('fixed_tags'));
// we check if term is fixed tags
// we tell wordpress to handle as 200 is found
$term = get_term_by('slug', $fixed_tag, 'fixed-tags');
return $term ? $fixed_tag : null;
}