It is really a big deal to manage translations of custom module in Drupal 7 expecially if you have a multisite installation.
Problem
We want use a .po file to translate a custom module programmatically, i.e. without forcing a redactor to do dangerous manual operations.
Furthermore we want have our module always accompained by its translations.
Solution
First of all we need to have l10n_update module installed.
Than we can declare the hook “l10n_update_projects_alter” which allow to set a remote path where the .po file is hosted.
Normally the path should be a remote, indipendent one, but in most cases we would like to have the .po file inside the website itself (i.e. not a separeted environment).
Take a look to the code below in which I declare a .po file that is in the module folder, in particular in “translations” subfolder.
As you can see the file name contains the parameter %language. In this case the filename would be ModuleName.LanguageCode.po.
/** * Alter the list of project to be updated by Localization Update. * * L10n_update uses the same list of projects as update module. Using this hook * the list can be altered. This hook is typically used to alter the following * values from the .info file: * - interface translation project * - l10n path. * * @param array $projects * Array of projects. */ function my_module_name_l10n_update_projects_alter(array &$projects) { // Setting module name. $name = 'my_module_name'; // Setting the path of .po files. $pathToModule = drupal_get_path('module', $name); $pathToPo = $pathToModule . '/translations/'; $poFileName = $name . '.%language.po'; // Getting url to po $urlToPoFolder = file_create_url($pathToPo); $urlToPoFile = $urlToPoFolder . $poFileName; /** * In case of S3 filesystem uncomment the code below. */ // Instead of the default ftp.drupal.org we use the file system of the test // instance to simulate a remote file location. //$wrapper = file_stream_wrapper_get_instance_by_uri('public://'); //$remote_url = $wrapper->getExternalUrl() . '/remote/'; // With this hook it is also possible to add a new project which does not // exist as a real module or theme project but is treated by the localization // update module as one. The below data is the minimum to be specified. // As in the previous example the 'l10n path' element is optional. $projects[$name] = array( 'project_type' => 'module', 'name' => $name, 'info' => array( 'name' => 'My Module name', 'interface translation project' => $name, 'version' => '7.x-1.0', 'core' => '7.x', 'l10n path' => $urlToPoFile, ), ); }
Furthermore with the following snippet, I have manually (i.e. programmatically) forced the module to update its translations.
// Getting dependencies. module_load_include('inc','l10n_update','l10n_update.translation'); module_load_include('inc','l10n_update','l10n_update.fetch'); $projects = ['my_module_name']; $options = _l10n_update_default_update_options(); $options['customized'] = true; $options['use_remote'] = true; $options['overwrite_options']['customized'] = true; l10n_update_clear_status(); $batch = l10n_update_batch_update_build($projects, [], $options); batch_set($batch);
The .po files have been extracted thanks to Translation Template Extractor.