Translating Commerce Kickstart 2

This is a follow-up on Translating a Commerce Store guide available in Commerce Kickstart 2 documentation.

This is a follow-up on Translating a Commerce Store guide available in Commerce Kickstart 2 documentation.

Note this is not a complete solution in itself, although combined with the guide linked above it gives pretty complete picture of what needs to be done to have working multilingual Commerce Kickstart store.

Site

Commerce Kickstart 2

Install Commerce Kickstart 2 with Localization enabled (select Yes when installer asks you if you want to be able to translate the interface of your store on the Configure store step).

Localization update

Before enabling any additional languages, download and enable Localization update module. It will take care of downloading interface translations for all enabled modules.

drush dl l10n_update
drush en -y l10n_update

Add required languages

Go to Administration » Site settings » Advanced settings » Configuration » Regional and language » Languages (or just admin/config/regional/language) and add new language(s). Interface translations should be downloaded automatically by Localization update module.

Products

Entity Translation

Download and enable Entity Translation module.

drush dl entity_translation
drush en -y entity_translation

To configure it, to to Administration » Site settings » Advanced settings » Configuration » Regional and language » Entity translation (admin/config/regional/entity_translation) and select which entities should be translated.

In Translatable entity types select Node. Optionally you could select Commerce Product as well, if you have added additional fields to commerce_product entity types which you want to be translatable and searchable, but this is going to be slightly more tricky.

You might want to configure Default language and other options below for each selected entity type before saving the form.

Enable multilingual support for product displays

