WordPress教學 – WooCommerce product permalinks to id

Posted in :

遇到「商品的預設網址是ID」 的需求修改好了。以後不用自己去修改「固定網址」欄位。

WooCommerce預設的 Rule 如下:


Product Permalinks

These settings control the permalinks used for products:

 

If you’re not using pretty permalinks, ‘default’ will be the only optional available to you and will use ID based URLs. e.g. yourdomain.com/?product=111. If you are using pretty permalinks, the default will be yourdomain.com/product/product-name.

The other options allow you to prepend the product permalinks with something custom, such as the shop page name, or a completely custom permalink you define.

Please note: The product custom base should not conflict with the taxonomy permalink bases. If you set the product base to ‘shop’ for example, you should not set the product category base to ‘shop’ too as this will not be unique and will conflict. WordPress requires something unique so it can distinguish categories from products.


The site that I am working on uses the following “pretty” permalink structure:

http://example.com/blog/my-special-post

But for a custom post type my client would like to avoid having a “pretty” slug:

http://example.com/product/142

How can the post ID be used in place of the slug for the custom post type?

I believe that this might be possible using WP_Rewrite, but I do not know where to begin.


This is what I use to rewrite custom post type URLs with the post ID. You need a rewrite rule to translate URL requests, as well as a filter on post_type_link to return the correct URLs for any calls to get_post_permalink():

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);

function wpse33551_post_type_link( $link, $post = 0 ){
    if ( $post->post_type == 'product' ){
        return home_url( 'product/' . $post->ID );
    } else {
        return $link;
    }
}

add_action( 'init', 'wpse33551_rewrites_init' );

function wpse33551_rewrites_init(){
    add_rewrite_rule(
        'product/([0-9]+)?$',
        'index.php?post_type=product&p=$matches[1]',
        'top' );
}

I’m looking for a way to put a Woocommerce product ID in a URL, e.g.:

domain.com/product-category/id/product-title

The ID is the product’s post ID, e.g. “12092”. Automatically created by WooCommerce in WordPress.

Can this be done in a way? Either easily through the WordPress permalinks settings or in a different way through hacking my way into the files.

This nearly works:

<?php

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);

function wpse33551_post_type_link( $link, $post = 0 ){
if ( $post->post_type == 'product' ){
    return home_url( 'p/' . $post->ID );
} else {
    return $link;
}
}

add_action( 'init', 'wpse33551_rewrites_init' );

function wpse33551_rewrites_init(){
add_rewrite_rule(
    'product/([0-9]+)?$',
    'index.php?post_type=product&p=$matches[1]',
    'top' );
}

?>

But the output is:

 domain.com/p/45

I’d like it to be:

 domain.com/p/45/title-of-the-post

Use a more permissive regular expression to accept any url that ends with /p/[id][anything]

<?php

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);
function wpse33551_post_type_link( $link, $post = 0 ){
    if ( $post->post_type != 'product' )
      return $link;

    return home_url( 'p/' . $post->ID . '/' . $post->post_name );
}

add_action( 'init', 'wpse33551_rewrites_init' );
function wpse33551_rewrites_init(){
    add_rewrite_rule(
        'p/([0-9]+)?.*?$',
        'index.php?post_type=product&p=$matches[1]',
        'top'
    );
}

?>

You might need to ‘reset’ your permalinks in the settings menu for WordPress to accept the new rule.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *