web/lib/django/template/loaders/app_directories.py
author ymh <ymh.work@gmail.com>
Thu, 05 Aug 2010 17:28:09 +0200
changeset 50 012451a812f1
parent 38 77b6da96e6f1
permissions -rw-r--r--
Merge with a2711e44ba5de8b1675d7e0ee6aaa4a6c56a9b46
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
"""
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
Wrapper for loading templates from "templates" directories in INSTALLED_APPS
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
packages.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
"""
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
import os
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
import sys
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
from django.conf import settings
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
from django.core.exceptions import ImproperlyConfigured
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
from django.template import TemplateDoesNotExist
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
from django.template.loader import BaseLoader
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
from django.utils._os import safe_join
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
from django.utils.importlib import import_module
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
# At compile time, cache the directories to search.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
app_template_dirs = []
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
for app in settings.INSTALLED_APPS:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
        mod = import_module(app)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    except ImportError, e:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
        raise ImproperlyConfigured('ImportError %s: %s' % (app, e.args[0]))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    if os.path.isdir(template_dir):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
        app_template_dirs.append(template_dir.decode(fs_encoding))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
# It won't change, so convert it to a tuple to save memory.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
app_template_dirs = tuple(app_template_dirs)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
class Loader(BaseLoader):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
    is_usable = True
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
    def get_template_sources(self, template_name, template_dirs=None):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        Returns the absolute paths to "template_name", when appended to each
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
        directory in "template_dirs". Any paths that don't lie inside one of the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
        template dirs are excluded from the result set, for security reasons.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        if not template_dirs:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
            template_dirs = app_template_dirs
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
        for template_dir in template_dirs:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
            try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
                yield safe_join(template_dir, template_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
            except UnicodeDecodeError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
                # The template dir name was a bytestring that wasn't valid UTF-8.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
                raise
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
            except ValueError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
                # The joined path was located outside of template_dir.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
                pass
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
    def load_template_source(self, template_name, template_dirs=None):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        for filepath in self.get_template_sources(template_name, template_dirs):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
            try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
                file = open(filepath)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
                try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
                    return (file.read().decode(settings.FILE_CHARSET), filepath)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
                finally:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
                    file.close()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
            except IOError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
                pass
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
        raise TemplateDoesNotExist(template_name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
_loader = Loader()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
def load_template_source(template_name, template_dirs=None):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
    # For backwards compatibility
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
    import warnings
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
    warnings.warn(
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        "'django.template.loaders.app_directories.load_template_source' is deprecated; use 'django.template.loaders.app_directories.Loader' instead.",
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        PendingDeprecationWarning
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
    )
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    return _loader.load_template_source(template_name, template_dirs)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
load_template_source.is_usable = True