Darren Cooney
Darren Cooney

Reputation: 1060

Remove custom taxonomy base slug from archive permalink

I'm looking for a rewrite rule to remove the base taxonomy slug (topic) from a WordPress taxonomy archive permalink.

An example of the functionality I'm looking for is as follow:

http://website.com/topic/health would remove the /topic base slug and become http://website.com/health/

I'm sure this is possible with rewrite rules, but what would that rewrite look like?

Upvotes: 1

Views: 5364

Answers (2)

grappler
grappler

Reputation: 567

When registering your custom taxonomy either remove the rewrite argument or set it to false.

add_action( 'init', 'namespace_register_taxonomy' );    
/**
 * Register a private 'Topic' taxonomy for post type 'Post'.
 */
function namespace_register_taxonomy() {
    $args = [
        'label'.  => __( 'Genre', 'textdomain' ),
        'public'  => true,
        'rewrite' => false,
    ];
    register_taxonomy( 'topic', 'post', $args );
}

Using the {$permastructname}_rewrite_rules filter you can modify the rewrite rules. Replace the taxonomy slug in two places to make it work for your taxonomy. Flush the rewrite rules to see it work.

add_filter( 'topic_rewrite_rules', 'namespace_topic_rewrite_rules' );
/**
 * Filters rewrite rules used for individual permastructs.
 *
 * @param string[] $rules Array of rewrite rules generated for the current permastruct, keyed by their regex pattern.
 * @return string[] Array of rewrite rules.
 */
public function namespace_topic_rewrite_rules( array $rules ): array {
    $terms = get_terms(
        [
            'taxonomy'   => 'topic',
            'hide_empty' => false,
        ]
    );
    $slugs         = wp_list_pluck( $terms, 'slug' );
    $slugs_pattern = '(' . implode( '|', array_unique( $slugs ) ) . ')';

    $new_rules = [];
    foreach ( $rules as $pattern => $query ) {
        $pattern               = str_replace( 'topic/([^/]+)', $slugs_pattern, $pattern );
        $new_rules[ $pattern ] = $query;
    }
    return $new_rules;
}

Now that the archive page is working, the link to the term archive page needs to be modified.

add_filter( 'term_link', 'namespace_topic_term_link', 10, 3 );
/**
 * Remove base from Topic taxonomy term link.
 *
 * @param string   $termlink Term link URL.
 * @param \WP_Term $term     Term object.
 * @param string   $taxonomy Taxonomy slug.
 * @return string Term link URL.
 */
public function namespace_topic_term_link( string $termlink, \WP_Term $term, string $taxonomy ): string {
    if ( 'topic' === $taxonomy ) {
        $termlink = str_replace( 'topic/', '', $termlink );
    }
    return $termlink;
}

Upvotes: 2

Ashish Patel
Ashish Patel

Reputation: 3614

Hope below code will help you:

function custom_topic_link( $link, $term, $taxonomy )
{
    if ( $taxonomy !== 'topic' )
        return $link;

    return str_replace( 'topic/', '', $link );
 }
add_filter( 'term_link', 'custom_topic_link', 10, 3 );

Upvotes: 0

Related Questions