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,
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
Method 2
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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0