0

I'm trying to create a permalink for single posts that are in a particular category called 'Test'. So I've set the stub with a filter which in turn sets the permalink when the post is saved. At the moment I have it hardcoded to 'test/post1'. Stub and permalink set just fine. I then have a rewrite rule which writes 'test/post1/' to 'index.php?pagename=test/post1' (again hardcoded just to test).

It looks like it's sort of working but wordpress only shows me the index with no posts (404) - so I'm seeing the all posts page rather than the single post page. Anyone know what might be wrong?

add_filter( 'wp_unique_post_slug', 'filter_wp_unique_post_slug', 10, 4 ); 
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('init','flushRules'); 

function filter_wp_unique_post_slug( $slug, $post )
{
// Get the categories for the post
$category = get_the_category($post->ID); 
if (  !empty($category) && $category[0]->cat_name == "Test" )
{
    $slug = 'test/post1';
}
return $slug; 
};

// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
$newrules = array();
$newrules['(.*)/(.*)/$'] = 'index.php?pagename=test/post1';
return $newrules + $rules;
}

// Remember to flush_rules() when adding rules
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}

Edit 1

@Milo, I had tried the permalink filter but when it didn't work and I noticed the slug was different I thought there may have been an issue there. I used this (below) previously. The permalink looks like this 'test/post1' and the slug like this 'post1'. Now I see the all posts page with the correct post preview on its own - it's still not the single post page of that post.

add_filter( 'post_link', 'custom_permalink', 10, 3 ); 
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('init','flushRules'); 

function custom_permalink( $permalink, $post, $leavename ) {
  $category = get_the_category($post->ID); 
  if (  !empty($category) && $category[0]->cat_name == "Test" )
  {
      $permalink = trailingslashit( home_url('test/' . $post->post_name ) );
  }
  return $permalink;
}

function flushRules(){
  global $wp_rewrite;
  $wp_rewrite->flush_rules();
}

function wp_insertMyRewriteRules($rules)
{
  $newrules = array();
  $newrules['(.*)/(.*)/$'] = 'index.php?name=post1';
  return $newrules + $rules;
}
2
  • A few things- pagename is the query var for the page post type, name is the query var for the post post type. See the WP_Query codex page for the full list of query vars. The other issue is that post slugs can't have directory separators in them. The slug isn't the full permalink, it's just the post name. You'll need to use the post_link filter to correctly return post permalinks with category slugs.
    – Milo
    Aug 11, 2017 at 3:44
  • @Milo - Question updated in response to your comment. Aug 11, 2017 at 9:26

1 Answer 1

1

I don't understand why but the regex seemed to be the last issue. It was catching it but even with the post name hardcoded in it didn't work correctly. This is the final working version.

add_filter( 'post_link', 'custom_permalink', 10, 3 ); 
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('init','flushRules'); 

function custom_permalink( $permalink, $post, $leavename ) {
  $category = get_the_category($post->ID); 
  if (  !empty($category) && $category[0]->cat_name == "Test" )
  {
      $permalink = trailingslashit( home_url('test/' . $post->post_name ) );
  }
  return $permalink;
}

function flushRules(){
  global $wp_rewrite;
  $wp_rewrite->flush_rules();
}

function wp_insertMyRewriteRules($rules)
{
  $newrules = array();
  $newrules['^test/(.*)$'] = 'index.php?name=$matches[1]';
  return $newrules + $rules;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.