Fixed #598 -- Added {% include %} template tag. Added docs and unit tests. Thanks, rjwittams
git-svn-id: http://code.djangoproject.com/svn/django/trunk@1349 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
1ba8bd114a
commit
bedf10a98d
|
@ -17,7 +17,7 @@
|
||||||
# installed, because pkg_resources is necessary to read eggs.
|
# installed, because pkg_resources is necessary to read eggs.
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, register_tag
|
from django.core.template import Template, Context, Node, TemplateDoesNotExist, TemplateSyntaxError, resolve_variable_with_filters, resolve_variable, register_tag
|
||||||
from django.conf.settings import TEMPLATE_LOADERS
|
from django.conf.settings import TEMPLATE_LOADERS
|
||||||
|
|
||||||
template_source_loaders = []
|
template_source_loaders = []
|
||||||
|
@ -160,6 +160,32 @@ class ExtendsNode(Node):
|
||||||
parent_block.nodelist = block_node.nodelist
|
parent_block.nodelist = block_node.nodelist
|
||||||
return compiled_parent.render(context)
|
return compiled_parent.render(context)
|
||||||
|
|
||||||
|
class ConstantIncludeNode(Node):
|
||||||
|
def __init__(self, template_path):
|
||||||
|
try:
|
||||||
|
t = get_template(template_path)
|
||||||
|
self.template = t
|
||||||
|
except:
|
||||||
|
self.template = None
|
||||||
|
|
||||||
|
def render(self, context):
|
||||||
|
if self.template:
|
||||||
|
return self.template.render(context)
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
class IncludeNode(Node):
|
||||||
|
def __init__(self, template_name):
|
||||||
|
self.template_name = template_name
|
||||||
|
|
||||||
|
def render(self, context):
|
||||||
|
try:
|
||||||
|
template_name = resolve_variable(self.template_name, context)
|
||||||
|
t = get_template(template_name)
|
||||||
|
return t.render(context)
|
||||||
|
except:
|
||||||
|
return '' # Fail silently for invalid included templates.
|
||||||
|
|
||||||
def do_block(parser, token):
|
def do_block(parser, token):
|
||||||
"""
|
"""
|
||||||
Define a block that can be overridden by child templates.
|
Define a block that can be overridden by child templates.
|
||||||
|
@ -202,5 +228,22 @@ def do_extends(parser, token):
|
||||||
raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0]
|
raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0]
|
||||||
return ExtendsNode(nodelist, parent_name, parent_name_var)
|
return ExtendsNode(nodelist, parent_name, parent_name_var)
|
||||||
|
|
||||||
|
def do_include(parser, token):
|
||||||
|
"""
|
||||||
|
Loads a template and renders it with the current context.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
{% include "foo/some_include" %}
|
||||||
|
"""
|
||||||
|
bits = token.contents.split()
|
||||||
|
if len(bits) != 2:
|
||||||
|
raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
|
||||||
|
path = bits[1]
|
||||||
|
if path[0] in ('"', "'") and path[-1] == path[0]:
|
||||||
|
return ConstantIncludeNode(path[1:-1])
|
||||||
|
return IncludeNode(bits[1])
|
||||||
|
|
||||||
register_tag('block', do_block)
|
register_tag('block', do_block)
|
||||||
register_tag('extends', do_extends)
|
register_tag('extends', do_extends)
|
||||||
|
register_tag('include', do_include)
|
||||||
|
|
|
@ -492,6 +492,40 @@ ifnotequal
|
||||||
|
|
||||||
Just like ``ifequal``, except it tests that the two arguments are not equal.
|
Just like ``ifequal``, except it tests that the two arguments are not equal.
|
||||||
|
|
||||||
|
include
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
**Only available in Django development version.**
|
||||||
|
|
||||||
|
Loads a template and renders it with the current context. This is a way of
|
||||||
|
"including" other templates within a template.
|
||||||
|
|
||||||
|
The template name can either be a variable or a hard-coded (quoted) string,
|
||||||
|
in either single or double quotes.
|
||||||
|
|
||||||
|
This example includes the contents of the template ``"foo/bar"``::
|
||||||
|
|
||||||
|
{% include "foo/bar" %}
|
||||||
|
|
||||||
|
This example includes the contents of the template whose name is contained in
|
||||||
|
the variable ``template_name``::
|
||||||
|
|
||||||
|
{% include template_name %}
|
||||||
|
|
||||||
|
An included template is rendered with the context of the template that's
|
||||||
|
including it. This example produces the output ``"Hello, John"``:
|
||||||
|
|
||||||
|
* Context: variable ``person`` is set to ``"john"``.
|
||||||
|
* Template::
|
||||||
|
|
||||||
|
{% include "name_snippet" %}
|
||||||
|
|
||||||
|
* The ``name_snippet`` template::
|
||||||
|
|
||||||
|
Hello, {{ person }}
|
||||||
|
|
||||||
|
See also: ``{% ssi %}``.
|
||||||
|
|
||||||
load
|
load
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
|
@ -645,6 +679,8 @@ file are evaluated as template code, within the current context::
|
||||||
Note that if you use ``{% ssi %}``, you'll need to define
|
Note that if you use ``{% ssi %}``, you'll need to define
|
||||||
`ALLOWED_INCLUDE_ROOTS`_ in your Django settings, as a security measure.
|
`ALLOWED_INCLUDE_ROOTS`_ in your Django settings, as a security measure.
|
||||||
|
|
||||||
|
See also: ``{% include %}``.
|
||||||
|
|
||||||
.. _ALLOWED_INCLUDE_ROOTS: http://www.djangoproject.com/documentation/settings/#allowed-include-roots
|
.. _ALLOWED_INCLUDE_ROOTS: http://www.djangoproject.com/documentation/settings/#allowed-include-roots
|
||||||
|
|
||||||
templatetag
|
templatetag
|
||||||
|
|
|
@ -134,6 +134,12 @@ TEMPLATE_TESTS = {
|
||||||
'ifnotequal03': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 2}, "yes"),
|
'ifnotequal03': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 2}, "yes"),
|
||||||
'ifnotequal04': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 1}, "no"),
|
'ifnotequal04': ("{% ifnotequal a b %}yes{% else %}no{% endifnotequal %}", {"a": 1, "b": 1}, "no"),
|
||||||
|
|
||||||
|
### INCLUDE TAG ###########################################################
|
||||||
|
'include01': ('{% include "basic-syntax01" %}', {}, "something cool"),
|
||||||
|
'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"),
|
||||||
|
'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"),
|
||||||
|
'include04': ('a{% include "nonexistent" %}b', {}, "ab"),
|
||||||
|
|
||||||
### INHERITANCE ###########################################################
|
### INHERITANCE ###########################################################
|
||||||
|
|
||||||
# Standard template with no inheritance
|
# Standard template with no inheritance
|
||||||
|
|
Loading…
Reference in New Issue