| 1 | """ |
| 2 | Wrapper for loading templates from "template" directories in installed app packages. |
| 3 | Different from the django provided app_directories, it creates a different template |
| 4 | namespace for each application. To use the template in your_app/templates/foo.html, |
| 5 | you specify 'your_app/foo'. Only the last app label is used as the namespace. |
| 6 | |
| 7 | Mostly shamelessly copied from django's app_directories template loader. |
| 8 | """ |
| 9 | |
| 10 | from django.conf import settings |
| 11 | from django.core.exceptions import ImproperlyConfigured |
| 12 | from django.template import TemplateDoesNotExist |
| 13 | from django.utils.datastructures import MultiValueDict |
| 14 | import os |
| 15 | |
| 16 | # At compile time, cache the directories to search. |
| 17 | app_template_dirs = MultiValueDict() |
| 18 | for app in settings.INSTALLED_APPS: |
| 19 | i = app.rfind('.') |
| 20 | if i == -1: |
| 21 | m, a = app, None |
| 22 | else: |
| 23 | m, a = app[:i], app[i+1:] |
| 24 | try: |
| 25 | if a is None: |
| 26 | mod = __import__(m, '', '', []) |
| 27 | label = m |
| 28 | else: |
| 29 | mod = getattr(__import__(m, '', '', [a]), a) |
| 30 | label = a |
| 31 | except ImportError, e: |
| 32 | raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0]) |
| 33 | template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates') |
| 34 | if os.path.isdir(template_dir): |
| 35 | app_template_dirs.appendlist(label, template_dir) |
| 36 | print app_template_dirs |
| 37 | |
| 38 | def get_template_sources(template_name, template_dirs=None): |
| 39 | # find top level directory component of template_name |
| 40 | path = [] |
| 41 | head = template_name |
| 42 | while True: |
| 43 | head,tail=os.path.split(head) |
| 44 | if not tail: |
| 45 | break |
| 46 | path.insert(0,tail) |
| 47 | if len(path)<=1: |
| 48 | return |
| 49 | template_name = os.path.join(*path[1:]) |
| 50 | for template_dir in app_template_dirs.getlist(path[0]): |
| 51 | yield os.path.join(template_dir, template_name) + settings.TEMPLATE_FILE_EXTENSION |
| 52 | |
| 53 | def load_template_source(template_name, template_dirs=None): |
| 54 | for filepath in get_template_sources(template_name, template_dirs): |
| 55 | try: |
| 56 | return (open(filepath).read(), filepath) |
| 57 | except IOError: |
| 58 | print "Not found: %s" % filepath |
| 59 | raise TemplateDoesNotExist, template_name |
| 60 | load_template_source.is_usable = True |