0

A wordpress website with bilingual setup, with three languages:

  • English ("primary language") : "en"
  • Traditional Chinese : "zh-hant"
  • Simplified Chinese : "zh-hans"

The bilingual setup is currently achieved with the polylang plugin.

I would like to have different URL structure based on the post's language.

For English,

example.com/blog/%category%/%postname%/

And the above permalink sturcture is my current set up in the WP permalink setting page. (custom structure, /blog/%category%/%postname%/)

But for non-English blog post URL, I would like to use post id instead of postname:

example.com/zh-hant/blog/%category%/%post_id%

The polylang plugin does not allow me to have different permalink setting per language, so I think I need a custom function solution to this.

6
  • Please follow the plugins guides. URL Modification is answer. polylang.wordpress.com/documentation/… Commented Jun 13, 2021 at 20:42
  • Hi thanks for the comments, but the plugin itself doesn't allow you to do different setting per language. I am looking for a custom function solution to this question.
    – Atimmy
    Commented Jun 13, 2021 at 20:53
  • %post_title% - I think you meant %postname%? And what is your current permalink structure? Does it have "blog" - blog/%category%/%postname% - could you please add the structure into your post?
    – Sally CJ
    Commented Jun 14, 2021 at 3:50
  • Hi Sally, you are right, I made a typo when I posted the question. My current permalink setting is (1) Custom Structure, (2) /blog/%category%/%postname%/
    – Atimmy
    Commented Jun 14, 2021 at 4:05
  • Thanks for editing the post, but that example.com/blog/zh-hant/, I believe, should have been example.com/zh-hant/blog/.. :) Anyway, see my answer.
    – Sally CJ
    Commented Jun 14, 2021 at 7:12

1 Answer 1

1

Try the following steps:

  1. Add the rewrite rules for the <language>/blog/%category%/%post_id% structure.

    I used the post_rewrite_rules hook to add the rewrite rules, but for generating the rewrite rules, I used WP_Rewrite::generate_rewrite_rules() the same way WordPress core used it to generate the rewrite rules for the default permalink structure (that you set via the Permalink Settings page).

    add_filter( 'post_rewrite_rules', 'my_post_rewrite_rules' );
    function my_post_rewrite_rules( $post_rewrite ) {
        global $wp_rewrite;
    
        // Generate the rewrite rules for example.com/<language>/blog/<category slug or path>/<post ID>/
        $post_rewrite2 = $wp_rewrite->generate_rewrite_rules(
            '^zh-han[st]/blog/%category%/%post_id%',
            EP_PERMALINK
        );
    
        // Combine the rules, with the new ones at the top.
        return array_merge( $post_rewrite2, $post_rewrite );
    }
    
  2. The above step ensures that the URLs do not result in a 404 error, and now, we need to filter the permalink URL generated via get_permalink() so that the URL uses the correct structure.

    Normally, one would use the post_link hook to replace the rewrite tag (%post_id% in your case), but %post_id% is a core rewrite/structure tag in WordPress, so we can simply use the pre_post_link hook to set the structure to /blog/%category%/%post_id%/ if the post language (slug) is zh-hans or zh-hant. I.e. We just need to set the structure and the tag will be replaced by WordPress.

    Note: pll_get_post_language() is a Polylang function; see here for further details.

    add_filter( 'pre_post_link', 'my_pre_post_link', 10, 3 );
    function my_pre_post_link( $permalink, $post, $leavename ) {
        if ( ! $leavename && is_object( $post ) &&
            preg_match( '#^zh-han[st]$#', pll_get_post_language( $post->ID ) )
        ) {
            $permalink = '/blog/%category%/%post_id%/';
        }
    
        return $permalink;
    }
    
  3. Be sure to flush the rewrite rules after you've added the above functions to your theme/plugin — just visit the Permalink Settings page without having to click on the Save Changes button.

Additionally, the RegEx pattern ^zh-han[st] will match both zh-hans and zh-hant. You can test it here.

11
  • Hi Sally, thank you for the answer. It works like a charm. Only thing I notice is that I have yoast SEO plugin installed, and when I create a new post in Chinese, upon clicking on the save button, it trigger yoast plugin to create URL redirection. Seems like when I save the post, it created chinese character URL permalink first and immediate the custom function takes effect... and since there was a URL changed, it triggered yoast plugin to created an URL redirection.
    – Atimmy
    Commented Jun 14, 2021 at 9:24
  • Try the updated code in step 2, but if the issue still happens, then I'm afraid there's nothing else I could do..
    – Sally CJ
    Commented Jun 14, 2021 at 10:02
  • Tried the update code, the site still create chinese URL first before the custom code. Overall, it still works for me, I just have to delete the redirection from yoast plugin, thank you for your help Sally. PS. I still need help with the other question... kindly help me out when you have time. Thank you again!
    – Atimmy
    Commented Jun 14, 2021 at 13:05
  • Actually, what do you mean by "create URL redirection"? Can you try disabling all other plugins? Did you use Gutenberg or the old/classic editor? If you deactivate Yoast, does the issue persist? Can you show (like via a short video) the steps you took when "saving" the post?
    – Sally CJ
    Commented Jun 14, 2021 at 14:07
  • If you mean the original permalink with the slug in the URL (e.g. example.com/zh-hant/blog/uncategorized-zh-hant/你好,世界!), then yes, I didn't include the code which disables that original URL.
    – Sally CJ
    Commented Jun 14, 2021 at 14:09

Your Answer

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

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