0

I'm trying to figure out the following :

  • I have a CPT called "Podcast" which has a slug as /podcasts/
  • I have a Page called "Podcasts" which has a slug as /podcasts/

I want my single podcast posts to have a permalink of /podcasts/%podcast_category%/post_name

When i do this, I cannot edit the podcasts page, as wordpress displays the archive page instead. How can i modify my code, so the archive page has a different slug, but still keeping /podcasts/%podcast_category%/post_name for single podcasts, and /podcasts/ can be used as a page.

//register podcast posts
function custom_post_podcasts_register(){

$labels = array(
    'name'               => _x('Podcast', 'post type general name'),
    'singular_name'      => _x('Podcast', 'post type singular name'),
    'add_new'            => _x('Add New', 'podcast'),
    'add_new_item'       => __('Add New Podcast'),
    'edit_item'          => __('Edit Podcast'),
    'new_item'           => __('New Integration'),
    'view_item'          => __('View Podcast'),
    'search_items'       => __('Search Podcast'),
    'not_found'          => __('Nothing found'),
    'not_found_in_trash' => __('Nothing found in Trash'),
    'parent_item_colon'  => ''
);

$args = array(
    'labels'             => $labels,
    'public'             => true,
    'publicly_queryable' => true,
    'show_ui'            => true,
    'query_var'          => true,
    'rewrite'            => true,
    'capability_type'    => 'post',
    'hierarchical'       => false,
    'menu_position'      => null,
    'show_in_rest'       => true,
    'rewrite'            => array('slug' => 'podcasts','with_front' => false),
    'has_archive'        => 'podcast-all',
    'supports'           => array('title', 'editor', 'thumbnail', 'excerpt','podcast_category', 'podcast_tags'),
    'taxonomies'         => array( 'podcast_category', 'podcast_tags' ),
    'menu_icon'          => 'dashicons-format-quote',
    'has_archive'        => true
  ); 
register_post_type('podcast' , $args);
}
add_action('init', 'custom_post_podcasts_register');
add_filter('manage_edit-podcast_columns', 'admin_remove_columns');

//create a custom taxonomy name it "type" for your posts
function podcast_custom_taxonomy() {

$labels = array(
  'name' => _x( 'Podcast Category', 'taxonomy general name' ),
  'singular_name' => _x( 'podcast_category', 'taxonomy singular name' ),
  'edit_item' => __( 'Edit Podcast Category' ), 
  'update_item' => __( 'Update Podcast Category' ),
  'add_new_item' => __( 'Add New Podcast Category' ),
  'new_item_name' => __( 'New Podcast Category Name' ),
  'menu_name' => __( 'Podcast Category' ),
);  

register_taxonomy('podcast_category',array('podcast'), array(
  'labels'                     => $labels,
      'hierarchical'               => true,
      'public'                     => true,
      'show_ui'                    => true,
      'show_admin_column'          => true,
      'show_in_nav_menus'          => true,
      'show_tagcloud'              => true,
      'show_in_rest'               => true,
  'rewrite' => array( 'slug' => 'podcast_category' ),
));
}
// Let us create Taxonomy for Custom Post Type
add_action( 'init', 'podcast_custom_taxonomy', 0 );

// Register Custom Taxonomy
function podcast_tags_taxononmy() {

$labels = array(
    'name'                       => 'Podcast Tag',
    'singular_name'              => 'Podcast Tag',
    'menu_name'                  => 'Podcast Tags',
    'all_items'                  => 'All Podcast Tags',
    'parent_item'                => 'Parent Podcast Tag',
    'parent_item_colon'          => 'Parent Podcast Tag:',
    'new_item_name'              => 'New Podcast Tag',
    'add_new_item'               => 'Add New Podcast Tag',
    'edit_item'                  => 'Edit Podcast Tag',
    'update_item'                => 'Update Podcast Tag',
    'separate_items_with_commas' => 'Separate Podcast Tags with commas',
    'search_items'               => 'Search Podcast Tags',
    'add_or_remove_items'        => 'Add or remove Podcast Tags',
    'choose_from_most_used'      => 'Choose from the most used Podcast Tags',
    'not_found'                  => 'Not Found',
);
$args = array(
    'labels'                     => $labels,
    'hierarchical'               => true,
    'public'                     => true,
    'show_ui'                    => true,
    'show_admin_column'          => true,
    'show_in_nav_menus'          => true,
    'show_tagcloud'              => true,
    'show_in_rest'               => true,
);
register_taxonomy( 'podcast-tags', array( 'podcast' ), $args );

}

// Hook into the 'init' action
add_action( 'init', 'podcast_tags_taxononmy', 0 );
1

The following assumes that the Podcast Archive will have a different slug than the Podcast Page. Otherwise, WordPress won't know which resource to serve when the user visits /podcasts/.

Give the Taxonomy a default term. This ensures that every Podcast lands in a category and will have a category in the permalink. See register_taxonomy() for full args.

register_taxonomy( 'podcast_category', array('podcast'), array(
    'rewrite' => array( 'slug' => 'podcasts-category' ),
    'default_term' => array(
        'name' => esc_html__( 'Uncategorized' ),
    ),
) );

Add an arbitrary placeholder in the Post Type rewrite slug.

register_post_type( 'podcast' , array(
    'rewrite' => array(
        'slug'       => 'podcasts/%podcast_category%',
        'with_front' => false
    ),
    'has_archive' => 'podcasts-all',
) );

Replace the arbitrary placeholder in the Postcast URL.

/**
 * Post Type Link
 * Replace placeholder with post term.
 *
 * @param String $post_link
 * @param WP_Post $post
 *
 * @return String $post_link
 */
function podcast_post_link( $post_link, $post ) {

    if( 'podcast' !== $post_type ) {
        return $post_link;
    }

    $terms = wp_get_object_terms( $post->ID, 'podcast_category' );

    if( ! ( empty( $terms ) || is_wp_error( $terms ) ) ) {
        $post_link = str_replace( '%podcast_category%' , $terms[0]->slug , $post_link );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'podcast_post_link', 10, 2 );

Save permalinks. Head to Settings > Permalinks and click Save. This will refresh the permalink structure. What you should end up with:

Podcast Page: /podcasts/
Podcast Archive: /podcasts-all/
Podcast Category: /podcast-category/uncategorized/
Podcast Singular: /podcasts/uncategorized/podcast-slug/


Note that in your register_post_type() you're calling has_archive twice. The 2nd has_archive => true is overwriting your post type archive slug.

1
  • 1
    Awesome. Actually the 2nd has_archive which i missed, was the culprit.
    – Jon
    Mar 2 '21 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.