How to fix a double slash in custom permalinks with hierarchical taxonomy’s?

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
4

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.

Leave a Comment