Bilingual WP site: How to achieve different URL sturcture rule based on its language?

The question:

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,

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:

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.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 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<language>/blog/<category slug or path>/<post ID>/
        $post_rewrite2 = $wp_rewrite->generate_rewrite_rules(
        // 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.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment