Features and i18n configuration management, oh my! Part 1

In my role as development team leader, I am responsible for the application architecture that allows other team members to focus on building functionality with minimum friction and rework. As such, one of my biggest tasks is to ensure that new features and configurations can be reliably deployed to the various stages: development, testing and production.

My current project is an Arabic/English application built on Drupal 7, that is deployed in multisite fashion to several partners. I use Features as a base configuration management system, and a number of extension modules to help me manage specific site components. The need to manage the configuration of multilingual components makes the task more complex, and in this series of posts I hope to describe a full recipe that's allowing our distributed team to commit code without overwriting existing settings.

Here are some of the main architectural components on the site:

  • Menus and menu links
  • Taxonomies
  • Static pages
  • Content types
  • Views
  • Rules
  • Heartbeat messages

All these components need to be shown in multiple languages, with the help of the Internationalization module and friends.

UI translations and default site language

Although our application can be delivered in multiple languages, we do all our development on the English UI. When we switched the default language to Arabic, we found that all our menus, taxonomies, and field translations were no longer showing. And for good reason: Drupal does not store the source language of strings in its database, so i18n has to guess the source language - and by default, it considers the site's default language to be the source. Fortunately, you can explicitly specify the source language via the variable i18n_string_source_language. We decided to hard-code the value of this variable in settings.php like so:

// settings.php

// Hardcode i18n_string_source_language to prevent nasty surprises.
$conf['i18n_string_source_language'] = 'en';

// Load per-site configurations.
require 'settings.local.php';

The last line is just a directive that allows us to version-control settings.php for global configurations and loads settings.local.php for instance-specific settings such as database connection.

UI translations and Features

Because we're deploying across 3 stages, with several instances at each stage, we cannot afford to manually import .po files each time we create or modify a translation. In order to keep the UI translation workflow sane, we designated a specific stage as the recipient of all translation work, allowing the configuration manager (yours truly) to solve the problem of automating the deployment of these translations to other stages and instances. To this end, I wrote a Features plugin called Features Translations that persists the selected translations within a feature, as shown in the screenshot below:

Translations in the Features UI

A file called feature_name.features.translations.inc gets exported to the feature, looking like this:

/**
 * @file
 * checkdesk_core_feature.features.translations.inc
 */

/**
 * Implements hook_translations_defaults().
 */
function checkdesk_core_feature_translations_defaults() {
  $translations = array();
  $translations['ar:default'][] = array(
    'source' => 'The optional description of the taxonomy vocabulary.',
    'context' => '',
    'location' => '',
    'translation' => 'الوصف الاختياري لمعجم الوسوم.',
    'plid' => '0',
    'plural' => '0',
  );
  $translations['ar:default'][] = array(
    'source' => 'You are not authorized to access this page.',
    'context' => '',
    'location' => '',
    'translation' => 'غير مسموح لك بالوصول إلى هذه الصفحة.',
    'plid' => '0',
    'plural' => '0',
  );
  $translations['ar:default'][] = array(
    'source' => 'Function',
    'context' => '',
    'location' => '',
    'translation' => 'الوظيفة',
    'plid' => '0',
    'plural' => '0',
  );
  [...]
  return $translations;
}

Next up

In the next part, I'll discuss our handling of multilingual menu items, which took a considerable amount of effort and patches to Features and i18n!

AttachmentSize
features_translations.png69.53 KB

Comments

Menus have multilingual options associated with them (Translate and Localize, Fixed). Where is this stored in the feature?

I haven't tackled multilingual menus in this post, only multilingual menu items. I might write about menus in an upcoming post.

I didn't known about i18n_string_source_language and suffered many headaches because of my ignorance. Thank you for showing me the light :D