diff --git a/django/template/__init__.py b/django/template/__init__.py index 750c48988d..c53d400f3c 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -289,6 +289,9 @@ class Parser(object): return NodeList() def extend_nodelist(self, nodelist, node, token): + if (node.must_be_first and nodelist and + (not isinstance(nodelist[0], TextNode) or len(nodelist) > 2)): + raise TemplateSyntaxError("%r must be the first tag in the template." % node) nodelist.append(node) def enter_command(self, command, token): @@ -708,6 +711,10 @@ class Variable(object): return current class Node(object): + # Set this to True for nodes that must be first in the template (although + # they can be preceded by text nodes. + must_be_first = False + def render(self, context): "Return the node rendered as a string" pass diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index ef4d8ab23a..7597c04b73 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -37,11 +37,18 @@ class BlockNode(Node): self.parent = BlockNode(self.name, nodelist) class ExtendsNode(Node): + must_be_first = True + def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None): self.nodelist = nodelist self.parent_name, self.parent_name_expr = parent_name, parent_name_expr self.template_dirs = template_dirs + def __repr__(self): + if self.parent_name_expr: + return "" % self.parent_name_expr.token + return '' % self.parent_name + def get_parent(self, context): if self.parent_name_expr: self.parent_name = self.parent_name_expr.resolve(context)