Sprachabhängige Template-Imports

Zuerst die Erklärung, der vollständige Code folgt am Ende.

Um Internationalisierung (i18n) bzw. Übersetzung in Django-Templates zu bringen, gibt es verschiedene Möglichkeiten, allen voran die Möglichkeit, Strings mittels trans oder blocktrans zu markieren und in den entsprechenden gettext-Dateien zu übersetzen.

Das funktioniert gut und hat sich bewährt, solange es sich um Strings handelt. Möchte man eine komplette Seite übersetzen, inkl. Bildern und HTML-Code, wird es schwieriger, mal abgesehen davon, dass ich HTML in gettext-Strings einfach häßlich finde.

Eine Möglichkeit ist es, ifequal mit dem aktuellen Sprachcode des Users (LANGUAGE_CODE) zu vergleichen:

{% ifequal LANGUAGE_CODE "de" %}
    <p>Hier ganz viel deutscher Text.</p>
{% else %}
    <p>Here is a lot of english text, the default language.</p>
{% endif %}

Wird der Inhalt zu lang, kann man die Texte jeweils in eigene Templates auslagern und mittels include importieren:

{% ifequal LANGUAGE_CODE "de" %}
    {% include "vieltext_deutsch.html" %}
{% else %}
    {% include "vieltext_english.html" %}
{% endif %}

Hier setzt der unten gezeigte Templatetag an. Er arbeitet prinzipiell wie der Standard-Include-Tag aber importiert automatisch das Template mit der jeweiligen Sprache.

Der Templatename muss dabei das Format <templatename>.<languagecode> als Dateinamen besitzen. Angenommen unser User ist mit deutscher Spracheinstellung unterwegs und sein LANGUAGE_CODE wäre de, der Aufruf:

{% langinclude "meintext.html" %}

würde hier zuerst das Template meintext.html.de suchen und importierten. Schlägt dies fehl, importiert es wie gewohnt das Template meintext.html.

Hier nun der Templatetag:

from django.template import Library, Node
from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
from django.template.loader_tags import IncludeNode
from django.template.loader import get_template
from django.conf import settings

register = Library()

class ConstantLanguageIncludeNode(Node):
    def __init__(self, template_path):
        self.template_path = template_path

    def render(self, context):
        try: 
            t = get_template('%s.%s' % (self.template_path, context['LANGUAGE_CODE']))
        except TemplateDoesNotExist, KeyError:
            t = get_template(self.template_path)
        except:
            if settings.TEMPLATE_DEBUG:
                raise
            return ''
        return t.render(context)

def do_language_include(parser, token):
    """
    Looks up for a template based on the template-name plus the current users language code.
    Loads the template and renders it with the current context.

    Example::

        {% langinclude "foo/some_include.html" %}

    Based on the users LANGUAGE_CODE, assumed we have 'de', it tries to render the
    template 'foo/some_include.html.de'. If that doesn't exists, it renders the 
    template 'foo/some_include.html'. This is the default behavior of the include-Tag.

    Basically this is a shortcut for the following code, just with a fallback for the
    default template::

        {% ifequal LANGUAGE_CODE "de" %}
            {% include "foo/some_include.html.de" %}
        {% else %}
            {% include "foo/some_include.html" %}
        {% endifequal %}
    """
    bits = token.contents.split()
    if len(bits) != 2:
        raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
    path = bits[1]
    if path[0] in ('"', "'") and path[-1] == path[0]:
        return ConstantLanguageIncludeNode(path[1:-1])
    return IncludeNode(bits[1])

register.tag('langinclude', do_language_include)

Der Quellcode auf djangosnippets.org.


  • flosch Feb. 25, 2009

    Toller und nützlicher Artikel. Werd' ich auch demnächst brauchen - danke! :)


Comments closed

Sorry, new comments are no longer allowed for this entry.

Write me an email if you have feedback or any questions regarding this post. If you found this post useful and just want to say thank you then don't forget that I have an Amazon Wishlist. :-)


↑ to the elevators

© 2001—2010 Martin Mahner. This is an I ♥ Django Project.

Admin | Generated: Mon, 26 Jul 2010 05:51:34 +0200