Custom Taxonomy in Permalink of Post

It is possible to use this as a permalink for a post:

/%category%/%postname%/

But lets say I’ve created a taxonomy called “artist”. I’d like to use this for my posts:

Read More
/%artist%/%postname%/

I know that taxonomies allow you to list their terms with this:

/%artist%/%someartist%/

but that is not what I’m looking for. I want to modify POST urls, not taxonomy ones.

I’m trying this on my blog and it is not working. Is this something that can be done in WordPress?

Related posts

Leave a Reply

3 comments

  1. Assuming your custom taxonomy is called artist (and you don’t override the slug in the rewrite parameter) you can use the rewrite tag %artist%. WordPress implements almost every functionality to use those rewrite tags in post permalinks. There are only a few small adaptations necessary.

    Building the Permalink

    First, you’ll need to use the post_link filter to replace a custom »tag« in your request structure:

    /**
     * replace the '%artist%' tag with the first 
     * term slug in the artist taxonomy
     * 
     * @wp-hook post_link
     * @param string $permalink
     * @param WP_Post $post
     * @return string
     */
    function wpse_56769_post_link( $permalink, $post ) {
    
        $default_term = 'no_artist';
        $terms = wp_get_post_terms( $post->ID, 'artist' );
        if ( ! empty( $terms ) && ! is_wp_error( $terms ) )
            $term = current( $terms )->slug;
        else
            $term = $default_term;
    
        $permalink = str_replace( '%artist%', $term, $permalink );
    
        return $permalink;
    }
    add_filter( 'post_link', 'wpse_56769_post_link', 10, 2 );
    

    This function (wpse_56769_post_link):

    • defines a default term slug (no_artist) which is used as fallback if the post as no assigned terms in the artist taxonomy,
    • fetches the first assigned term (in alphabetical order) of the artist taxonomy,
    • replaces the tag %artist% with the slug of this term.

    Now, go to the menu Settings → Permalinks, choose the option »Custom Structure« and write in: /%artist%/%postname%/.

    In the result, a post permalink should look like this:

    Using the first term as URL slug

    Now that the post permalinks inkludes the first artist term slug, let’s have a look to the routing.

    Update the permalinks (Routing)

    You will notice, that the permalink is resolved correctly to the single post. Unfortunately, page permalinks are broken.

    To solve this problem, you don’t necessarily need to alter the rewrite rules. The only thing we need to do is to change the internal state of WP_Rewrite. The property WP_Rewrite::use_verbose_page_link needs to be set to TRUE. (This is the internal behaviour of WP_Rewrite when using %category% or %author% tags as base for post permalinks.)

    /**
     * set WP_Rewrite::use_verbose_page_rules to TRUE if %artist%
     * is used as the first rewrite tag in post permalinks
     * 
     * @wp-hook do_parse_request
     * @wp-hook page_rewrite_rules
     * @global $wp_rewrite
     * @param mixed $pass_through (Unused)
     * @return mixed
     */
    function wpse_56769_rewrite_verbose_page_rules( $pass_through = NULL ) {
    
        $permastruct = $GLOBALS[ 'wp_rewrite' ]->permalink_structure;
        $permastruct = trim( $permastruct, '/%' );
        if ( 0 !== strpos( $permastruct, 'artist%' ) )
            return $pass_through;
    
        $GLOBALS[ 'wp_rewrite' ]->use_verbose_page_rules = TRUE;
        return $pass_through;
    }
    add_filter( 'page_rewrite_rules', 'wpse_56769_rewrite_verbose_page_rules', PHP_INT_MAX );
    add_filter( 'do_parse_request',  'wpse_56769_rewrite_verbose_page_rules', PHP_INT_MAX );
    

    The state has to be changed at two points: do_parse_request because WP::parse_request() asks for this state and page_rewrite_rules for when the rewrite rules gets build.

    Now, the routing is fixed and page permalinks works well. (After flushing the permalinks once again.)

    Handle the no_artist pseudo term

    One last thing on the no_artist thing: If the post really is not assigned to any term of the artist taxonomy, the permalink is parsed to the following query variables:

    name   => 'sample_post'
    artist => 'no_artist'
    page   => ''
    

    This should lead to a 404 because the term doesn’t exists. As the post’s name should be unique we can remove the artist query variable on the request filter:

    /**
     * check for existing artist and set query to 404 if necessary
     *
     * @wp-hook parse_query
     * @param array $request_vars
     * @return array
     */
    function wpse_56769_request_vars( $request_vars ) {
    
        if ( ! isset( $request_vars[ 'artist' ] ) )
            return $request_vars;
    
        if ( ! isset( $request_vars[ 'name' ] ) )
            return $request_vars;
    
        if ( 'no_artist' == $request_vars[ 'artist' ] )
            unset( $request_vars[ 'artist' ] );
    
        return $request_vars;
    }
    add_filter( 'request', 'wpse_56769_request_vars' );
    

    With that filter, a post like http://wordpress.dev/no_artist/sample-post/ will be found properly.

  2. I think this is what your looking for:
    Custom Post Type Permalinks

    This plugin lets you edit the permalink structure of custom post type.

    To install this plugin:

    1. Download the custom-post-type-permalinks.zip file to your computer.
    2. Unzip the file.
    3. Upload the custom-post-type-permalinks directory to
      your /wp-content/plugins/ directory.
    4. Activate the plugin through the ‘Plugins’ menu in WordPress.

    You can also go to the ‘Plugins’ menu in your wordpress and click “add new”. Then find this plugin by searching for “Custom Post Type Permalinks” and install it by clicking the install button.

    A new item will appear in the menu on the left of your wordpress admin. Here you can change the settings depending on your needs (names of the taxonomies etc).


    Futhermore my site currently has the following permalink structure “site.com/star/aristname/” which then list all posts for this artist or a page/post about this artist.

    If your looking for this you can create an archive page for your custom post type. WordPress will automaticly assume this structure. For more information on how to create your own archive page please go here. (If your indeed looking for this, I can explain it more thoroughly if you want)

  3. Whan i wanted to hook url to category (in any url structure) i set a list of terms into url rewrite structure , but in my case there was not much terms…

    the results was something like
    rewrite rule key

    publications/(annual-reports|articles|books|policy-briefs)/([^/]+).html?$ 
    

    and rule value

    index.php?post_type=publication&category_publication=$matches[1]&publication=$matches[2]&paged=1
    

    everything was hooked using rewrite_rules_array filter.

    result you can see at http://unu.edu/publications