Language-aware template inclusion

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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)

More like this

  1. Repeat blocks with new context / simple Jinja-like macro system by miracle2k 4 years, 6 months ago
  2. Language aware template loader by rmt 2 years, 10 months ago
  3. Active class for navigation link by cschand 2 years, 4 months ago
  4. YUI Loader as Django middleware by akaihola 3 years, 9 months ago
  5. Silently-failing include tag by brutasse 1 year, 8 months ago

Comments

justinlilly (on February 25, 2009):

I like this, but it kills file-type detection on most editors.

What would something like mytemplate_de.html w/ failover to mytemplate.html look like? Probably have to mess with template_loaders, right?

#

bartTC (on February 25, 2009):

Justin, I was aware of this but a template name like "mytemplate_de.html" means, that you must use .html as the extension. Or it must replace the language before the last dot ... but what is, if there is no dot?

In most editors it is just one shortcut to set highlighting to html but feel free to extend it. ;)

#

sasha (on February 26, 2009):

if there is no dot:

s = self.template_path.split('.')
s.insert(-1,'_%s'%context['LANGUAGE_CODE'])
t = get_template('.'.join(s))

#

sasha (on February 26, 2009):

Sorry...

s.insert(1,'_%s'%context['LANGUAGE_CODE'])

#

KempPaulette21 (on December 21, 2011):

I guess that to get the mortgage loans from banks you must have a great reason. However, one time I've got a auto loan, because I was willing to buy a bike.

#

(Forgotten your password?)