HTML dentro de las funciones de traducción __() o _e()

15 sept 2013, 06:19:01
Vistas: 50.5K
Votos: 29

¿Cuál es el enfoque adecuado para construir cadenas de traducción?

Por ejemplo,

echo __( 'Hola ' . $first . ' me debes dinero.' );
echo __( '<div><p>Arriba: ' . $t_margin . '</p>' . '<p>Abajo: ' . $b_margin . '</p></div>' )

¿Está bien añadir las cadenas y/o HTML o debería hacerse primero y luego pasarlo por la traducción como:

$html = '<div><p>Arriba: ' . $t_margin . '</p>' . '<p>Abajo: ' . $b_margin . '</p></div>';
echo __( $html ); 
0
Todas las respuestas a la pregunta 2
5
49

Existe un segundo argumento en la función __(). Debe establecerse como el dominio que estás utilizando para tu plugin o tema. En los ejemplos siguientes uso 'text_domain'. Tu cadena de dominio debe ser única. No debe coincidir con ninguna otra cadena de dominio. No usar un argumento de dominio de texto por defecto se establece como 'default', el nombre de dominio de WordPress. Consulta el enlace para más detalles.

Siempre usa la cadena ('text_domain'). Nunca uses una variable, función o constante con la cadena dentro. La mayoría (¿todos?) los programas de traducción no lo verán sin la cadena allí.

Tu código:

echo __( 'Hola ' . $first . ' me debes dinero.' );

No incluyas variables dentro de la cadena.

Una mejor forma:

echo sprintf( __( 'Hola %s me debes dinero.', 'text_domain' ), $first );

O simplemente:

printf( __( 'Hola %s me debes dinero.', 'text_domain' ), $first );

El marcador de posición %s le indica al traductor humano que allí irá una cadena. Usa %d para números. También hay otros marcadores de posición.

(Esta oración está gramaticalmente incorrecta en inglés. Usa 'Hola %s, me debes dinero.' o 'Hola %s, posees mi dinero.' dependiendo del significado que intentabas.)


Tu código:

$html = '<div><p>Superior: ' . $t_margin . '</p>' . <p>Inferior: ' . $b_margin . '</p></div>';

No traduzcas HTML. Es el mismo en cualquier idioma.

Una mejor forma:

$html = sprintf( '<div><p>%s</p><p>%s</p></div>', __( 'Superior: ', 'text_domain' ) .  $t_margin, __( 'Inferior: ', 'text_domain' ) . $b_margin );

O divídelo en múltiples líneas:

$html = sprintf(
    '<div><p>%s</p><p>%s</p></div>',
    __( 'Superior: ', 'text_domain' ) .  $t_margin,
    __( 'Inferior: ', 'text_domain' ) . $b_margin
);

Si no es claro qué son Superior e Inferior, podrías usar _x() para explicar el contexto de estos términos.


Puedes encontrar otros casos de traducción aquí: Internacionalización: Probablemente lo estás haciendo mal

15 sept 2013 07:09:45
Comentarios

Dices que no traduzcas HTML. Podría señalar que no se está traduciendo, se está buscando en una/s tabla/s existente/s de cadenas previamente traducidas. Tener HTML en la cadena no hace diferencia siempre y cuando el traductor no los elimine. De hecho, en algunas situaciones resulta en mejor rendimiento que búsqueda y reemplazo con regex.

Twifty Twifty
15 sept 2013 10:12:32

No relacionado, pero vale la pena mencionar: el textdomain debe ser una cadena literal, no puede ser una variable/constante/propiedad.

brasofilo brasofilo
15 sept 2013 13:33:22

@brasofilo, ese consejo está escrito en la respuesta cerca de la parte superior, pero vale la pena repetirlo. Cometí este error en varios plugins personalizados que escribí para clientes.

Charles Clarkson Charles Clarkson
15 sept 2013 14:27:57

+1 para sprintf(). Es realmente la solución para evitar tener HTML en la cadena traducible.

helgatheviking helgatheviking
15 sept 2013 14:31:21

No veo cómo el uso de sprintf() ayuda de alguna manera, excepto quizás por una apariencia más limpia. Si tienes una oración con HTML dentro como Algo de texto con una palabra <strong>fuerte</strong> dentro. ¿cómo es posible traducir la oración como un todo y no traducir Algo de texto con una, fuerte y palabra dentro individualmente (lo cual no tiene sentido).

phpheini phpheini
3 jun 2017 19:56:21
2

No abordaré el tema de las variables en la cadena ya que ya se ha mencionado.

Quieres mantener tu cadena estática, lo que significa que el contenido no cambiará. También quieres evitar HTML innecesario.

__( '<p>¡Hola Mundo!</p>' );
__( '<h1>¡Hola Mundo!</h1>' );

Lo anterior ocupará dos filas en tu tabla para lo que esencialmente es el mismo texto. Se pueden reescribir como:

'<p>' . __( '¡Hola Mundo!' ) . '</p>'
'<h1>' . __( '¡Hola Mundo!' ) . '</h1>'

Reduciéndolo a una sola fila.

A veces el HTML en el texto es inevitable. Tomemos como ejemplo:

__( 'Actualmente debes <b>%s</b> dólares' );

Dado que los idiomas son gramaticales, dividir el texto causaría problemas para quien esté traduciendo.

Regla general. Las etiquetas HTML de formato en medio de una oración están bien. Las oraciones que comienzan y terminan con HTML solo ocupan espacio innecesario.

15 sept 2013 10:43:58
Comentarios

En el último ejemplo, podrías envolver las etiquetas de negrita alrededor del argumento que se inserta "<b>$string</b>". Luego puedes usar 'Actualmente debes %s dólares'. Pero podría necesitar permanecer si lo usas con la función _n() que requiere un marcador de posición %d.

Charles Clarkson Charles Clarkson
15 sept 2013 14:36:15

@CharlesClarkson Buen punto. Tal vez debería haber omitido el %s para que fuera un poco más claro.

Twifty Twifty
15 sept 2013 14:52:55