I'm struggling setting up custom permalink structure with custom taxonomies. I've read many questions/answers here but I can't get it to work (most frustrating is that I don't know of a way to debug and find the problem myself). Any help is greatly appreciated!

What you need to know

  • I have a custom post type called items
  • items has two custom taxonomies:
    • types and locations.
  • Every item is associated with one type and multiple (1+) locations

I'm trying to get this link structure for every item:


whereas I only want the first location term to be used in this link structure.

I haven't tried implementing the /location part of the link structure (I guess that's a little bit more complex), as I'm already struggling with the /type/ part. So my code currently looks like this and this doesn't yield any changes in my permalinks:

in a plugin

register_post_type( 'item',
            'labels'        => $labels,
            'supports'      => array( 'title', 'editor', 'thumbnail', 'comments'),
            'public'        => true,
            'has_archive'   => true,
            'rewrite'       => true,
            'menu_icon'    => plugins_url( '/img/icon.png'),
            'menu_position' => 42,
            'categories'    => array( ),

register_taxonomy( 'types', 'item', array(
        'labels'       => $item_types_labels,
        'hierarchical' => true,
        'query_var'    => 'type',
        'rewrite'      => true,
        'public'       => true,
        'show_ui'      => true,
    ) );

in functions.php

add_filter('post_link', 'types_permalink', 10, 3);
add_filter('post_type_link', 'types_permalink', 10, 3);

function types_permalink($permalink, $post_id, $leavename) {
    if (strpos($permalink, '%types%') === FALSE) return $permalink;

        // Get post
        $post = get_post($post_id);
        if (!$post) return $permalink;

        // Get taxonomy terms
        $terms = wp_get_object_terms($post->ID, 'types');   
        if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
        else $taxonomy_slug = 'no-type';

    return str_replace('%types%', $taxonomy_slug, $permalink);

I set my permalink structure to the custom structure /%types%/%postname%/. My URL still looks like this domain.com/item/postname.

Also: Whatever I put in place for /item/ (e.g. domain.com/this-doesn-make-sense-to-me/postname), I get redirect to domain.com/item/postname.


First issue- the permalink structure in Settings is only for the post post type, so your post_type_link function has no %types% tag to replace.

Second- unless you want a very complicated (and less performant) solution, the simpler solution is to have a static prefix in your post type slug. With the URL http://domain.com/type/location/post-name/, WordPress has no way of knowing what you're asking for. Is type a page with child page location, or is it a types taxonomy term? Using the standard rewrites system, one rule will always take precedence, and the other requests will always 404. With the URL format http://domain.com/item/type/location/post-name/, WordPress will know exactly what you're asking for, because only one post type is prefixed with item.

As for specifics- in your post type registration, set the slug argument of rewrite to the format of URL you want:

'rewrite' => array( 'slug' => 'item/%types%' ),

… and your post_type_link filter should work. If you want to add locations, just add that tag to the slug and add the code to replace the tag in your post_type_link filter-

'rewrite' => array( 'slug' => 'item/%types%/%locations%' ),

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.