Reputation: 12198
What to do with HTML in translations? I want to translate sentences with HTML in them. For example such a string ([login]
is a link):
Please [login] to view your profile.
I do not want to bother my translators with translating text with html intertwined. On the other hand, I do not want to bother with creating all the links in my views, like suggested in this question. So ideally I want a template-only solution to have the flexibility of crafting HTML, while allowing translators to only work with text strings.
For example, this pseudocode implements these requirements:
{% render as login_html %}
<a href="{{ url 'login' }}?next={{ request.path|urlencode }}">
{% trans "Login" %}
</a>
{% endrender %}
{% blocktrans with login=login_html %}
Please {{ login }} to view your profile.
{% endblocktrans %}
First, the login HTML is rendered and stored as login_url
. Then in my blocktrans, I can simply use {{ login }}
to give the rendered login HTML. Is there a (similar) solution to this problem, or would it require custom template tags?
Upvotes: 4
Views: 1544
Reputation: 12198
I've created a generic render
tag to do just that:
from classytags.arguments import Argument, Flag
from classytags.core import Options
from classytags.helpers import AsTag
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
class Render(AsTag):
"""
Renders the block contents to be used elsewhere in the template.
Example usage:
{% render as login_url %}
<a href="{% url 'login' %}">{% trans "Login" %}</a>
{% endrender %}
{% blocktrans %}
Please {{ login_url }} for more information.
{% endblocktrans %}
It will automatically strip leading and trailing whitespace, use `nowrap`
to disable this behaviour:
{% render nostrip as varname %} . . . {% endrender %}
"""
options = Options(
Flag('strip', default=True, false_values=['nostrip']),
'as',
Argument('varname', resolve=False, required=True),
blocks=[('endrender', 'nodelist')],
)
def get_value(self, context, nodelist, strip, **kwargs):
value = nodelist.render(context)
if strip:
value = value.strip()
return mark_safe(value)
register.tag(Render)
When used with translation contexts (e.g. {% trans "Login" context "login_url" %}
), the translator will have great control over the translation while still not being bothered with HTML.
msgctxt "login_url"
msgid "Login"
msgstr ""
#, python-format
msgid "Please %(login_url)s for more information."
msgstr ""
Upvotes: 2