Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom taxonomy in custom post type permalink?

I have a custom taxonomy called campaign and a custom post type called asset. For assets, I want to have the following permalink structure: mysite.com/<campaign_name>/<asset_name>. I have achieved this by the following code, but now if I go to any normal page with the url structure mysite.com/<pagename> it gives a 404. And when I comment out the rewrite slug part in the function for registering the custom post type, or add this instead ams/%campaign%, it works but that's not the URL structure I want for my custom post type.

Code for registering custom taxonomy:

...
'rewrite' => array(
    'slug' => '',
    'with_front' => true,
),
...

Code for registering custom post type:

...
rewrite' => array(
    'slug' => '%campaign%',
    'with_front' => true,
),
...

Functions for rewrite rules:

function ams_asset_add_rewrite_rules( $rules ) {
    global $post;
    if ($post->post_type == 'asset' ) {
        $new = array();
        $new['([^/]+)/(.+)/?$'] = 'index.php?asset=$matches[2]';
        $new['(.+)/?$'] = 'index.php?campaign=$matches[1]';
        return array_merge( $new, $rules );
    }
    return $rules;
}
add_filter( 'rewrite_rules_array', 'ams_asset_add_rewrite_rules' );

// Handle the '%campaign%' URL placeholder
function ams_asset_filter_post_type_link( $link, $post = 0 ) {
    if ( $post->post_type == 'asset' ) {
        $cats = wp_get_object_terms( $post->ID, 'campaign' );
        if ( $cats ) {
            $link = str_replace( '%campaign%', $cats[0]->slug, $link );
        }
    }
    return $link;
}
add_filter( 'post_type_link', 'ams_asset_filter_post_type_link', 10, 2 );
like image 256
sadmansh Avatar asked Sep 03 '19 05:09

sadmansh


1 Answers

First, register your taxonomy and set the slug argument of rewrite to shows:

register_taxonomy(
    'campaign',
    'asset',
    array(
        'rewrite' => array( 'slug' => 'shows', 'with_front' => false ),
        // your other args...
    )
);

Next, register your post type and set the slug to shows/%show_category%, and set has_archive argument to shows:

register_post_type(
    'show',
    array(
        'rewrite' => array( 'slug' => 'campaign/%asset%', 'with_front' => false ),
        'has_archive' => 'asset',
        // your other args...
    )
);

Last, add a filter to post_type_link to substitute the show category in individual show permalinks:

function wpa_show_permalinks( $post_link, $post ){
    if ( is_object( $post ) && $post->post_type == 'asset' ){
        $terms = wp_get_object_terms( $post->ID, 'campaign' );
        if( $terms ){
            return str_replace( '%campaign%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'wpa_show_permalinks', 1, 2 );
like image 129
Kapil Yadav Avatar answered Oct 20 '22 00:10

Kapil Yadav