Following the instructions from this thread, I have custom post type taxonomical permalink URLs working.
However, when the permalink is actually displayed in the admin or editor, it reverts to using the variable name (e.g. /%taxonomy_name%/
) rather than the variable values (e.g. /podcast/
).
E.g. My taxonomy is called podcast
. My custom post type is called podcast_episode
.
I can create a top-level podcast
“foo” and I create a podcast_episode
post titled “123”. url.test/podcast/foo/123
works.
I can create a 2nd-level podcast
underneath “foo” called “bar”, then I create a podcast_episode
titled “1234” url.test/podcast/foo/bar/1234
works.
However, in the actual classic editor, the displayed permalink is url.test/podcast/%taxonomy_name%/123
and url.test/podcast/%taxonomy_name%/1234
.
In the table view for all podcast_episode
s, pressing “View” on a row also points to the same broken URL with %taxonomy_name%
in it.
How can I update it so that the displayed permalink in the WordPress admin section matches the actual URL?
This is my current code:
// functions.php
function _s_create_custom_post_types() {
register_post_type(
'podcast_episode',
array(
'labels' => array(
'name' => __('Podcast Episodes'),
'singular_name' => __('Podcast Episode'),
'add_new' => __('Add New'),
'add_new_item' => __('Add New Podcast Episode'),
'view_item' => __('View Item'),
'edit_item' => __('Edit Item'),
'search_items' => __('Search Items'),
'not_found' => __('Not Found'),
'not_found_in_trash' => __('Not Found in Trash')
),
'public' => true,
// 'hierarchical' => true,
'supports' => array('title', 'editor'),
'rewrite' => array(
'slug' => 'podcast/%taxonomy_name%',
),
'taxonomies' => array('podcast_episode'),
'query_var' => true,
'supports' => array('title', 'editor', 'thumbnail',),
)
);
}
add_action('init', '_s_create_custom_post_types');
function _s_add_custom_taxonomies() {
// Add new "podcast" taxonomy to "podcast_episode" post type
register_taxonomy('podcast', 'podcast_episode', array(
// Hierarchical taxonomy (like categories)
'labels' => array(
'name' => _x('Podcasts', 'taxonomy general name'),
'singular_name' => _x('Podcast', 'taxonomy singular name'),
'search_items' => __('Search Podcasts'),
'all_items' => __('All Podcasts'),
'parent_item' => __('Parent Podcast'),
'parent_item_colon' => __('Parent Location:'),
'edit_item' => __('Edit Podcast'),
'update_item' => __('Update Podcast'),
'add_new_item' => __('Add New Podcast or Podcast Season'),
'menu_name' => __('Podcasts'),
),
'public' => true,
'hierarchical' => true,
'rewrite' => array(
'slug' => 'podcast',
'with_front' => true,
'hierarchical' => true
),
'query_var' => true,
));
}
add_action('init', '_s_add_custom_taxonomies');
// Fix URLs
function vk_query_vars($qvars) {
if (is_admin()) return $qvars;
$custom_taxonomy = 'podcast';
if (array_key_exists($custom_taxonomy, $qvars)) {
$custom_post_type = 'podcast_episode';
$pathParts = explode('/', $qvars[$custom_taxonomy]);
$numParts = sizeof($pathParts);
$lastPart = array_pop($pathParts);
$post = get_page_by_path($lastPart, OBJECT, $custom_post_type);
if ($post && !is_wp_error($post)) {
$qvars['p'] = $post->ID;
$qvars['post_type'] = $custom_post_type;
}
}
return $qvars;
}
add_filter('request', 'vk_query_vars');
function filter_post_type_link($link, $post) {
if ($post->post_type != 'podcast')
return $link;
if ($cats = get_the_terms($post->ID, 'podcast_episode')) {
$link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'podcast', false, '/', true), $link); // see custom function defined below
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {
$chain = '';
$parent = &get_term($id, $taxonomy);
if (is_wp_error($parent)) {
return $parent;
}
if ($nicename)
$name = $parent->slug;
else
$name = $parent->name;
if ($parent->parent && ($parent->parent != $parent->term_id) && !in_array($parent->parent, $visited)) {
$visited[] = $parent->parent;
$chain .= get_taxonomy_parents($parent->parent, $taxonomy, $link, $separator, $nicename, $visited);
}
if ($link) {
// nothing, can't get this working :(
} else
$chain .= $name . $separator;
return $chain;
}