Django templates: meilleure pratique pour traduire un bloc de texte avec HTML

Dans les modèles Django, comment traduire un bloc contenant du HTML? Par exemple:

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

Diviser les chaînes traduites me permet de changer le code HTML dans le modèle à tout moment, mais je suppose qu'il serait plus logique de le mettre dans une seule chaîne de traduction, comme ceci:

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

Mais alors le balisage HTML est dans la chaîne de traduction, c'est-à-dire si je voulais changer le HTML (par exemple la classe CSS pour l'ancre), je devrais retraduire la chaîne pour chaque langue.

Y a-t-il de meilleures alternatives?

30
demandé sur AndiDog 2011-01-09 18:52:55

3 réponses

À partir de les documents :

Il n'est pas possible de mélanger une variable de modèle dans une chaîne dans {%trans %}. Si vos traductions nécessitent des chaînes avec des variables (espaces réservés), utilisez {% blocktrans %} à la place.

, Puis sous blocktrans:

Pour traduire une expression de modèle-par exemple, accéder aux attributs d'objet ou utiliser des filtres de modèle-vous devez lier l'expression à une variable locale pour l'utiliser dans le bloc de traduction. Exemples:

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

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

De cette façon, vos chaînes traduites ont les espaces réservés. Dans votre cas:

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

Vous devrez générer le texte qui va dans anchor dans votre fonction de vue. Cela le maintient hors de votre chaîne traduite.

20
répondu Mike DeSimone 2011-01-09 16:15:35

Non seulement il est plus logique de mettre la phrase entière dans une chaîne de traduction, il peut être impossible pour les traducteurs d'obtenir la phrase correcte quand il est divisé en morceaux. Rappelez-vous que les différentes parties de la phrase peuvent affecter les uns les autres, avec des temps, des cas, le sexe, et ainsi de suite. Sans oublier que les autres langues se comportent différemment de l'anglais. Le mot "merci" par exemple, pourrait être différent lors d'une demande et de faire une demande, par exemple.

Toujours utiliser complétez les phrases dans vos chaînes de traduction afin que les traducteurs puissent faire une phrase correcte dans la langue cible.

Mike DeSimone fait la bonne recommandation, je ferais juste un tweak à elle:

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

Cela maintient le code HTML dans la chaîne de traduction équilibrée. Sans la balise d'ouverture dans la chaîne, il peut facilement ressembler à une erreur dans la chaîne.

11
répondu Ned Batchelder 2011-01-09 16:22:25

Je peux offrir une solution pratique pour seulement des fragments partiels qui sont constants pour n'importe quelle traduction.

Dans ce cas, vous pouvez éviter d'utiliser N'importe quel HTML ou CSS à l'intérieur de votre .fichier po lors de l'utilisation de modèle personnalisé balise , comme le:

@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 %}

Donc, dans votre .fichier po que vous avez:

It costs %(sum2)s dollars.

Mais c'est une question difficile - que faire avec des fragments partiels qui nécessitent une traduction (comme dans votre cas).

8
répondu sergzach 2013-01-17 11:00:27