diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2005-10-14 20:10:13 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2005-10-14 20:10:13 +0000 |
| commit | f71f8546283dbdf698c7578f8f9154045c84f9e7 (patch) | |
| tree | 1ae0aa237970d1b67ec8504d9f3f425305b3e155 /django | |
| parent | b773bf45c3011dc95617dcbec9584c8d139c27cc (diff) | |
Fixed #626 -- Moved template modules to django.core.template package. django.core.template_loader is deprecated, in favor of django.core.template.loader.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@867 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/extensions.py | 5 | ||||
| -rw-r--r-- | django/core/rss.py | 13 | ||||
| -rw-r--r-- | django/core/template/__init__.py (renamed from django/core/template.py) | 0 | ||||
| -rw-r--r-- | django/core/template/defaultfilters.py (renamed from django/core/defaultfilters.py) | 104 | ||||
| -rw-r--r-- | django/core/template/defaulttags.py (renamed from django/core/defaulttags.py) | 165 | ||||
| -rw-r--r-- | django/core/template/loader.py | 163 | ||||
| -rw-r--r-- | django/core/template/loaders/__init__.py | 0 | ||||
| -rw-r--r-- | django/core/template/loaders/filesystem.py (renamed from django/core/template_file.py) | 2 | ||||
| -rw-r--r-- | django/core/template_loader.py | 167 | ||||
| -rw-r--r-- | django/middleware/admin.py | 10 | ||||
| -rw-r--r-- | django/views/admin/doc.py | 3 | ||||
| -rw-r--r-- | django/views/admin/template.py | 9 | ||||
| -rw-r--r-- | django/views/auth/login.py | 2 | ||||
| -rw-r--r-- | django/views/defaults.py | 7 | ||||
| -rw-r--r-- | django/views/registration/passwords.py | 5 |
15 files changed, 331 insertions, 324 deletions
diff --git a/django/core/extensions.py b/django/core/extensions.py index 6909ace33d..a7eaf3b06f 100644 --- a/django/core/extensions.py +++ b/django/core/extensions.py @@ -2,14 +2,13 @@ # of MVC. In other words, these functions/classes introduce controlled coupling # for convenience's sake. -from django.core import template_loader from django.core.exceptions import Http404, ObjectDoesNotExist -from django.core.template import Context +from django.core.template import Context, loader from django.conf.settings import DEBUG, INTERNAL_IPS from django.utils.httpwrappers import HttpResponse def render_to_response(*args, **kwargs): - return HttpResponse(template_loader.render_to_string(*args, **kwargs)) + return HttpResponse(loader.render_to_string(*args, **kwargs)) load_and_render = render_to_response # For backwards compatibility. def get_object_or_404(mod, **kwargs): diff --git a/django/core/rss.py b/django/core/rss.py index cd2bcf4ad1..7563d2ea82 100644 --- a/django/core/rss.py +++ b/django/core/rss.py @@ -1,6 +1,5 @@ -from django.core import template_loader from django.core.exceptions import ObjectDoesNotExist -from django.core.template import Context +from django.core.template import Context, loader from django.models.core import sites from django.utils import feedgenerator from django.conf.settings import LANGUAGE_CODE, SETTINGS_MODULE @@ -28,7 +27,7 @@ class FeedConfiguration: get_list_kwargs_cb -- Function that takes the param and returns a dictionary to use in addition to get_list_kwargs (if applicable). - + get_pubdate_cb -- Function that takes the object and returns a datetime to use as the publication date in the feed. @@ -49,7 +48,7 @@ class FeedConfiguration: self.enc_url = enc_url self.enc_length = enc_length self.enc_mime_type = enc_mime_type - + def get_feed(self, param_slug=None): """ Returns a utils.feedgenerator.DefaultRssFeed object, fully populated, @@ -64,8 +63,8 @@ class FeedConfiguration: param = None current_site = sites.get_current() f = self._get_feed_generator_object(param) - title_template = template_loader.get_template('rss/%s_title' % self.slug) - description_template = template_loader.get_template('rss/%s_description' % self.slug) + title_template = loader.get_template('rss/%s_title' % self.slug) + description_template = loader.get_template('rss/%s_description' % self.slug) kwargs = self.get_list_kwargs.copy() if param and self.get_list_kwargs_cb: kwargs.update(self.get_list_kwargs_cb(param)) @@ -102,7 +101,7 @@ class FeedConfiguration: pubdate = self.get_pubdate_cb and self.get_pubdate_cb(obj) or None, ) return f - + def _get_feed_generator_object(self, param): current_site = sites.get_current() link = self.link_cb(param).decode() diff --git a/django/core/template.py b/django/core/template/__init__.py index 71a8e621c8..71a8e621c8 100644 --- a/django/core/template.py +++ b/django/core/template/__init__.py diff --git a/django/core/defaultfilters.py b/django/core/template/defaultfilters.py index b9e0e67745..9ef367ee52 100644 --- a/django/core/defaultfilters.py +++ b/django/core/template/defaultfilters.py @@ -1,6 +1,7 @@ "Default variable filters" -import template, re +from django.core.template import register_filter, resolve_variable +import re import random as random_module ################### @@ -196,7 +197,7 @@ def dictsort(value, arg): Takes a list of dicts, returns that list sorted by the property given in the argument. """ - decorated = [(template.resolve_variable('var.' + arg, {'var' : item}), item) for item in value] + decorated = [(resolve_variable('var.' + arg, {'var' : item}), item) for item in value] decorated.sort() return [item[1] for item in decorated] @@ -205,7 +206,7 @@ def dictsortreversed(value, arg): Takes a list of dicts, returns that list sorted in reverse order by the property given in the argument. """ - decorated = [(template.resolve_variable('var.' + arg, {'var' : item}), item) for item in value] + decorated = [(resolve_variable('var.' + arg, {'var' : item}), item) for item in value] decorated.sort() decorated.reverse() return [item[1] for item in decorated] @@ -414,52 +415,51 @@ def pprint(value, _): from pprint import pformat return pformat(value) -# Syntax: template.register_filter(name of filter, callback, has_argument) -template.register_filter('add', add, True) -template.register_filter('addslashes', addslashes, False) -template.register_filter('capfirst', capfirst, False) -template.register_filter('center', center, True) -template.register_filter('cut', cut, True) -template.register_filter('date', date, True) -template.register_filter('default', default, True) -template.register_filter('default_if_none', default_if_none, True) -template.register_filter('dictsort', dictsort, True) -template.register_filter('dictsortreversed', dictsortreversed, True) -template.register_filter('divisibleby', divisibleby, True) -template.register_filter('escape', escape, False) -template.register_filter('filesizeformat', filesizeformat, False) -template.register_filter('first', first, False) -template.register_filter('fix_ampersands', fix_ampersands, False) -template.register_filter('floatformat', floatformat, False) -template.register_filter('get_digit', get_digit, True) -template.register_filter('join', join, True) -template.register_filter('length', length, False) -template.register_filter('length_is', length_is, True) -template.register_filter('linebreaks', linebreaks, False) -template.register_filter('linebreaksbr', linebreaksbr, False) -template.register_filter('linenumbers', linenumbers, False) -template.register_filter('ljust', ljust, True) -template.register_filter('lower', lower, False) -template.register_filter('make_list', make_list, False) -template.register_filter('phone2numeric', phone2numeric, False) -template.register_filter('pluralize', pluralize, False) -template.register_filter('pprint', pprint, False) -template.register_filter('removetags', removetags, True) -template.register_filter('random', random, False) -template.register_filter('rjust', rjust, True) -template.register_filter('slice', slice_, True) -template.register_filter('slugify', slugify, False) -template.register_filter('stringformat', stringformat, True) -template.register_filter('striptags', striptags, False) -template.register_filter('time', time, True) -template.register_filter('timesince', timesince, False) -template.register_filter('title', title, False) -template.register_filter('truncatewords', truncatewords, True) -template.register_filter('unordered_list', unordered_list, False) -template.register_filter('upper', upper, False) -template.register_filter('urlencode', urlencode, False) -template.register_filter('urlize', urlize, False) -template.register_filter('urlizetrunc', urlizetrunc, True) -template.register_filter('wordcount', wordcount, False) -template.register_filter('wordwrap', wordwrap, True) -template.register_filter('yesno', yesno, True) +# Syntax: register_filter(name of filter, callback, has_argument) +register_filter('add', add, True) +register_filter('addslashes', addslashes, False) +register_filter('capfirst', capfirst, False) +register_filter('center', center, True) +register_filter('cut', cut, True) +register_filter('date', date, True) +register_filter('default', default, True) +register_filter('dictsort', dictsort, True) +register_filter('dictsortreversed', dictsortreversed, True) +register_filter('divisibleby', divisibleby, True) +register_filter('escape', escape, False) +register_filter('filesizeformat', filesizeformat, False) +register_filter('first', first, False) +register_filter('fix_ampersands', fix_ampersands, False) +register_filter('floatformat', floatformat, False) +register_filter('get_digit', get_digit, True) +register_filter('join', join, True) +register_filter('length', length, False) +register_filter('length_is', length_is, True) +register_filter('linebreaks', linebreaks, False) +register_filter('linebreaksbr', linebreaksbr, False) +register_filter('linenumbers', linenumbers, False) +register_filter('ljust', ljust, True) +register_filter('lower', lower, False) +register_filter('make_list', make_list, False) +register_filter('phone2numeric', phone2numeric, False) +register_filter('pluralize', pluralize, False) +register_filter('pprint', pprint, False) +register_filter('removetags', removetags, True) +register_filter('random', random, False) +register_filter('rjust', rjust, True) +register_filter('slice', slice_, True) +register_filter('slugify', slugify, False) +register_filter('stringformat', stringformat, True) +register_filter('striptags', striptags, False) +register_filter('time', time, True) +register_filter('timesince', timesince, False) +register_filter('title', title, False) +register_filter('truncatewords', truncatewords, True) +register_filter('unordered_list', unordered_list, False) +register_filter('upper', upper, False) +register_filter('urlencode', urlencode, False) +register_filter('urlize', urlize, False) +register_filter('urlizetrunc', urlizetrunc, True) +register_filter('wordcount', wordcount, False) +register_filter('wordwrap', wordwrap, True) +register_filter('yesno', yesno, True) diff --git a/django/core/defaulttags.py b/django/core/template/defaulttags.py index e86b385f9c..ea21ebafce 100644 --- a/django/core/defaulttags.py +++ b/django/core/template/defaulttags.py @@ -1,13 +1,14 @@ "Default tags used by the template system, available to all templates." +from django.core.template import Node, NodeList, Template, Context, resolve_variable, resolve_variable_with_filters, get_filters_from_token, registered_filters +from django.core.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, register_tag import sys -import template -class CommentNode(template.Node): +class CommentNode(Node): def render(self, context): return '' -class CycleNode(template.Node): +class CycleNode(Node): def __init__(self, cyclevars): self.cyclevars = cyclevars self.cyclevars_len = len(cyclevars) @@ -17,7 +18,7 @@ class CycleNode(template.Node): self.counter += 1 return self.cyclevars[self.counter % self.cyclevars_len] -class DebugNode(template.Node): +class DebugNode(Node): def render(self, context): from pprint import pformat output = [pformat(val) for val in context] @@ -25,7 +26,7 @@ class DebugNode(template.Node): output.append(pformat(sys.modules)) return ''.join(output) -class FilterNode(template.Node): +class FilterNode(Node): def __init__(self, filters, nodelist): self.filters, self.nodelist = filters, nodelist @@ -33,21 +34,21 @@ class FilterNode(template.Node): output = self.nodelist.render(context) # apply filters for f in self.filters: - output = template.registered_filters[f[0]][0](output, f[1]) + output = registered_filters[f[0]][0](output, f[1]) return output -class FirstOfNode(template.Node): +class FirstOfNode(Node): def __init__(self, vars): self.vars = vars def render(self, context): for var in self.vars: - value = template.resolve_variable(var, context) + value = resolve_variable(var, context) if value: return str(value) return '' -class ForNode(template.Node): +class ForNode(Node): def __init__(self, loopvar, sequence, reversed, nodelist_loop): self.loopvar, self.sequence = loopvar, sequence self.reversed = reversed @@ -73,15 +74,15 @@ class ForNode(template.Node): return nodes def render(self, context): - nodelist = template.NodeList() + nodelist = NodeList() if context.has_key('forloop'): parentloop = context['forloop'] else: parentloop = {} context.push() try: - values = template.resolve_variable_with_filters(self.sequence, context) - except template.VariableDoesNotExist: + values = resolve_variable_with_filters(self.sequence, context) + except VariableDoesNotExist: values = [] if values is None: values = [] @@ -111,7 +112,7 @@ class ForNode(template.Node): context.pop() return nodelist.render(context) -class IfChangedNode(template.Node): +class IfChangedNode(Node): def __init__(self, nodelist): self.nodelist = nodelist self._last_seen = None @@ -129,7 +130,7 @@ class IfChangedNode(template.Node): else: return '' -class IfEqualNode(template.Node): +class IfEqualNode(Node): def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): self.var1, self.var2 = var1, var2 self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false @@ -139,13 +140,13 @@ class IfEqualNode(template.Node): return "<IfEqualNode>" def render(self, context): - val1 = template.resolve_variable(self.var1, context) - val2 = template.resolve_variable(self.var2, context) + val1 = resolve_variable(self.var1, context) + val2 = resolve_variable(self.var2, context) if (self.negate and val1 != val2) or (not self.negate and val1 == val2): return self.nodelist_true.render(context) return self.nodelist_false.render(context) -class IfNode(template.Node): +class IfNode(Node): def __init__(self, boolvars, nodelist_true, nodelist_false): self.boolvars = boolvars self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false @@ -170,27 +171,27 @@ class IfNode(template.Node): def render(self, context): for ifnot, boolvar in self.boolvars: try: - value = template.resolve_variable_with_filters(boolvar, context) - except template.VariableDoesNotExist: + value = resolve_variable_with_filters(boolvar, context) + except VariableDoesNotExist: value = None if (value and not ifnot) or (ifnot and not value): return self.nodelist_true.render(context) return self.nodelist_false.render(context) -class RegroupNode(template.Node): +class RegroupNode(Node): def __init__(self, target_var, expression, var_name): self.target_var, self.expression = target_var, expression self.var_name = var_name def render(self, context): - obj_list = template.resolve_variable_with_filters(self.target_var, context) + obj_list = resolve_variable_with_filters(self.target_var, context) if obj_list == '': # target_var wasn't found in context; fail silently context[self.var_name] = [] return '' output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]} for obj in obj_list: - grouper = template.resolve_variable_with_filters('var.%s' % self.expression, \ - template.Context({'var': obj})) + grouper = resolve_variable_with_filters('var.%s' % self.expression, \ + Context({'var': obj})) if output and repr(output[-1]['grouper']) == repr(grouper): output[-1]['list'].append(obj) else: @@ -205,7 +206,7 @@ def include_is_allowed(filepath): return True return False -class SsiNode(template.Node): +class SsiNode(Node): def __init__(self, filepath, parsed): self.filepath, self.parsed = filepath, parsed @@ -220,13 +221,13 @@ class SsiNode(template.Node): output = '' if self.parsed: try: - t = template.Template(output) + t = Template(output) return t.render(context) - except template.TemplateSyntaxError: + except TemplateSyntaxError: return '' # Fail silently for invalid included templates. return output -class LoadNode(template.Node): +class LoadNode(Node): def __init__(self, taglib): self.taglib = taglib @@ -244,7 +245,7 @@ class LoadNode(template.Node): pass # Fail silently for invalid loads. return '' -class NowNode(template.Node): +class NowNode(Node): def __init__(self, format_string): self.format_string = format_string @@ -254,11 +255,11 @@ class NowNode(template.Node): df = DateFormat(datetime.now()) return df.format(self.format_string) -class TemplateTagNode(template.Node): - mapping = {'openblock': template.BLOCK_TAG_START, - 'closeblock': template.BLOCK_TAG_END, - 'openvariable': template.VARIABLE_TAG_START, - 'closevariable': template.VARIABLE_TAG_END} +class TemplateTagNode(Node): + mapping = {'openblock': BLOCK_TAG_START, + 'closeblock': BLOCK_TAG_END, + 'openvariable': VARIABLE_TAG_START, + 'closevariable': VARIABLE_TAG_END} def __init__(self, tagtype): self.tagtype = tagtype @@ -266,7 +267,7 @@ class TemplateTagNode(template.Node): def render(self, context): return self.mapping.get(self.tagtype, '') -class WidthRatioNode(template.Node): +class WidthRatioNode(Node): def __init__(self, val_var, max_var, max_width): self.val_var = val_var self.max_var = max_var @@ -274,9 +275,9 @@ class WidthRatioNode(template.Node): def render(self, context): try: - value = template.resolve_variable_with_filters(self.val_var, context) - maxvalue = template.resolve_variable_with_filters(self.max_var, context) - except template.VariableDoesNotExist: + value = resolve_variable_with_filters(self.val_var, context) + maxvalue = resolve_variable_with_filters(self.max_var, context) + except VariableDoesNotExist: return '' try: value = float(value) @@ -330,7 +331,7 @@ def do_cycle(parser, token): args = token.contents.split() if len(args) < 2: - raise template.TemplateSyntaxError("'Cycle' statement requires at least two arguments") + raise TemplateSyntaxError("'Cycle' statement requires at least two arguments") elif len(args) == 2 and "," in args[1]: # {% cycle a,b,c %} @@ -341,13 +342,13 @@ def do_cycle(parser, token): elif len(args) == 2: name = args[1] if not parser._namedCycleNodes.has_key(name): - raise template.TemplateSyntaxError("Named cycle '%s' does not exist" % name) + raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) return parser._namedCycleNodes[name] elif len(args) == 4: # {% cycle a,b,c as name %} if args[2] != 'as': - raise template.TemplateSyntaxError("Second 'cycle' argument must be 'as'") + raise TemplateSyntaxError("Second 'cycle' argument must be 'as'") cyclevars = [v for v in args[1].split(",") if v] # split and kill blanks name = args[3] node = CycleNode(cyclevars) @@ -359,7 +360,7 @@ def do_cycle(parser, token): return node else: - raise template.TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args) + raise TemplateSyntaxError("Invalid arguments to 'cycle': %s" % args) def do_debug(parser, token): "Print a whole load of debugging information, including the context and imported modules" @@ -379,7 +380,7 @@ def do_filter(parser, token): {% endfilter %} """ _, rest = token.contents.split(None, 1) - _, filters = template.get_filters_from_token('var|%s' % rest) + _, filters = get_filters_from_token('var|%s' % rest) nodelist = parser.parse(('endfilter',)) parser.delete_first_token() return FilterNode(filters, nodelist) @@ -408,7 +409,7 @@ def do_firstof(parser, token): """ bits = token.contents.split()[1:] if len(bits) < 1: - raise template.TemplateSyntaxError, "'firstof' statement requires at least one argument" + raise TemplateSyntaxError, "'firstof' statement requires at least one argument" return FirstOfNode(bits) @@ -434,9 +435,9 @@ def do_for(parser, token): ========================== ================================================ ``forloop.counter`` The current iteration of the loop (1-indexed) ``forloop.counter0`` The current iteration of the loop (0-indexed) - ``forloop.revcounter`` The number of iterations from the end of the + ``forloop.revcounter`` The number of iterations from the end of the loop (1-indexed) - ``forloop.revcounter0`` The number of iterations from the end of the + ``forloop.revcounter0`` The number of iterations from the end of the loop (0-indexed) ``forloop.first`` True if this is the first time through the loop ``forloop.last`` True if this is the last time through the loop @@ -447,11 +448,11 @@ def do_for(parser, token): """ bits = token.contents.split() if len(bits) == 5 and bits[4] != 'reversed': - raise template.TemplateSyntaxError, "'for' statements with five words should end in 'reversed': %s" % token.contents + raise TemplateSyntaxError, "'for' statements with five words should end in 'reversed': %s" % token.contents if len(bits) not in (4, 5): - raise template.TemplateSyntaxError, "'for' statements should have either four or five words: %s" % token.contents + raise TemplateSyntaxError, "'for' statements should have either four or five words: %s" % token.contents if bits[2] != 'in': - raise template.TemplateSyntaxError, "'for' statement must contain 'in' as the second word: %s" % token.contents + raise TemplateSyntaxError, "'for' statement must contain 'in' as the second word: %s" % token.contents loopvar = bits[1] sequence = bits[3] reversed = (len(bits) == 5) @@ -477,7 +478,7 @@ def do_ifequal(parser, token, negate): """ bits = token.contents.split() if len(bits) != 3: - raise template.TemplateSyntaxError, "%r takes two arguments" % bits[0] + raise TemplateSyntaxError, "%r takes two arguments" % bits[0] end_tag = 'end' + bits[0] nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() @@ -485,7 +486,7 @@ def do_ifequal(parser, token, negate): nodelist_false = parser.parse((end_tag,)) parser.delete_first_token() else: - nodelist_false = template.NodeList() + nodelist_false = NodeList() return IfEqualNode(bits[1], bits[2], nodelist_true, nodelist_false, negate) def do_if(parser, token): @@ -538,7 +539,7 @@ def do_if(parser, token): bits = token.contents.split() del bits[0] if not bits: - raise template.TemplateSyntaxError, "'if' statement requires at least one argument" + raise TemplateSyntaxError, "'if' statement requires at least one argument" # bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] boolpairs = ' '.join(bits).split(' or ') boolvars = [] @@ -546,7 +547,7 @@ def do_if(parser, token): if ' ' in boolpair: not_, boolvar = boolpair.split() if not_ != 'not': - raise template.TemplateSyntaxError, "Expected 'not' in if statement" + raise TemplateSyntaxError, "Expected 'not' in if statement" boolvars.append((True, boolvar)) else: boolvars.append((False, boolpair)) @@ -556,7 +557,7 @@ def do_if(parser, token): nodelist_false = parser.parse(('endif',)) parser.delete_first_token() else: - nodelist_false = template.NodeList() + nodelist_false = NodeList() return IfNode(boolvars, nodelist_true, nodelist_false) def do_ifchanged(parser, token): @@ -576,7 +577,7 @@ def do_ifchanged(parser, token): """ bits = token.contents.split() if len(bits) != 1: - raise template.TemplateSyntaxError, "'ifchanged' tag takes no arguments" + raise TemplateSyntaxError, "'ifchanged' tag takes no arguments" nodelist = parser.parse(('endifchanged',)) parser.delete_first_token() return IfChangedNode(nodelist) @@ -599,12 +600,12 @@ def do_ssi(parser, token): bits = token.contents.split() parsed = False if len(bits) not in (2, 3): - raise template.TemplateSyntaxError, "'ssi' tag takes one argument: the path to the file to be included" + raise TemplateSyntaxError, "'ssi' tag takes one argument: the path to the file to be included" if len(bits) == 3: if bits[2] == 'parsed': parsed = True else: - raise template.TemplateSyntaxError, "Second (optional) argument to %s tag must be 'parsed'" % bits[0] + raise TemplateSyntaxError, "Second (optional) argument to %s tag must be 'parsed'" % bits[0] return SsiNode(bits[1], parsed) def do_load(parser, token): @@ -617,13 +618,13 @@ def do_load(parser, token): """ bits = token.contents.split() if len(bits) != 2: - raise template.TemplateSyntaxError, "'load' statement takes one argument" + raise TemplateSyntaxError, "'load' statement takes one argument" taglib = bits[1] # check at compile time that the module can be imported try: LoadNode.load_taglib(taglib) except ImportError: - raise template.TemplateSyntaxError, "'%s' is not a valid tag library" % taglib + raise TemplateSyntaxError, "'%s' is not a valid tag library" % taglib return LoadNode(taglib) def do_now(parser, token): @@ -639,7 +640,7 @@ def do_now(parser, token): """ bits = token.contents.split('"') if len(bits) != 3: - raise template.TemplateSyntaxError, "'now' statement takes one argument" + raise TemplateSyntaxError, "'now' statement takes one argument" format_string = bits[1] return NowNode(format_string) @@ -691,13 +692,13 @@ def do_regroup(parser, token): """ firstbits = token.contents.split(None, 3) if len(firstbits) != 4: - raise template.TemplateSyntaxError, "'regroup' tag takes five arguments" + raise TemplateSyntaxError, "'regroup' tag takes five arguments" target_var = firstbits[1] if firstbits[2] != 'by': - raise template.TemplateSyntaxError, "second argument to 'regroup' tag must be 'by'" + raise TemplateSyntaxError, "second argument to 'regroup' tag must be 'by'" lastbits_reversed = firstbits[3][::-1].split(None, 2) if lastbits_reversed[1][::-1] != 'as': - raise template.TemplateSyntaxError, "next-to-last argument to 'regroup' tag must be 'as'" + raise TemplateSyntaxError, "next-to-last argument to 'regroup' tag must be 'as'" expression = lastbits_reversed[2][::-1] var_name = lastbits_reversed[0][::-1] return RegroupNode(target_var, expression, var_name) @@ -722,10 +723,10 @@ def do_templatetag(parser, token): """ bits = token.contents.split() if len(bits) != 2: - raise template.TemplateSyntaxError, "'templatetag' statement takes one argument" + raise TemplateSyntaxError, "'templatetag' statement takes one argument" tag = bits[1] if not TemplateTagNode.mapping.has_key(tag): - raise template.TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \ + raise TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \ (tag, TemplateTagNode.mapping.keys()) return TemplateTagNode(tag) @@ -744,27 +745,27 @@ def do_widthratio(parser, token): """ bits = token.contents.split() if len(bits) != 4: - raise template.TemplateSyntaxError("widthratio takes three arguments") + raise TemplateSyntaxError("widthratio takes three arguments") tag, this_value_var, max_value_var, max_width = bits try: max_width = int(max_width) except ValueError: - raise template.TemplateSyntaxError("widthratio final argument must be an integer") + raise TemplateSyntaxError("widthratio final argument must be an integer") return WidthRatioNode(this_value_var, max_value_var, max_width) -template.register_tag('comment', do_comment) -template.register_tag('cycle', do_cycle) -template.register_tag('debug', do_debug) -template.register_tag('filter', do_filter) -template.register_tag('firstof', do_firstof) -template.register_tag('for', do_for) -template.register_tag('ifequal', lambda parser, token: do_ifequal(parser, token, False)) -template.register_tag('ifnotequal', lambda parser, token: do_ifequal(parser, token, True)) -template.register_tag('if', do_if) -template.register_tag('ifchanged', do_ifchanged) -template.register_tag('regroup', do_regroup) -template.register_tag('ssi', do_ssi) -template.register_tag('load', do_load) -template.register_tag('now', do_now) -template.register_tag('templatetag', do_templatetag) -template.register_tag('widthratio', do_widthratio) +register_tag('comment', do_comment) +register_tag('cycle', do_cycle) +register_tag('debug', do_debug) +register_tag('filter', do_filter) +register_tag('firstof', do_firstof) +register_tag('for', do_for) +register_tag('ifequal', lambda parser, token: do_ifequal(parser, token, False)) +register_tag('ifnotequal', lambda parser, token: do_ifequal(parser, token, True)) +register_tag('if', do_if) +register_tag('ifchanged', do_ifchanged) +register_tag('regroup', do_regroup) +register_tag('ssi', do_ssi) +register_tag('load', do_load) +register_tag('now', do_now) +register_tag('templatetag', do_templatetag) +register_tag('widthratio', do_widthratio) diff --git a/django/core/template/loader.py b/django/core/template/loader.py new file mode 100644 index 0000000000..65a6c735b3 --- /dev/null +++ b/django/core/template/loader.py @@ -0,0 +1,163 @@ +"Wrapper for loading templates from storage of some sort (e.g. files or db)" + +from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, register_tag +from django.core.template.loaders.filesystem import load_template_source + +class ExtendsError(Exception): + pass + +def get_template(template_name): + """ + Returns a compiled Template object for the given template name, + handling template inheritance recursively. + """ + return get_template_from_string(load_template_source(template_name)) + +def get_template_from_string(source): + """ + Returns a compiled Template object for the given template code, + handling template inheritance recursively. + """ + return Template(source) + +def render_to_string(template_name, dictionary=None, context_instance=None): + """ + Loads the given template_name and renders it with the given dictionary as + context. The template_name may be a string to load a single template using + get_template, or it may be a tuple to use select_template to find one of + the templates in the list. Returns a string. + """ + dictionary = dictionary or {} + if isinstance(template_name, (list, tuple)): + t = select_template(template_name) + else: + t = get_template(template_name) + if context_instance: + context_instance.update(dictionary) + else: + context_instance = Context(dictionary) + return t.render(context_instance) + +def select_template(template_name_list): + "Given a list of template names, returns the first that can be loaded." + for template_name in template_name_list: + try: + return get_template(template_name) + except TemplateDoesNotExist: + continue + # If we get here, none of the templates could be loaded + raise TemplateDoesNotExist, ', '.join(template_name_list) + +class BlockNode(Node): + def __init__(self, name, nodelist, parent=None): + self.name, self.nodelist, self.parent = name, nodelist, parent + + def __repr__(self): + return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) + + def render(self, context): + context.push() + # Save context in case of block.super(). + self.context = context + context['block'] = self + result = self.nodelist.render(context) + context.pop() + return result + + def super(self): + if self.parent: + return self.parent.render(self.context) + return '' + + def add_parent(self, nodelist): + if self.parent: + self.parent.add_parent(nodelist) + else: + self.parent = BlockNode(self.name, nodelist) + +class ExtendsNode(Node): + def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None): + self.nodelist = nodelist + self.parent_name, self.parent_name_var = parent_name, parent_name_var + self.template_dirs = template_dirs + + def get_parent(self, context): + if self.parent_name_var: + self.parent_name = resolve_variable_with_filters(self.parent_name_var, context) + parent = self.parent_name + if not parent: + error_msg = "Invalid template name in 'extends' tag: %r." % parent + if self.parent_name_var: + error_msg += " Got this from the %r variable." % self.parent_name_var + raise TemplateSyntaxError, error_msg + try: + return get_template_from_string(load_template_source(parent, self.template_dirs)) + except TemplateDoesNotExist: + raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent + + def render(self, context): + compiled_parent = self.get_parent(context) + parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode) + parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) + for block_node in self.nodelist.get_nodes_by_type(BlockNode): + # Check for a BlockNode with this node's name, and replace it if found. + try: + parent_block = parent_blocks[block_node.name] + except KeyError: + # This BlockNode wasn't found in the parent template, but the + # parent block might be defined in the parent's *parent*, so we + # add this BlockNode to the parent's ExtendsNode nodelist, so + # it'll be checked when the parent node's render() is called. + if parent_is_child: + compiled_parent.nodelist[0].nodelist.append(block_node) + else: + # Keep any existing parents and add a new one. Used by BlockNode. + parent_block.parent = block_node.parent + parent_block.add_parent(parent_block.nodelist) + parent_block.nodelist = block_node.nodelist + return compiled_parent.render(context) + +def do_block(parser, token): + """ + Define a block that can be overridden by child templates. + """ + bits = token.contents.split() + if len(bits) != 2: + raise TemplateSyntaxError, "'%s' tag takes only one argument" % bits[0] + block_name = bits[1] + # Keep track of the names of BlockNodes found in this template, so we can + # check for duplication. + try: + if block_name in parser.__loaded_blocks: + raise TemplateSyntaxError, "'%s' tag with name '%s' appears more than once" % (bits[0], block_name) + parser.__loaded_blocks.append(block_name) + except AttributeError: # parser._loaded_blocks isn't a list yet + parser.__loaded_blocks = [block_name] + nodelist = parser.parse(('endblock',)) + parser.delete_first_token() + return BlockNode(block_name, nodelist) + +def do_extends(parser, token): + """ + Signal that this template extends a parent template. + + This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) + uses the literal value "base" as the name of the parent template to extend, + or ``{% entends variable %}`` uses the value of ``variable`` as the name + of the parent template to extend. + """ + bits = token.contents.split() + if len(bits) != 2: + raise TemplateSyntaxError, "'%s' takes one argument" % bits[0] + parent_name, parent_name_var = None, None + if (bits[1].startswith('"') and bits[1].endswith('"')) or (bits[1].startswith("'") and bits[1].endswith("'")): + parent_name = bits[1][1:-1] + else: + parent_name_var = bits[1] + nodelist = parser.parse() + if nodelist.get_nodes_by_type(ExtendsNode): + raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0] + return ExtendsNode(nodelist, parent_name, parent_name_var) + +register_tag('block', do_block) +register_tag('extends', do_extends) diff --git a/django/core/template/loaders/__init__.py b/django/core/template/loaders/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/django/core/template/loaders/__init__.py diff --git a/django/core/template_file.py b/django/core/template/loaders/filesystem.py index 6f5a324d61..849f62b94e 100644 --- a/django/core/template_file.py +++ b/django/core/template/loaders/filesystem.py @@ -1,4 +1,4 @@ -# Wrapper for loading templates from files +# Wrapper for loading templates from the filesystem. from django.conf.settings import TEMPLATE_DIRS, TEMPLATE_FILE_EXTENSION from django.core.template import TemplateDoesNotExist diff --git a/django/core/template_loader.py b/django/core/template_loader.py index 7c26cf0faa..e268c390e1 100644 --- a/django/core/template_loader.py +++ b/django/core/template_loader.py @@ -1,162 +1,7 @@ -"Wrapper for loading templates from storage of some sort (e.g. files or db)" -import template -from template_file import load_template_source +# This module is DEPRECATED! +# +# You should no longer be using django.core.template_loader. +# +# Use django.core.template.loader instead. -class ExtendsError(Exception): - pass - -def get_template(template_name): - """ - Returns a compiled template.Template object for the given template name, - handling template inheritance recursively. - """ - return get_template_from_string(load_template_source(template_name)) - -def get_template_from_string(source): - """ - Returns a compiled template.Template object for the given template code, - handling template inheritance recursively. - """ - return template.Template(source) - -def render_to_string(template_name, dictionary=None, context_instance=None): - """ - Loads the given template_name and renders it with the given dictionary as - context. The template_name may be a string to load a single template using - get_template, or it may be a tuple to use select_template to find one of - the templates in the list. Returns a string. - """ - dictionary = dictionary or {} - if isinstance(template_name, (list, tuple)): - t = select_template(template_name) - else: - t = get_template(template_name) - if context_instance: - context_instance.update(dictionary) - else: - context_instance = template.Context(dictionary) - return t.render(context_instance) - -def select_template(template_name_list): - "Given a list of template names, returns the first that can be loaded." - for template_name in template_name_list: - try: - return get_template(template_name) - except template.TemplateDoesNotExist: - continue - # If we get here, none of the templates could be loaded - raise template.TemplateDoesNotExist, ', '.join(template_name_list) - -class BlockNode(template.Node): - def __init__(self, name, nodelist, parent=None): - self.name, self.nodelist, self.parent = name, nodelist, parent - - def __repr__(self): - return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) - - def render(self, context): - context.push() - # Save context in case of block.super(). - self.context = context - context['block'] = self - result = self.nodelist.render(context) - context.pop() - return result - - def super(self): - if self.parent: - return self.parent.render(self.context) - return '' - - def add_parent(self, nodelist): - if self.parent: - self.parent.add_parent(nodelist) - else: - self.parent = BlockNode(self.name, nodelist) - -class ExtendsNode(template.Node): - def __init__(self, nodelist, parent_name, parent_name_var, template_dirs=None): - self.nodelist = nodelist - self.parent_name, self.parent_name_var = parent_name, parent_name_var - self.template_dirs = template_dirs - - def get_parent(self, context): - if self.parent_name_var: - self.parent_name = template.resolve_variable_with_filters(self.parent_name_var, context) - parent = self.parent_name - if not parent: - error_msg = "Invalid template name in 'extends' tag: %r." % parent - if self.parent_name_var: - error_msg += " Got this from the %r variable." % self.parent_name_var - raise template.TemplateSyntaxError, error_msg - try: - return get_template_from_string(load_template_source(parent, self.template_dirs)) - except template.TemplateDoesNotExist: - raise template.TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent - - def render(self, context): - compiled_parent = self.get_parent(context) - parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode) - parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) - for block_node in self.nodelist.get_nodes_by_type(BlockNode): - # Check for a BlockNode with this node's name, and replace it if found. - try: - parent_block = parent_blocks[block_node.name] - except KeyError: - # This BlockNode wasn't found in the parent template, but the - # parent block might be defined in the parent's *parent*, so we - # add this BlockNode to the parent's ExtendsNode nodelist, so - # it'll be checked when the parent node's render() is called. - if parent_is_child: - compiled_parent.nodelist[0].nodelist.append(block_node) - else: - # Keep any existing parents and add a new one. Used by BlockNode. - parent_block.parent = block_node.parent - parent_block.add_parent(parent_block.nodelist) - parent_block.nodelist = block_node.nodelist - return compiled_parent.render(context) - -def do_block(parser, token): - """ - Define a block that can be overridden by child templates. - """ - bits = token.contents.split() - if len(bits) != 2: - raise template.TemplateSyntaxError, "'%s' tag takes only one argument" % bits[0] - block_name = bits[1] - # Keep track of the names of BlockNodes found in this template, so we can - # check for duplication. - try: - if block_name in parser.__loaded_blocks: - raise template.TemplateSyntaxError, "'%s' tag with name '%s' appears more than once" % (bits[0], block_name) - parser.__loaded_blocks.append(block_name) - except AttributeError: # parser._loaded_blocks isn't a list yet - parser.__loaded_blocks = [block_name] - nodelist = parser.parse(('endblock',)) - parser.delete_first_token() - return BlockNode(block_name, nodelist) - -def do_extends(parser, token): - """ - Signal that this template extends a parent template. - - This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) - uses the literal value "base" as the name of the parent template to extend, - or ``{% entends variable %}`` uses the value of ``variable`` as the name - of the parent template to extend. - """ - bits = token.contents.split() - if len(bits) != 2: - raise template.TemplateSyntaxError, "'%s' takes one argument" % bits[0] - parent_name, parent_name_var = None, None - if (bits[1].startswith('"') and bits[1].endswith('"')) or (bits[1].startswith("'") and bits[1].endswith("'")): - parent_name = bits[1][1:-1] - else: - parent_name_var = bits[1] - nodelist = parser.parse() - if nodelist.get_nodes_by_type(ExtendsNode): - raise template.TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0] - return ExtendsNode(nodelist, parent_name, parent_name_var) - -template.register_tag('block', do_block) -template.register_tag('extends', do_extends) +from django.core.template.loader import * diff --git a/django/middleware/admin.py b/django/middleware/admin.py index ff21689646..9c20cfc31c 100644 --- a/django/middleware/admin.py +++ b/django/middleware/admin.py @@ -1,6 +1,6 @@ from django.utils import httpwrappers -from django.core import template_loader -from django.core.extensions import DjangoContext as Context +from django.core.extensions import DjangoContext +from django.core.extensions import render_to_response from django.models.auth import users from django.views.registration import passwords from django.views.auth.login import logout @@ -96,14 +96,12 @@ class AdminUserRequired: post_data = encode_post_data(request.POST) else: post_data = encode_post_data({}) - t = template_loader.get_template(self.get_login_template_name()) - c = Context(request, { + return render_to_response(self.get_login_template_name(), { 'title': 'Log in', 'app_path': request.path, 'post_data': post_data, 'error_message': error_message - }) - return httpwrappers.HttpResponse(t.render(c)) + }, context_instance=DjangoContext(request)) def authenticate_user(self, user, password): return user.check_password(password) and user.is_staff diff --git a/django/views/admin/doc.py b/django/views/admin/doc.py index 38d7fdc572..64785385c4 100644 --- a/django/views/admin/doc.py +++ b/django/views/admin/doc.py @@ -4,7 +4,8 @@ from django.conf import settings from django.models.core import sites from django.core.extensions import DjangoContext, render_to_response from django.core.exceptions import Http404, ViewDoesNotExist -from django.core import template, template_loader, defaulttags, defaultfilters, urlresolvers +from django.core import template, template_loader, urlresolvers +from django.core.template import defaulttags, defaultfilters try: from django.parts.admin import doc except ImportError: diff --git a/django/views/admin/template.py b/django/views/admin/template.py index 2bf4f1a1d8..c35770178e 100644 --- a/django/views/admin/template.py +++ b/django/views/admin/template.py @@ -1,5 +1,6 @@ -from django.core import formfields, template_loader, validators +from django.core import formfields, validators from django.core import template +from django.core.template import loader from django.core.extensions import DjangoContext, render_to_response from django.models.core import sites from django.conf import settings @@ -49,7 +50,7 @@ class TemplateValidator(formfields.Manipulator): # so that inheritance works in the site's context, register a new function # for "extends" that uses the site's TEMPLATE_DIR instead def new_do_extends(parser, token): - node = template_loader.do_extends(parser, token) + node = loader.do_extends(parser, token) node.template_dirs = settings_module.TEMPLATE_DIRS return node template.register_tag('extends', new_do_extends) @@ -58,10 +59,10 @@ class TemplateValidator(formfields.Manipulator): # making sure to reset the extends function in any case error = None try: - tmpl = template_loader.get_template_from_string(field_data) + tmpl = loader.get_template_from_string(field_data) tmpl.render(template.Context({})) except template.TemplateSyntaxError, e: error = e - template.register_tag('extends', template_loader.do_extends) + template.register_tag('extends', loader.do_extends) if error: raise validators.ValidationError, e.args diff --git a/django/views/auth/login.py b/django/views/auth/login.py index 75a80c7907..6950ad7efe 100644 --- a/django/views/auth/login.py +++ b/django/views/auth/login.py @@ -1,5 +1,5 @@ from django.parts.auth.formfields import AuthenticationForm -from django.core import formfields, template_loader +from django.core import formfields from django.core.extensions import DjangoContext, render_to_response from django.models.auth import users from django.models.core import sites diff --git a/django/views/defaults.py b/django/views/defaults.py index c75bc6880e..d283e54c1b 100644 --- a/django/views/defaults.py +++ b/django/views/defaults.py @@ -1,6 +1,5 @@ -from django.core import template_loader from django.core.exceptions import Http404, ObjectDoesNotExist -from django.core.template import Context +from django.core.template import Context, loader from django.models.core import sites from django.utils import httpwrappers @@ -56,7 +55,7 @@ def page_not_found(request): if r == '': return httpwrappers.HttpResponseGone() return httpwrappers.HttpResponseRedirect(r.new_path) - t = template_loader.get_template('404') + t = loader.get_template('404') c = Context() return httpwrappers.HttpResponseNotFound(t.render(c)) @@ -67,6 +66,6 @@ def server_error(request): Templates: `500` Context: None """ - t = template_loader.get_template('500') + t = loader.get_template('500') c = Context() return httpwrappers.HttpResponseServerError(t.render(c)) diff --git a/django/views/registration/passwords.py b/django/views/registration/passwords.py index 662490eec7..09d3037560 100644 --- a/django/views/registration/passwords.py +++ b/django/views/registration/passwords.py @@ -1,5 +1,6 @@ -from django.core import formfields, template_loader, validators +from django.core import formfields, validators from django.core.extensions import DjangoContext, render_to_response +from django.core.template import loader from django.models.auth import users from django.views.decorators.auth import login_required from django.utils.httpwrappers import HttpResponseRedirect @@ -32,7 +33,7 @@ class PasswordResetForm(formfields.Manipulator): domain = current_site.domain else: site_name = domain = domain_override - t = template_loader.get_template('registration/password_reset_email') + t = loader.get_template('registration/password_reset_email') c = { 'new_password': new_pass, 'email': self.user_cache.email, |
