WPML lets you use unique URLs for custom content in different languages. This includes translating the post slug, as well as the name of the custom post type.

URLs for custom post types include the name of the post-type and the page name. Typically, custom post types in different language will look like:

  • /houses/my-green-house/
  • /casas/mi-casa-verde/

The first part of the URL, in bold, is the post type. The second type is the page name.

To translate page names, click on the Edit button next to the permalink field in the post editor. Since WPML uses a different post for each language, you can set their names individually.

Editing page permalinks

Translating Names of Custom Post Types

To allow WPML to translate custom post type names, you need to use the String Translation module.

Declaring custom post types in PHP

If you are registering custom post types manually, via PHP, WPML will catch these calls and register the slug for translation.

Declaring custom post types with Types

To define custom post types without PHP, you can use our Types plugin. Types will automatically declare custom post types, so that you can translate them in WPML.

Go to Types and edit a custom post type. If it’s not enabled for name-translation, you will see a link to WPML’s setup screen:

Types links to WPML to setup slug localization

Enabling Custom-Post-Type Name Localization in WPML

Next, go to WPML->Translation Management->Multilingual content setup. You’ll see the new section for localizing slugs.

The checklist for enabling custom post type name localization is:

1. Make that custom post type translatable

Set the custom post type to Translate

2. Enable slug translation for the site

Click on the checkbox to allow localized post type names for the entire site

3. Select to use different slugs in different languages

Click on the checkbox to allow localizing each custom post type name

Now you are ready to translate the names of custom post types. Enter their translations, hit Save and they should appear in URLs.

Translating Custom Post Type Archives

When you register custom post types manually, WordPress allows you to set a distinct archive slug using:

has_archive

As of version 3.2, WPML allows has_archive to be set to a string. However, if the string value is set to something other than rewrite['slug'], or the CPT name slug is not set, the archive slug will not be translatable.

Example code 1:

In this code example, we set 'has_archive' => true. Assuming that the slug book has been translated to libro in Spanish, the archive links are in the following:

  • English (default language): http://mydomain.tld/book/
  • Spanish (second language): http://mydomain.tld/es/libro/
add_action( 'init', 'create_post_type' );
function create_post_type() {
    register_post_type( 'book',
        array(
            'labels' => array(
                'name' => __( 'Books', 'textdomain' ),
                'singular_name' => __( 'Book', 'textdomain' )
            ),
            'public' => true,
            'has_archive' => true,
            'publicly_queryable' => true,
            'exclude_from_search' => false,
            'show_ui' => true,
            'show_in_menu' => true,
            'query_var' => true,
            'rewrite' => array('slug' => 'book'),
            'supports' => array('title','editor', 'custom-fields','thumbnail')
        )
    );
}

Example code 2:

In this code example, we set a specific string for the parameter 'has_archive' => 'my-books'. Now the archive links are as follows:

  • English (default language): http://mydomain.tld/my-books/
  • Spanish (second language): http://mydomain.tld/es/my-books/
add_action( 'init', 'create_post_type' );
function create_post_type() {
    register_post_type( 'book',
        array(
            'labels' => array(
                'name' => __( 'Books', 'textdomain' ),
                'singular_name' => __( 'Book', 'textdomain' )
            ),
            'public' => true,
            'has_archive' => 'my-books', // Do not use the gettext functions for this parameter
            'publicly_queryable' => true,
            'exclude_from_search' => false,
            'show_ui' => true,
            'show_in_menu' => true,
            'query_var' => true,
            'rewrite' => array('slug' => 'book'),
            'supports' => array('title','editor', 'custom-fields','thumbnail')
        )
    );
}