Login

Dynamic Template Loader

Author:
jgeewax
Posted:
July 3, 2008
Language:
Python
Version:
.96
Tags:
template dynamic import loader
Score:
1 (after 1 ratings)

This snippet provides support for dynamically importing templates. This helps you to avoid naming collisions and other problems.

The format is as follows:

  1. module.submodule.app:template.html
  2. module.submodule.app:subfolder/template.html
  3. module.submodule.app:/subfolder/template.html

Assuming the module is located in '/var/', these would map (respectively) to:

  1. /var/module/submodule/app/templates/template.html
  2. /var/module/submodule/app/templates/subfolder/template.html
  3. /var/module/submodule/app/templates/subfolder/template.html

The colon splits the the python module from the template directory, meaning you can import from anything that has a "templates" directory. This helps me to avoid naming collisions by specifying the application I'm referring to, without having to put long paths in my extends and include tags inside other templates. It's also dynamic in that if I move a library outside the old path, it has no effect on the templates.

To get this rolling, in your settings.py file, add the following::

TEMPLATE_LOADERS = ( 'addons.template_loader.load_template_source', # <--- add this 'django.template.loaders.app_directories.load_template_source', 'django.template.loaders.filesystem.load_template_source',

'django.template.loaders.eggs.load_template_source',

)

 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
55
56
57
58
#---- addons/template_loader.py ----
"""
Wrapper for loading templates from "template" directories in arbitrary modules.
"""

import os

from django.conf import settings
from django.template import TemplateDoesNotExist
from addons import get_module_dir

def get_template_sources(template_name, template_dirs=None):
    delimiter = ':'
    
    if not delimiter in template_name: return []
    
    # Find the delimiter in the name and split by it
    i = template_name.find(delimiter)
    app, template_path = template_name[:i], template_name[i+1:]
    
    # Get the directory for the app and make sure that is indeed a directory
    app_dir = get_module_dir(app)
    parts = (app_dir, 'templates', template_path)
    
    # Normalize the path
    template_path = '/'.join(parts)
    
    # Return it as a list for iteration
    return [os.path.normpath(template_path)]

def load_template_source(template_name, template_dirs=None):
    for filepath in get_template_sources(template_name, template_dirs):
        try:
            return (open(filepath).read().decode(settings.FILE_CHARSET), filepath)
        except IOError:
            pass
    raise TemplateDoesNotExist, template_name
load_template_source.is_usable = True


#---- addons/util.py ----
import inspect
from os import path

def import_module(module_name):
    module = __import__(module_name, globals(), locals(), [], -1)    
    components =  module_name.split('.')
    for component in components[1:]:
        module = getattr(module, component)

    return module

def get_module_path(module_name):
    module = import_module(module_name)
    return inspect.getsourcefile(module)

def get_module_dir(module_name):
    return path.dirname(get_module_path(module_name))

More like this

  1. GeoDjango maps in admin TabularInlines by alanB 4 years, 4 months ago
  2. Test runner that installs 'tests' packages as apps by adrian_lc 1 year, 5 months ago
  3. Complex Form Preview by smagala 5 years, 11 months ago
  4. Django 1.2+ template loader for Jinja2 by SimonSapin 4 years, 8 months ago
  5. db_dump.py - for dumpping and loading data from database by limodou 8 years ago

Comments

Please login first before commenting.