2011-01-09 14 views
30

En las plantillas de Django, ¿cómo traduciría un bloque que contiene HTML? Por ejemplo:Plantillas de Django: práctica recomendada para traducir bloques de texto con HTML

{% trans "Please" %} 
    <a href="{% url login %}?next={{ currentUrlPath }}"> 
     {% trans "log in" %} 
    </a> 
{% trans "in order to use MyApplicationName." %} 

Dividir cadenas traducidas me permite cambiar el código HTML de la plantilla en cualquier momento, pero supongo que tendría más sentido para ponerlo en una cadena de traducción única, así:

{% url login as loginUrl %} 
{% blocktrans %} 
    Please 
    <a href="{{ loginUrl }}?next={{ currentUrlPath }}"> 
     log in 
    </a> 
    in order to use MyApplicationName. 
{% endblocktrans %} 

Pero luego el marcado HTML está en la cadena de traducción, es decir, si quería cambiar el HTML (por ejemplo, la clase CSS para el ancla), tendría que volver a traducir la cadena para cada idioma.

¿Hay mejores alternativas?

Respuesta

20

De the docs:

No es posible mezclar una variable de plantilla dentro de una cadena dentro de {% trans%}. Si sus traducciones requieren cadenas con variables (marcadores de posición), use {% blocktrans%} en su lugar.

A continuación, en blocktrans:

para traducir una expresión de plantilla - por ejemplo, el acceso a los atributos de objeto o utilizando filtros de plantilla - es necesario obligar a la expresión a una variable local para su uso dentro del bloque de traslación . Ejemplos:

{% blocktrans with article.price as amount %} 
That will cost $ {{ amount }}. 
{% endblocktrans %} 

{% blocktrans with value|filter as myvar %} 
This will have {{ myvar }} inside. 
{% endblocktrans %} 

De esta manera sus cadenas traducidas tienen los marcadores de posición. En su caso:

{% blocktrans with login_object.anchor as anchor %} 
    Please {{ anchor|safe }}log in</a> in order to use MyApplicationName. 
{% endblocktrans %} 

Usted tendrá que generar el texto que va en anchor en su función de vista. Esto lo mantiene fuera de su cadena traducida.

+0

Esa es una buena solución, gracias por esto. Usaré el ajuste de Ned Batchelder (almacenando solo los atributos en una variable). Desafortunadamente tienes razón en que la variable 'ancla 'no se puede crear fácilmente usando el lenguaje de plantilla incorporado de Django, así que tengo que hacerlo en mi opinión. – AndiDog

+4

Puede hacer esto: {% url login as anchor_url%} {% blocktrans with anchor = ''|safe %}Please {{ anchor }}log in para usar MyApplicationName. {% Endblocktrans%} –

11

No solo tiene más sentido poner toda la oración en una sola cadena de traducción, puede ser imposible para los traductores obtener la oración correcta cuando se divide en partes. Recuerde que las diferentes partes de la oración pueden afectarse entre sí, con tiempos verbales, casos, género, etc. Sin mencionar que otros lenguajes se comportan de manera diferente al inglés. La palabra "por favor", por ejemplo, podría ser diferente al hacer una solicitud y hacer una demanda, por ejemplo.

Utilice siempre oraciones completas en sus cadenas de traducción para que los traductores puedan hacer una oración correcta en el idioma de destino.

Mike DeSimone hace la recomendación de la derecha, me gustaría hacer sólo un pellizco a la misma:

{% blocktrans with login_object.anchor_attr as anchor_attr %} 
    Please <a {{ anchor_attr|safe }}>log in</a> in order to use MyApplicationName. 
{% endblocktrans %} 

Esto mantiene el HTML en la cadena de traducción equilibrada. Sin la etiqueta de apertura en la cadena, podría parecer fácilmente un error en la cadena.

+1

Pero en este caso tenemos la etiqueta' a 'en nuestro archivo .po de traducción , ¿derecho? ¿Es una forma de tener un archivo .po sin etiquetas html? Gracias. – sergzach

+0

No hay una manera simple. Si necesita marcar algunas palabras en la oración, solo el traductor puede decirle dónde están esas palabras, por lo que tendrá que marcarlas de alguna manera. Puede usar HTML o crear su propio marcado. –

8

Puedo ofrecer una solución conveniente solo para fragmentos parciales que son constantes para cualquier traducción.

En este caso puede evitar el uso de cualquier HTML o CSS dentro de su.archivo po cuando se utiliza la etiqueta nueva plantilla tales como el próximo:

@register.filter(name='safewrap') 
def safewrap(val, arg): 
    return val.format(arg) 
safewrap.is_safe = True 

... 

{% blocktrans with sum2="<a href='mysite.com/offer'>{0}</a>"|safewrap:sum %} 
    It costs {{sum2}} dollars. 
{% endblocktrans %} 

Así, en su archivo .po tiene:

It costs %(sum2)s dollars. 

Pero es una pregunta difícil - qué hacer con los fragmentos parciales que requieren traducción (como en su caso).

Cuestiones relacionadas