0

I need to have 2 languages in a website (EN and LT). I have a custom post type 'services'. I need to have the links like this:

  • English version of the service: '/en/services/some-service'
  • Lithuanian (translated by Polylang or other plugin): '/lt/paslaugos/some-service'

I have searched for a solution for hours, but all solutions seem to be at least 5 years old, and non working.

For example, I have tried this, with no success:

// Function to register custom post type and taxonomy
function register_custom_post_type_services() {
    $labels = array(
        'name' => _x('Services', 'Post Type General Name', 'text_domain'),
        'singular_name' => _x('Service', 'Post Type Singular Name', 'text_domain'),
    );

    $args = array(
        'label' => __('Service', 'text_domain'),
        // removed some lines for readability for Stack Exchange
        'publicly_queryable' => true,
        'capability_type' => 'page',
        'show_in_rest' => true,
        'rewrite' => array('slug' => get_services_slug()),
    );

    register_post_type('services', $args);
}

// Function to get the language-specific slug
function get_services_slug() {
    $current_language = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : 'en'; 

    switch ($current_language) {
        case 'lt':
            return 'paslaugos'; // Lithuanian slug
        default:
            return 'services'; // English slug
    }
}

add_action('init', 'register_custom_post_type_services');

Two issues occur with this method:

  1. when I'm in EN language, and switch to LT, the post type slug is not translated, but the correct translated version of the post is shown in LT language.

  2. when I'm in LT language already, and then I try to "switch" to LT again, then the post type slug is translated correctly, but a 404 error occurs.

Is there really no way to accomplish this with some code? Paid plugins advertise such functionality, so I believe it should not be that hard to do with some custom coding.

1 Answer 1

0

First, you should have to register your custom post type with a generic, language-independent slug because the slug in register_post_type is not meant to be dynamic.

and then modify rewrite rule

try this snippet

function register_custom_post_type_services() {
    $labels = array(
        'name' => _x('Services', 'Post Type General Name', 'text_domain'),
        'singular_name' => _x('Service', 'Post Type Singular Name', 'text_domain'),
    );

    $args = array(
        'label' => __('Service', 'text_domain'),
        // ... other args
        'publicly_queryable' => true,
        'capability_type' => 'page',
        'show_in_rest' => true,
        'rewrite' => array('slug' => 'services-base'), // Generic slug
    );

    register_post_type('services', $args);
}
add_action('init', 'register_custom_post_type_services');

function custom_rewrite_rules_array($rules) {
    $newRules = array();
    $newRules['en/services/(.+)/?$'] = 'index.php?services=$matches[1]';
    $newRules['lt/paslaugos/(.+)/?$'] = 'index.php?services=$matches[1]';

    return $newRules + $rules;
}
add_filter('rewrite_rules_array', 'custom_rewrite_rules_array');

function custom_post_type_link($post_link, $id = 0, $leavename = false) {
    if (strpos('%services-base%', $post_link) === 'FALSE') {
        return $post_link;
    }
    $post = get_post($id);
    if (is_wp_error($post)) {
        return $post_link;
    }

    // Change 'services-base' based on language
    if (function_exists('pll_current_language')) {
        $language = pll_current_language();
        switch ($language) {
            case 'lt':
                $slug = 'lt/paslaugos';
                break;
            default:
                $slug = 'en/services';
                break;
        }
        return home_url($slug . '/' . $post->post_name);
    }

    return $post_link;
}
add_filter('post_type_link', 'custom_post_type_link', 1, 3);

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.