How to translate custom post types and taxonomies

In this document we explain you how to translate custom post types and taxonomies in MultilingualPress. To demonstrate it, we’ll create a WordPress Multisite installation with two connected sites.

We are going to use the Custom Post Type UI plugin to create a custom post type and a taxonomy. Just keep in mind that the process is the same for any other plugin that creates custom post types or if you register them manually using register_post_type and register_taxonomy.

Setup a WordPress Multisite with 2 connected sites

To setup a WordPress Multisite you can follow our tutorial How to install and set up a WordPress Multisite. Our guide Getting started with MultilingualPress 3 explains how to create the sites and connect them with MultilingualPress. We created 2 sites, one for English and one for German and connected them as you can see in the screenshot below.

Two connected language Sites in a WordPress Multisite
Two sites in a WordPress multisite for English and German connected with MultilingualPress

Install and setup Custom Post Type UI plugin

In the next step we install and activate the Custom Post Type UI plugin. Regarding plugin activation we need to decide if it should be network activated or activated in each site individually. The decision will depend on the plugins ability to support Multisite or not. In this case Custom Post Type UI does not have Multisite support (at least in the free version) so we activate it on each site. To do so, go to the Dashboard of each site and activate the plugin on the Plugins page.

Please note: The plugin you use to create the custom post type has to be network activated in the Multisite environment or, at least, has to be activated also in the main network site in order to make the custom type available across all the network.

Install the plugin Custom Post type UI
Install the plugin Custom Post type UI which we want to use for creating our custom post type and custom taxonomy.

Create a new custom post type and a taxonomy

We first create the custom post type and taxonomy on site 1 and afterwards we will copy them to site 2. We will call our custom post type Recipes and the taxonomy Ingredients.

Create a custom post type Recipes
Create a custom post type Recipes
Create a custom taxonomy Ingredients.
Create a custom taxonomy Ingredients.

To copy the custom post type and taxonomy we use the Export/Import functionality in the Tools page of Custom Post Type UI.

Copy the content of the Export Post Type settings field from site 1...
Copy the content of the Export Post Type settings field from site 1…
... And paste into the field Import Post Types of  site 2.
… And paste into the field Import Post Types of  site 2.

In the next step we do the same export/import for taxonomies via Taxonomies tab.

Enable Custom Post Types and Taxonomies in MultilingualPress Settings

Now that we have custom post type and taxonomy created in both sites, we can configure MultilingualPress in order to be able to translate them. To do so go to My Sites → Network Admin →  Settings →  MultilingualPress and enable the custom post type and the taxonomy in the corresponding tabs, in our case Recipes and Ingredients.

Enable Recipes in Translatable Post Types tab.
Enable Recipes in Translatable Post Types tab.
Enable Ingredients in Translatable Taxonomies tab.
Enable Ingredients in Translatable Taxonomies tab.

Enter Post Type slug value on each site

Before to proceed, please note that MultilingualPress does not translate custom post type slugs, that should be done at registration time via rewrite parameter from register_post_type (e.g. ‘rewrite’ => [‘slug’ => esc_html__(‘my-cpt’, ‘text-domain-here’)] ) and with language files (.po/.mo, .pot). When you have the slugs properly translated then you can tell MultilingualPress which slug to use on each site.

In case you need  to also set the archive page for your custom post type, and then be able to translate it, then you should also have the has_archive parameter set to true when registering the post type; and any custom slug for archive pages should not be specified.

Besides, if the language set in your profile and the one selected in a particular subsite are not the same, the solution above described will be not enough.
In this case, if your profile language and the subsite language are different, you also need to add a code snippet to your code, as an example consider the following snippet added in the functions.php file:

/**
* Updates the rewrite => slug argument when registering a post type.
*
* Will use the option from the "Post Type Slugs" tab the 
* Network Settings of a website, in case it’s not empty.
*
* @see register_post_type()
*
* @param array $args An array of arguments that will be passed to register_post_type().
* @param string $postType The name/slug of the post type.
*
* @return array Updated arguments.
*/
add_filter( 'register_post_type_args', function( $args, $postType ) {

if ( ( isset( $args['_builtin' ] ) && $args['_builtin'] )
|| ( isset( $args['public'] ) && ! $args['public'] )
) {
    return $args;
}
$slugSettings = get_network_option(
            0,
            \Inpsyde\MultilingualPress\Core\Admin\PostTypeSlugsSettingsRepository::OPTION,
            []
        );

$siteId = get_current_blog_id();

if (!empty($slugSettings[$siteId][$postType]) && isset($args['rewrite'], $args['rewrite']['slug'])) {
            $args['rewrite']['slug'] = $slugSettings[$siteId][$postType];
        }

return $args;
}, 10, 2 );

