Following the solution from Jeff @ Custom permalinks – post type – hierarchical taxonomy’s
I managed to rewrite my url’s for custom taxonomy’s.
However i do have one thing that bothers me and that is a double slash in the output because of the separator.
http://www.domain.nl/product/televisies/led/55-inch//product-naam-4/
I can not change this in the permalinks section in de admin. (/%category%/%postname%/)
register_post_type( "products",
array( 'label' => CUSTOM_MENU_TITLE,
'labels' => array( 'name' => CUSTOM_MENU_NAME,
'singular_name' => CUSTOM_MENU_SIGULAR_NAME,
'add_new' => CUSTOM_MENU_ADD_NEW,
'add_new_item' => CUSTOM_MENU_ADD_NEW_ITEM,
'edit' => CUSTOM_MENU_EDIT,
'edit_item' => CUSTOM_MENU_EDIT_ITEM,
'new_item' => CUSTOM_MENU_NEW,
'view_item' => CUSTOM_MENU_VIEW,
'search_items' => CUSTOM_MENU_SEARCH,
'not_found' => CUSTOM_MENU_NOT_FOUND,
'not_found_in_trash' => CUSTOM_MENU_NOT_FOUND_TRASH ),
'public' => true,
'can_export' => true,
'show_ui' => true, // UI in admin panel
'_builtin' => false, // It's a custom post type, not built in
'_edit_link' => 'post.php?post=%d',
'capability_type' => 'post',
'menu_icon' => get_bloginfo('template_url').'/images/favicon.ico',
'hierarchical' => true,
'rewrite' => array('slug' => 'product/%taxonomy_name%','with_front' => true,'hierarchical'=>true), // Permalinks
'query_var' => "products", // This goes to the WP_Query schema
'supports' => array( 'title',
'author',
'excerpt',
'thumbnail',
'comments',
'editor',
'trackbacks',
'custom-fields',
'revisions') ,
'show_in_nav_menus' => true ,
'taxonomies' => array("pcategory","ptags")
)
);
// Register custom taxonomy
register_taxonomy( "pcategory",
array( "products" ),
array ( "hierarchical" => true,
"label" => CUSTOM_MENU_CAT_LABEL,
'labels' => array( 'name' => CUSTOM_MENU_CAT_TITLE,
'singular_name' => CUSTOM_MENU_SIGULAR_CAT,
'search_items' => CUSTOM_MENU_CAT_SEARCH,
'popular_items' => CUSTOM_MENU_CAT_SEARCH,
'all_items' => CUSTOM_MENU_CAT_ALL,
'parent_item' => CUSTOM_MENU_CAT_PARENT,
'parent_item_colon' => CUSTOM_MENU_CAT_PARENT_COL,
'edit_item' => CUSTOM_MENU_CAT_EDIT,
'update_item' => CUSTOM_MENU_CAT_UPDATE,
'add_new_item' => CUSTOM_MENU_CAT_ADDNEW,
'new_item_name' => CUSTOM_MENU_CAT_NEW_NAME, ),
'public' => true,
'show_ui' => true,
"rewrite" => array('slug' => 'product','with_front' => true,'hierarchical'=>true))
);
My functions.php includes:
add_filter('rewrite_rules_array', 'mmp_rewrite_rules');
function mmp_rewrite_rules($rules) {
$newRules = array();
$newRules['product/(.+)/(.+)/(.+)/(.+)/?$'] = 'index.php?products=$matches[4]';
$newRules['product/(.+)/?$'] = 'index.php?pcategory=$matches[1]';
return array_merge($newRules, $rules);
}
function filter_post_type_link($link, $post)
{
if ($post->post_type != 'products')
return $link;
if ($cats = get_the_terms($post->ID, 'pcategory'))
{
$link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'pcategory', false, "https://wordpress.stackexchange.com/", true), $link);
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
// my own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator="https://wordpress.stackexchange.com/", $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;
}
Does any one know how to solve this?
4 Answers
There is a quick and somewhat dirty potential solution to this. I say ‘potential’ because I can’t spot the problem by looking at the code. I only have my suspicions. Instead of passing a separator like that. Try trailingslashit
.
} else
$chain .= trailingslashit($name);
return $chain;
I am guessing at where the problem is based on your description, but that is the only place that $separator
is applied.
There is a case where this simple fix won’t work. If $name
is empty, you will get an extra slash in your string, so it would be better to check for that, just in case.
} elseif (!empty($name))
$chain .= trailingslashit($name);
return $chain;
Try that.