app/django/template/loaders/filesystem.py
author Sverre Rabbelier <srabbelier@gmail.com>
Sat, 06 Dec 2008 14:23:53 +0000
changeset 679 77a286ff6667
parent 323 ff1a9aa48cfd
permissions -rw-r--r--
Introduce dynamic scope_path regexps Instead of relying on scope_path's being "one slash deep", we should instead allow for either: 1. scope_paths that have a pre-defined depth 2. scope_paths that can be arbitrarily deep We achieve 1 by setting an entities scope_logic to another logic module. We then recursively call getScopeDepth until we get to the topmost entity (that is, an unscoped entity). A little different is the solution to 2, since some entities can have an arbitrarily deep scope (such as Documents), we need to have some way of signaling this to getScopePattern. A clean solution is to return None, rather than a number. If None is returned, the SCOPE_PATH_ARG_PATTERN is returned as regexp instead, which will match an arbitrarily deeply nested scope. The solution for 2 requires that we return None somewhere in the scope_logic chain, the most straight forward method to do so is to override getScopeDepth anywhere such a scope is needed and make it return None. A more elegant solution however, is to set the scope_logic to that module in all entities that require it. Patch by: Sverre Rabbelier

"""
Wrapper for loading templates from the filesystem.
"""

from django.conf import settings
from django.template import TemplateDoesNotExist
from django.utils._os import safe_join

def get_template_sources(template_name, template_dirs=None):
    """
    Returns the absolute paths to "template_name", when appended to each
    directory in "template_dirs". Any paths that don't lie inside one of the
    template dirs are excluded from the result set, for security reasons.
    """
    if not template_dirs:
        template_dirs = settings.TEMPLATE_DIRS
    for template_dir in template_dirs:
        try:
            yield safe_join(template_dir, template_name)
        except UnicodeDecodeError:
            # The template dir name was a bytestring that wasn't valid UTF-8.
            raise
        except ValueError:
            # The joined path was located outside of this particular
            # template_dir (it might be inside another one, so this isn't
            # fatal).
            pass

def load_template_source(template_name, template_dirs=None):
    tried = []
    for filepath in get_template_sources(template_name, template_dirs):
        try:
            return (open(filepath).read().decode(settings.FILE_CHARSET), filepath)
        except IOError:
            tried.append(filepath)
    if tried:
        error_msg = "Tried %s" % tried
    else:
        error_msg = "Your TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory."
    raise TemplateDoesNotExist, error_msg
load_template_source.is_usable = True