I have a custom module I've built which essentially acts as a repository of custom CTools keywords that users can arbitrarily define. The issue I'm facing is I need to be able to translate these user-defined strings, so I think I need to implement string translation using the i18n_string module.

I have never worked with translation or localization before, so I'm a bit lost with regards to going about how to implement this. I think I'm on the right path with i18n_string though. Can someone experienced with i18n provide examples that I can look at so I can learn the proper way to implement this?

  • Do you need this process to be automated or are you going to translate yourself the keywords through your admin interface?
    – Djouuuuh
    Jul 31, 2014 at 14:40
  • So I want to set up an automated way to translate all the current values of the keywords. So if some site maintainer alters a keyword, they just go to the translate interface, select the module, and say "translate keywords" or something to that effect. Jul 31, 2014 at 14:50
  • Mmmh I'm not sure but I'm afraid the modules that can be translated through i18n have been translated manually and their translation can be downloaded by i18n. I think that way because there are some modules for which there is no translation available... Don't you think?
    – Djouuuuh
    Jul 31, 2014 at 14:53
  • That doesn't really make any sense to me. User defined strings are regularly translated in fields, views, etc... So that means there is a way to tap into that process. That's what I'm looking to do here. Jul 31, 2014 at 14:55
  • 1
    My understanding is you can't wrap variables with t()? Jul 31, 2014 at 20:04

1 Answer 1


Exactly, you can't wrap variables with t(). They will get printed, but they won't be translatable. I had a form that saves a user-defined string and wanted that string to be translatable from Drupal's translation interface.

Messed around quite a while with i18n_string() and its attribute $name (a $textgroup and a $context glued together with :).

Finally got it: You can provide your own $textgroup via hook_i18n_string_info() and later provide any other custom string as $context (maybe take your module's name to keep things clean).

If you have more than one string in your module pay attention to have every single one of them glued with another custom string to the prior context (textgroup:context:string_1, textgroup:context:string_2, ...).

Here comes a working example:

 * Implements hook_i18n_string_info().
 *   This is the most interesting thing here. You create a new
 *   textgroup your strings will be identified with. Here it's
 *   simply: Custom modules.
 *   When you set the i18n-string later you then only add another
 *   string as context like 'custommodules:any_other_string'.
 *   See the markup example in the form below.
function MYMODULE_i18n_string_info() {

  $groups['custommodules'] = array(
    'title' => t('Custom modules'),
    'format' => FALSE,
    'list' => TRUE,

  return $groups;

 * Example form.
function form_example() {

  // Just for testing, the first form element prints the translated
  // string, so you simply can test it after translation by switching
  // your page's language and see it working. This also demonstrates how
  // you will print the string everywhere else.
  $form['markup'] = array(
    '#markup' => i18n_string('custommodules:MYMODULE:string_1', variable_get('user_defined_string', 'Bempo Kohm'), array('update' => TRUE)),

  $form['string'] = array(
    '#type' => 'textfield',
    '#title' => t('A beautiful and pure string'),
    '#default_value' => variable_get('user_defined_string', 'Bempo Kohm'),

  $form['button'] = array(
    '#type' => 'submit',
    '#value' => t('Action'),

  return $form;

 * Example form submit handler.
function form_example_submit($form, &$form_state) {

  variable_set('user_defined_string', $form_state['values']['string']);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.