Go to Administration » Content » Settings » Content types (admin/structure/types), edit each content type you want to be translatable (in case of Kickstart's example store these will be Bags & CasesDrinksHatsShoesStorage Devices and Tops) and set Multilingual support to Enabled, with field translation_ (in Publishing options fieldset).

Enable translation for all required fields

In Kickstart 2, translation will be enabled by default for title_field only. You might want to enable it also for Body field, and any other field that should be translatable.

To do this, edit such a field on any content type (for example, on Bags & Cases content type from the example store, it will be in Administration » Content Settings » Content types » Bags & Cases » Manage fields » Body (admin/structure/types/manage/bags-cases/fields/body)) and click Enable translation link at the bottom of the page. This will enable translation of this field for all content types the field is used on.

Repeat for all other fields that should be translatable.

Translate product displays

Go to Administration » Products » Actions » Manage products (admin/commerce/products) and edit a product you want to translate. Use "full" Edit from the button drop down, as the Quick Edit will not give you required options.

You will notice that Translate tab is not available yet. To make it appear first you need to change product display's language from Language neutral to a real language. After doing that you will see a new Translate link in the button drop down, as well as new Translate tab on the top of product display edit page.

Use it and add a new translation for language(s) added before.

Optional: Enabling multilingual support for commerce_product entities

This part is a bit tricky. Also, before doing it, make sure that you really need it.

As explained in How to translate Drupal Commerce products, with Commerce Backoffice module enabled standard Drupal paths are messed up, the same applies to product type edit forms, and it's impossible (or, at least, difficult to do) to enable multilingual support for product types.

Let's start with disabling the Commerce Backoffice Product module:

drush dis -y commerce_backoffice_product

Now you can access Manage products page at Administration » Products » Actions » Manage products » Product types (admin/commerce/products/types).

Edit each product type you want to be translatable and change Multilingual support to Enabled via Entity translation.

After you have done it for all required product types, you can re-enable Commerce Backoffice Product module.

Product search

Products search index and view

Standard Kickstart's All Products product listing (/products) is based on Display products view (admin/structure/views/view/display_products), built on top of Product display Search API index (admin/config/search/search_api/index/product_display). None of them however is able to handle multilingual entities out of the box.

First, to add multilingual features to Search API, you will need Search API Entity Translation module (version 2.x):

drush dl search_api_et
drush en -y search_api_et

After enabling it you will have a set of new multilingual item types available on Add index page (admin/config/search/search_api/add_index), including Multilingual node, which might be used to create a multilingual index of product displays, replicating functionality of Kickstart's Product display index.

This, as well, as adding new multilingual version of Display products view might be done manually, followed by disabling old index/view and replacing them with the new, multilingual ones, but... there is an easier way.

Commerce Search API Entity Translation to the rescue!

The purpose of this module is to take the whole burden of adding multilingual support to existing product listings/search off your shoulders and do this automatically for you. Just download and enable it:

drush dl commerce_search_api_et
drush en -y commerce_search_api_et

and it will create for you:

  • new Multilingual product display search index (admin/config/search/search_api/index/multilingual_product_display - remember to index all its items, either from UI, or using drush sapi-i <index_id>), with its configuration (fields, facets and sorts) copied over from Kickstart's standard Product display index

  • new Display Multilingual Products view (admin/structure/views/view/display_products_multilingual) created from Kickstart's default Display Products view, but based on the new multilingual search index, with old view getting disabled, and the new one using the same path to seamlessly replace the old one on the site.

At the time of writing this post, as mentioned on the module page, even though this module provides default facet configuration, relevant blocks are not created automatically yet.

For the moment, to have them appear, you need to go to Multilingual product display index's Facets page (admin/config/search/search_api/index/multilingual_product_display/facets) and just save the form (no need to make any changes - unless you want to make some). This will create the blocks in the database, after which either they will need to be manually configured on the Blocks admin page, or the whole code from commerce_search_api_et_install() run in devel/php

Also, you'd need to manually move the Exposed form: display_products_multilingual-page block to the Branding section.

Re-index!

Whichever way you choose to create new multilingual search index, do not forget to index all the items. You can do it either through the UI, or using drush:

# Check our multilingual index id:
drush sapi-s
# Most probably the id will be 3.
# Let's index all the items:
drush sapi-i 3

Sorting out duplicate search results / incorrect facet counts

For multilingual search indexes, the number of items created in the index for each entity is the same as the number of languages the entity is available in.

Which means that if you search for a word appearing in all language versions of the same entity, it might get returned multiple times - which would be incorrect.

To avoid this, as well as incorrect counts in search facets, the Search API Entity Translation Database Search module was developed (assuming that you are using Search API Database Search module as the Search API backend, which Kickstart does by default).

Just install and enable the module:

drush dl search_api_et_db
drush en -y search_api_et_db

and both the search results as well as facet counts should be fine again.

This will also help with PHP Notice: Undefined index: (...) in search_api_ranges_minmax() coming from Search API Ranges module.

Indexing additional fields

Kickstart 2's default Product display search, and therefore new Multilingual product display index as well, are configured to work with title_field (amongst others), but they don't search the body field (nor any other custom fields) out of the box. You might want however to add other fields which should be searchable.

For example, to add the body field to the index, go to Administration » Site settings » Advanced settings » Configuration » Search and metadata » Search API » Multilingual product display » Fields (admin/config/search/search_api/index/multilingual_product_display/fields), expand Add related fields fieldset on the bottom of the page, and add The main body text field. Select the checkbox next to The main body text » Text (body:value), change the Boost if needed, and Save changes.

After doing this for all required fields, you will need to re-index all the data again.

Taxonomies

Taxonomy vocabularies

Note that this section relates to translating vocabularies, not taxonomy terms!

Enable Taxonomy translation module (i18n_taxonomy), part of Internationalization module suite (i18n), already included in Kickstart 2:

drush en -y i18n_taxonomy

Edit each vocabulary that should be translatable and select required Translation mode in Multilingual options.

For localizable elements, to have all items available for translation you should visit the translation refresh page (Administration » Site settings » Advanced settings » Configuration » Regional and language » Translate interface » Stringsadmin/config/regional/translate/i18n_string).

Taxonomy terms

This assumes you have already downloaded and enabled Entity Translation module mentioned at the beginning of this post.

Go to Administration » Site settings » Advanced settings » Configuration » Regional and language » Entity translation (admin/config/regional/entity_translation) and check Taxonomy term in Translatable entity types.

Go to Manage fields for each vocabulary which you want to be translatable (for example in case of Kickstart 2's Category vocabulary it will be Administration » Site settings » Advanced settings » Structure » Taxonomy » Category » Manage fieldsadmin/structure/taxonomy/category/fields), and replace name and description pseudofields with real field instances (only then their values could be translated).

By default, only Plain text text formats are translatable. If you want to translate fields in any other format, first go to Administration » Site settings » Advanced settings » Configuration » Regional and language » Multilingual settings » Strings (admin/config/regional/i18n/strings) and enable required text formats.

Don't forget about refreshing strings after doing that - go to Administration » Site settings » Advanced settings » Configuration » Regional and language » Translate interface » Strings (admin/config/regional/translate/i18n_string), select text groups to refresh, and refresh them.

Few gotchas

Commerce Search API

If you want to use either Product Display filter or Exclude unpublished products filter provided by Commerce Search API module you would need to make sure that the patch from Use proper entity type check in data alteration classes issue is either already applied to the module, or apply it yourself.

Otherwise these two filters will not be available on multilingual indexes created with the help of Search API Entity Translation module.

Search API Ranges

If you are planning on using the Search API ranges module, make sure you apply patch from Not working in combination with entity translation issue - otherwise you will get a fatal error when trying to display the facet.