i am trying to give a specific category posts it's own permalink. Followed the steps from this topic (Give specific category its own permalink structure) but the posts are giving a 404 error.
Cleared cache, saved permalinks under settings but to no avail.
Would appreciate help in fixing this.
Thanks
here is my code:
//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 == "Foodguide" ) {
$cat_name = strtolower($category[0]->cat_name);
$permalink = trailingslashit( home_url('/'. $cat_name . '/' . $post->ID . '/' . $post->post_name .'/' ) );
}
return $permalink;
}
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 ) && 'foodguide' === $slug ) {
$link = home_url( user_trailingslashit( '/foodguide/', 'category' ) );
}
return $link;
}
add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
add_rewrite_rule(
'foodguide(?:/page/?([0-9]{1,})|)/?$',
'index.php?category_name=foodguide&paged=$matches[1]',
'top' // The rule position; either 'top' or 'bottom' (default).
);
add_rewrite_rule(
'foodguide/([^/]+)(?:/([0-9]+))?/?$',
'index.php?category_name=foodguide&name=$matches[1]&page=$matches[2]',
'top' // The rule position; either 'top' or 'bottom' (default).
);
}
i am trying to give a specific category posts it's own permalink. Followed the steps from this topic (Give specific category its own permalink structure) but the posts are giving a 404 error.
Cleared cache, saved permalinks under settings but to no avail.
Would appreciate help in fixing this.
Thanks
here is my code:
//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 == "Foodguide" ) {
$cat_name = strtolower($category[0]->cat_name);
$permalink = trailingslashit( home_url('/'. $cat_name . '/' . $post->ID . '/' . $post->post_name .'/' ) );
}
return $permalink;
}
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 ) && 'foodguide' === $slug ) {
$link = home_url( user_trailingslashit( '/foodguide/', 'category' ) );
}
return $link;
}
add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
add_rewrite_rule(
'foodguide(?:/page/?([0-9]{1,})|)/?$',
'index.php?category_name=foodguide&paged=$matches[1]',
'top' // The rule position; either 'top' or 'bottom' (default).
);
add_rewrite_rule(
'foodguide/([^/]+)(?:/([0-9]+))?/?$',
'index.php?category_name=foodguide&name=$matches[1]&page=$matches[2]',
'top' // The rule position; either 'top' or 'bottom' (default).
);
}
Share
Improve this question
edited Sep 26, 2019 at 5:21
Praveen Kumar
asked Sep 26, 2019 at 3:45
Praveen KumarPraveen Kumar
53 bronze badges
5
|
2 Answers
Reset to default 0First off, the add_rewrite_rule()
syntax is add_rewrite_rule( 'RegEx pattern', 'WordPress query string/vars', 'position/priority - top or bottom' )
.
Now I could see you're trying to have the following permalink structure:
Structure: example/foodguide/<post ID>/<post slug>
Example: example/foodguide/1/sample-food-guide
But your rewrite rule (the second one in your code) does not have the proper RegEx subpattern for the post ID part in the permalink; hence, the permalink leads to a 404
error page.
And to fix the issue, you can add \d+/
to the rewrite rule:
add_rewrite_rule(
'foodguide/\d+/([^/]+)(?:/([0-9]+))?/?$', // <- here, add the \d+/
'index.php?category_name=foodguide&name=$matches[1]&page=$matches[2]',
'top'
);
Alternatively, in the RegEx pattern, you can "capture" the post ID (i.e. use (\d+)
) and not the post slug, and then in the WordPress query, use the p
(i.e. ID) parameter instead of name
(i.e. slug):
add_rewrite_rule(
'foodguide/(\d+)/[^/]+(?:/([0-9]+))?/?$', // capture the \d+
// $matches[1] is now the post ID, so use &p= instead of &name=
'index.php?category_name=foodguide&p=$matches[1]&page=$matches[2]',
'top'
);
PS: Don't forget to flush the rewrite rules — just visit the permalink settings page.
UPDATE
If you want the post permalink to end with a .html
, then:
In
custom_permalink()
, make the following change:// Change this: $permalink = trailingslashit( home_url('/'. $cat_name . '/' . $post->ID . '/' . $post->post_name .'/' ) ); // To this: $permalink = untrailingslashit( home_url( '/'. $cat_name . '/' . $post->ID . '/' . $post->post_name . '.html' ) );
In
custom_rewrite_rules()
, change the secondadd_rewrite_rule()
to this:add_rewrite_rule( '^foodguide/(\d+)/[^/]+\.html$', 'index.php?category_name=foodguide&p=$matches[1]', 'top' );
After the
function custom_rewrite_rules() { ... }
, add this:function cancel_canonical_redirect( $wp ) { if ( '^foodguide/(\d+)/[^/]+\.html$' === $wp->matched_rule ) { remove_action( 'template_redirect', 'redirect_canonical' ); } } add_action( 'parse_request', 'cancel_canonical_redirect' );
That would prevent "adding" the ending slash (
/
) to the permalink URL.
And once again, don't forget to flush the permalinks.
Also, I've not added support for paginated requests (i.e. posts having the <!--nextpage-->
tag or the Page Break block in Gutenberg); and if you need that, let me know.
UPDATE 2
For paginated requests with this permalink/URL structure:
example/foodguide/<post ID>/<post slug>/page-<page number>.html
In
custom_rewrite_rules()
, change the secondadd_rewrite_rule()
to this:add_rewrite_rule( '^foodguide/(\d+)/[^/]+(?:/page-(\d+)|)\.html$', 'index.php?category_name=foodguide&p=$matches[1]&page=$matches[2]', 'top' );
Change the
cancel_canonical_redirect
to (* the RegEx pattern needs to match the one used in the aboveadd_rewrite_rule()
):function cancel_canonical_redirect( $wp ) { if ( '^foodguide/(\d+)/[^/]+(?:/page-(\d+)|)\.html$' === $wp->matched_rule ) { remove_action( 'template_redirect', 'redirect_canonical' ); } } add_action( 'parse_request', 'cancel_canonical_redirect' );
After the above code, add this:
function custom_wp_link_pages_link( $link, $i ) { if ( in_category( 'foodguide' ) ) { $name = get_post_field( 'post_name' ); $link = str_replace( "{$name}.html/$i/", // replace example/foodguide/<post ID>/<post slug>.html/<page number>/ "$name/page-{$i}.html", // with example/foodguide/<post ID>/<post slug>/page-<page number>.html $link ); } return $link; } add_filter( 'wp_link_pages_link', 'custom_wp_link_pages_link', 10, 2 );
And as always, be sure to flush the permalinks.
Please remove the code from functions.php. Instead of that do the following,
Step 1:Go to the settings -> permalink in the WordPress dashboard(Refer to this link).
Step 2:Select the Custom Structure in the permalink settings page(Refer to this link).
Step 3:Change the Permalink to our requirement and click the save changes button(Refer this link).
Step 4:Then the permalink of the post is changed as we given in the settings page(Refer this link).
example/foodguide/1/hello-world
), but your rewrite rules doesn't include the pattern for that post ID. So remove the'/' . $post->ID .
(in yourcustom_permalink
function). Otherwise, you need to change the rewrite rules/regex. – Sally CJ Commented Sep 26, 2019 at 6:59