3

For the purposes of my site, I have my Permalinks set to /blog/%postname%/ for all posts.

However, I need to give Posts with a specific Category (in this case, "Testimonials") its own permalink structure, where each individual post assigned the Category "Testimonials" returns as /testimonials/%postname%/ and the Category Archive page returns as /testimonials/.

Here is the code I have so far:

//Rewrite URLs for "testimonial" category
add_filter( 'post_link', 'custom_permalink', 10, 3 );
function custom_permalink( $permalink, $post, $leavename ) {
    // Get the category for the post
    $category = get_the_category($post->ID);
    if (  !empty($category) && $category[0]->cat_name == "Testimonials" ) {
        $cat_name = strtolower($category[0]->cat_name);
        $permalink = trailingslashit( home_url('/'. $cat_name . '/' . $post->post_name .'/' ) );
    }
    return $permalink;
}

add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
    add_rewrite_rule(
        'testimonials/([^/]+)(?:/([0-9]+))?/?$',
        'index.php?category_name=testimonials&name=$matches[1]&page=$matches[2]',
        'top' // The rule position; either 'top' or 'bottom' (default).
    );
}

This successfully returns each individual post with the category "Testimonials" as /testimonials/%postname%/. However, the Category Archive page returns as /blog/category/testimonials. I need this to just return as /testimonials/, while still returning all other Posts as /blog/%postname%/

I tried using this plugin, https://wordpress.org/plugins/custom-permalinks/, which solved the Category Archive page issue, but broke each individual testimonial post, returning them as a 404 error.

In this case, I cannot register Testimonials as a Custom Post Type as it will affect other site functionality,

  • Is there a reason you don't have the testimonials set as a custom post type? – thosetinydreams Mar 13 '18 at 22:12
  • The site was inherited from a previous developer. I'd like to know if I can solve this issue by rewriting the URL structure, as opposed to registering a custom post type and porting every single Post with that category over to it. – user3183717 Mar 13 '18 at 22:55
4

Try these steps:

Step #1: Replace this:

add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
    add_rewrite_rule(
        'testimonials/([^/]+)(?:/([0-9]+))?/?$',
        'index.php?category_name=testimonials&name=$matches[1]&page=$matches[2]',
        'top' // The rule position; either 'top' or 'bottom' (default).
    );
}

..with this one:

add_filter( 'category_link', 'custom_category_permalink', 10, 2 );
function custom_category_permalink( $link, $cat_id ) {
    $slug = get_term_field( 'slug', $cat_id, 'category' );
    if ( ! is_wp_error( $slug ) && 'testimonials' === $slug ) {
        $link = home_url( user_trailingslashit( '/testimonials/', 'category' ) );
    }
    return $link;
}

add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
    add_rewrite_rule(
        'testimonials(?:/page/?([0-9]{1,})|)/?$',
        'index.php?category_name=testimonials&paged=$matches[1]',
        'top' // The rule position; either 'top' or 'bottom' (default).
    );

    add_rewrite_rule(
        'testimonials/([^/]+)(?:/([0-9]+))?/?$',
        'index.php?category_name=testimonials&name=$matches[1]&page=$matches[2]',
        'top' // The rule position; either 'top' or 'bottom' (default).
    );
}

Step #2: Go to the Permalink Settings page, and click on the Save Changes button without actually making any changes.

  • 1
    This worked, thank you very much. Encouraging to know that thinking to add another "add_rewrite_rule" function was on the right track, but I had not known about the "category_link" filter. Thanks again! – user3183717 Mar 14 '18 at 15:32
  • You're very welcome. =) – Sally CJ Mar 15 '18 at 0:16
0

Why not just add the post id then? If that's all you need? You could just do this with query_vars

add_filter('query_vars', 'my_query_vars' );

You only need to check if you are in the 'special' category and if yes, add the var. Then utilizing the pre_get_posts hook, check if your post contains an ID and if yes change your query to get desired post.

  • without adding actual rewrite rules wordpress will not know how to parse the url. There is no way to go around it – Mark Kaplun Mar 14 '18 at 7:25

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.