Drupal y la traducción de formularios

Traducir formularios en Drupal

El módulo i18n (Internazionalization) de Drupal nos permite crear sitios multilingües de una manera sencilla y rápida.

Una vez instalado, nos agregará un submenú en la página de “Configuración” llamado “Regional e idioma” desde donde podremos agregar los diferentes idiomas que utilizará nuestra página. También, desde este menú, podremos instalar los paquetes de traducción de los módulos, traducir “strings”, o configurar el método con el que se obtendrán el idioma requerido según las necesidades del usuario.

Una vez configurados los idiomas, la traducción del contenido se vuelve trivial. En la página de edición de cada tipo de contenido nos aparecerán unas opciones de traducción. Seleccionamos la que más nos interese, teniendo en cuenta las implicaciones de cada una de ellas.
Y ya podemos traducir. En la página de edición de cada uno de los contenidos de tu sitio aparecerá ahora una opción “traducir” con la que de una forma sencilla y muy rápida podremos crear el contenido para los diferentes idiomas.

¿Pero, y los formularios?

Al traducir nos daremos cuenta de que básicamente se crea un nuevo nodo del mismo tipo de contenido, asociado al idioma seleccionado.

Con los formularios pasa casi lo mismo. Creará un nuevo nodo asociado al idioma, pero hemos de volver a construirlo, añadiendo las componentes y aplicando las opciones necesarias.
Si nuestra web cuenta con más de un formulario, la traducción de estos se puede volver tediosa, ya que habrá que repetir los mismos pasos tantas veces como sean necesarias hasta tener traducidos todos los formularios.

¿Como traducimos un formulario sin que se creen nuevos nodos?

Gracias a la potencia de Drupal, y sobre todo, a su escalabilidad, la solución se presenta sencilla.
Bastará con crear una sola vez el formulario, y un módulo para poder traducirlo.

Una vez creado el archivo .info del módulo, pasamos a crear el módulo en sí, la parte encargada, en nuestro caso, de traducir el formulario. El módulo se llamará “Translate form Bikuma”.

Para poder traducir un formulario debemos emplear el método “hook_form_alter”:

  function translate_form_bikuma_form_alter(&$form, &$form_state,$form_id ){ }

Nota: Los hook están asociados a un módulo en concreto, por lo que debemos sustituir la palabra hook del nombre de la función por el nombre de nuestro módulo.

Una vez creado nuestro hook, pasamos a modificar el formulario. Para traducir emplearemos la función “t()” de Drupal:

      $form['submitted']['name']['#attributes']['placeholder'] = t('Name');

Con esto logramos que el componente del formulario llamado “name” obtenga el valor devuelto por la función t(), encargada de traducir strings. Hay que tener en cuenta que todo lo que escribamos dentro de la función t() será asociado al idioma Inglés, por lo que es más que recomendable que su contenido sea en dicho idioma.

Para un formulario con los componentes nombre, email, asunto y mensaje mostrados en el “placeholder”, el botón de enviar y la confirmación de envio; debería de quedarnos una función similar a la siguiente:

  function translate_form_bikuma_form_alter(&$form, &$form_state,$form_id ){
      $form['submitted']['name']['#attributes']['placeholder'] = t('Name');
      $form['submitted']['email']['#attributes']['placeholder'] = t('Email');
      $form['submitted']['subject']['#attributes']['placeholder'] = t('Issue');
      $form['submitted']['message']['#attributes']['placeholder'] = t('Message');
      $form['actions']['submit']['#value'] = t('Send');
      $form['#node']->webform['confirmation'] = '<div id="success_page"><h4 class="highlight">'.t('Thanks you. Your message was sent.').'</h4></div> <br>';
  }

Una vez creada la función y después de vaciar cachés, podremos ver en mi_sitio_drupal/admin/config/regional/translate/translate los textos con sus diferentes idiomas y traducciones. Los nombres de los elementos del formulario aparecerán aquí y podrán añadirse la traducciones, que será lo que muestre la función t() según el idioma.

¿Y si creé el formulario en inglés?

En este caso, el formulario será más dinamico y manejable, y será perfectamente exportable esta función a otros módulos, y estos módulos, a otras instalaciones de Drupal. 

Simplemente sustituimos cada una de las sentencias

$form['submitted']['name']['#attributes']['placeholder'] = t('Name');

por una traducción de si mismas:

$form['submitted']['name']['#attributes']['placeholder'] = t($form['submitted']['name']['#attributes']['placeholder']);

Esto nos funcionará correctamente si tenemos un solo formulario en nuestro sitio web.

Pero, ¿y si hay más de uno?

Tenemos que modificar un poco esta función, y para ello existen dos vías para traducir multiples formularios. 

- Utilizando de nuevo hook_form_alter() debemos filtrar los formularios y sus acciones según el id del formulario. Nos quedará algo parecido a esto:

function translate_form_bikuma_form_alter(&$form, &$form_state,$form_id ){
      if ($form_id == 'webform_contact_form_1') {
            $form['submitted']['name']['#attributes']['placeholder'] = t($form['submitted']['name']['#attributes']['placeholder']);
            $form['submitted']['email']['#attributes']['placeholder'] = t($form['submitted']['email']['#attributes']['placeholder']);
            $form['submitted']['subject']['#attributes']['placeholder'] = t($form['submitted']['subject']['#attributes']['placeholder']);
            $form['submitted']['message']['#attributes']['placeholder'] = t($form['submitted']['message']['#attributes']['placeholder']);
            $form['actions']['submit']['#value'] = t($form['actions']['submit']['#value'] );
            $form['#node']->webform['confirmation'] = '<div id="success_page"><h4 class="highlight">'.t($form['#node']->webform['confirmation']).'</h4></div> <br>';      }      }

- Utilizando la modificación hook_form_FORM_ID_alter(). Esta función filtra según el ID del formulario, por lo que si tenemos formularios con estructuras y acciones muy concretas, tendremos una función de este tipo por cada uno de ellos (:

function translate_form_bikuma_form_webform_contact_form_1_alter(&$form, &$form_state,$form_id ){
      $form['submitted']['name']['#attributes']['placeholder'] = t($form['submitted']['name']['#attributes']['placeholder']);
      $form['submitted']['email']['#attributes']['placeholder'] = t($form['submitted']['email']['#attributes']['placeholder']);
      $form['submitted']['subject']['#attributes']['placeholder'] = t($form['submitted']['subject']['#attributes']['placeholder']);
      $form['submitted']['message']['#attributes']['placeholder'] = t($form['submitted']['message']['#attributes']['placeholder']);
      $form['actions']['submit']['#value'] = t($form['actions']['submit']['#value'] );
      $form['#node']->webform['confirmation'] = '<div id="success_page"><h4 class="highlight">'.t($form['#node']->webform['confirmation']).'</h4></div> <br>';
}

De esta manera podemos tener diferentes formularios, incluso mostrándose al mismo tiempo, y cada uno con su propia traducción.

Como hemos visto, gracias a la escalabilidad de Drupal, podemos modificar rápidamente el funcionamiento de ciertos elementos para adaptarlos a nuestras necesidades concretas, como por ejemplo, traducir multiples formularios con distintas estructuras con poco código PHP.

Necesito un sitio web en varios idiomas