url rewriting - Insert post ID into the end of a slug preceeded by a dash

admin2025-06-05  1

I would like to dynamically insert post IDs into their URL slugs.

What I have

  • Code that strips out the prepended post name (WC's '/product')
  • Code that generates the URL that I want

What I want

  • URLs that look like: ~/category-name/hey-slug-12903/
  • The reason for this is I have loads of products that are only different because of the category within which they reside...as such I want to automatically insert the ID within the subdirectory to prevent any duplicate weirdness.
  • I do not want IDs to be appended as superfluous subdirectories like: ~/category-name/hey-slug/12903/ or ~/category-name/12903/hey-slug/

My Issue

  • I'm getting 404s (I've flushed rewrite rules)
  • I don't know if I also need to use add_rewrite_rule();

My Code:

add_filter( 'post_type_link', 'wpp_remove_slug', 10, 3 );
function wpp_remove_slug( $post_link, $post, $name ) {

    if ( 'product' != $post->post_type || 'publish' != $post->post_status ) {
      return $post_link;
    }
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    $post_link = substr($post_link, 0, -1);
    $post_link = $post_link . "-" . $post->ID . '/';
    return $post_link;


}

I would like to dynamically insert post IDs into their URL slugs.

What I have

  • Code that strips out the prepended post name (WC's '/product')
  • Code that generates the URL that I want

What I want

  • URLs that look like: ~/category-name/hey-slug-12903/
  • The reason for this is I have loads of products that are only different because of the category within which they reside...as such I want to automatically insert the ID within the subdirectory to prevent any duplicate weirdness.
  • I do not want IDs to be appended as superfluous subdirectories like: ~/category-name/hey-slug/12903/ or ~/category-name/12903/hey-slug/

My Issue

  • I'm getting 404s (I've flushed rewrite rules)
  • I don't know if I also need to use add_rewrite_rule();

My Code:

add_filter( 'post_type_link', 'wpp_remove_slug', 10, 3 );
function wpp_remove_slug( $post_link, $post, $name ) {

    if ( 'product' != $post->post_type || 'publish' != $post->post_status ) {
      return $post_link;
    }
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    $post_link = substr($post_link, 0, -1);
    $post_link = $post_link . "-" . $post->ID . '/';
    return $post_link;


}
Share Improve this question edited Dec 28, 2018 at 17:37 Ryan Dorn asked Dec 28, 2018 at 15:16 Ryan DornRyan Dorn 3699 silver badges23 bronze badges 2
  • Have you tried using the %post_id% and %product_cat% tags in the custom base for the permalink product settings? – birgire Commented Dec 28, 2018 at 16:48
  • Yes, I have tried /%product_cat%/%post_id%- in permalink settings, but WP always appends a / ..when I try to remove the slash and make the ID separated by a dash, I get a 404 again. – Ryan Dorn Commented Dec 28, 2018 at 17:37
Add a comment  | 

1 Answer 1

Reset to default 2

The rewrite argument in register_post_type is limited, but you can define a more complex structure with add_permastruct. The added benefits are that this will generate all the rewrite rules for you, and the new rules will overwrite the originals. You just have to be sure to hook after the post type is registered.

function wpd_woo_product_permastruct(){
    add_permastruct(
        'product',
        '%product_cat%/%product%-%post_id%/',
        array(
            'walk_dirs' => false,
            'with_front' => false
        )
    );
}
add_action( 'init', 'wpd_woo_product_permastruct', 99 );

And that is, magically, all you need. The rewrite tag replacements will be done for you, so the post_type_link filter won't be needed.

Normally, the absence of a static slug would cause clashes with other rules, but in this case it works because the embedded post ID triggers a more strict match.

What you can't have is the %product_cat% rules without a static slug, which is why we have to set walk_dirs to false. Otherwise, any request for a root page will be overridden by the taxonomy rule, and WordPress will go looking for a term that matches your page slug.

If you do want rules that introduce this ambiguity, you can do something like this answer, where you manually resolve conflicts.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749061120a316019.html

最新回复(0)