Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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, '/', 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 = '/', $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?

share|improve this question

3 Answers 3

    $link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'pcategory', false, '/', true), $link);

needs to become

    $link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'pcategory', false, true), $link);

Otherwise the revised function errors out looking for the separator.

share|improve this answer
up vote 0 down vote accepted

After changing something i have the final code that makes it work.

This is where you register the post types. (not changed)

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, '/', 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, $nicename = false, $visited = array()) {    
// removed $seperator="/" after $link, otherwise there was a double slash before the post name in the link    
$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, $nicename, $visited); //removed $seperator after $link
    $chain .= "/"; //add a / after every category
}

if ($link) {
    // nothing, can't get this working :(
} else    
    $chain .= $name; //don't need the . $separator anymore
return $chain;    
}
share|improve this answer

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.

share|improve this answer
    
That didn't work, i tried it in a few ways. I also used untrailingslashit. What did work is adding $chain .= "/"; after $chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited); and removing $separator in this. –  jochem Dec 6 '12 at 16:00
    
Well, glad you got it. –  s_ha_dum Dec 6 '12 at 16:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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