With that filter, doesn’t matter what language is selected in your language settings: the right Custom Post Type slug will be used.
Now we can go on to set our Post Type Slug.

To do so go to My Sites →  Network Admin →  Sites and edit each site. In Post Type Slugs fill in the value of the custom post type slug for our custom post type Recipes. In this case both sites use the same slug, but this feature allows you to setup a different translated slug on each site.

But consider also that when you register a custom post type and you don’t want to translate that post type’s slug, even in that case you should fill in the value in the Post Type Slugs tab in order to let the language menu work correctly.

Enter a slug for your custom post type on each site
Enter a slug for your custom post type on each site

Create some custom posts and taxonomy terms

We can start creating ingredients (taxonomy terms) and recipes (custom posts) in site 1 and then we use the MultilingualPress translation metabox to create the translations for site 2 from there. It is also possible to connect existing content in site 2 from the same translation metabox.

Create some Ingredients in site 1.
Create some Ingredients in site 1.
Create Recipes and assign Ingredients in site 1.
Create Recipes and assign Ingredients in site 1.

Connect Taxonomy Terms with MultilingualPress

After creating the taxonomy terms on the different language sites we need to connect them.  Go to the dashboard of site 1, select Recipes → Ingredients and edit one term. In the translation metabox you can choose Create a new term or Select an existing term. In this case we choose Create a new term. We can fill the fields in Term Data tab manually otherwise the values will be generated automatically for you.

Connect taxonomy terms in the MultilingualPress translation meta box
Connect taxonomy terms in the MultilingualPress translation meta box

Connect Custom Post Types with MultilingualPress

Connecting the custom posts is similar to connecting taxonomy terms. Go to the dasboard of site 1, select Recipes in the menu and edit one.  In the translation metabox you can choose Create a new Recipe or Select an existing Recipe. We choose Create a new Recipe. You can setup the values manually and use advanced features like Copy featured image in Advanced tab.

Connect custom post types with MultilingualPress
Connect custom post types with MultilingualPress

Now if you go to site 2 you will see a new Recipe created. Edit it and select a translated taxonomy in the Ingredients metabox:

Select an Ingredients taxonomy term in the taxonomy metabox
Select an Ingredients taxonomy term in the Ingredients taxonomy metabox

Create a menu on each site to navigate through languages

Now that we have some recipes and ingredients connected between both sites we create a menu on each site to allow the user to switch between languages. In the menu we will add MultilingualPress language items.

Create a language menu on each site to allow users to switch languages
Create a language menu on each site to allow users to switch languages and add language items to it

Setup Permalinks structure

Before we check that switching languages works, we need to ensure that our permalinks structure is configured correctly. Depending on if it is a new Multisite installation it could be that our permalink includes a /blog/ slug added by WordPress. The best approach for now is to simply get rid of this part in the permalink:

Remove /blog/ from URLs
Remove /blog/ from URLs

A quick tip for removing the /blog/ slug from the permalink is to select Plain and save. Then select Custom Structure and remove /blog/ slug there. You need to remove the /blog/ slug in both sites. Don’t forget to 301 redirect the old slugs to the new.

Visit a Custom Post page and switch language

Now that everything is setup correctly, its time to check that we can switch languages from a custom post type page. Go to site 1 and view one of the Recipes you’ve set up. Then switch languages in the menu. You should be redirected to the translated version. Do the same also for the taxonomy terms.

View a Recipes post
View a Recipes post …
... and switch the language
… and switch the language
View an ingredient...
View an ingredient…
... and switch the language
… and switch the language

That’s all you need to do regarding setting up custom post type and taxonomy translations in MultilingualPress. If you have doubts or need further assistance, just let us know.

 


Build the perfect multilingual webshop with WooCommerce and our plugins MultilingualPress and CentralStock!