Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #598 -- Added {% include %} template tag. Added docs and unit t…

…ests. Thanks, rjwittams

git-svn-id: http://code.djangoproject.com/svn/django/trunk@1349 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit bedf10a98dfe46dda39e8a20530f7476e7df90ff 1 parent 1ba8bd1
@adrianholovaty adrianholovaty authored
View
45 django/core/template/loader.py
@@ -17,7 +17,7 @@
# installed, because pkg_resources is necessary to read eggs.
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
template_source_loaders = []
@@ -160,6 +160,32 @@ def render(self, context):
parent_block.nodelist = block_node.nodelist
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):
"""
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]
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('extends', do_extends)
+register_tag('include', do_include)
View
36 docs/templates.txt
@@ -492,6 +492,40 @@ ifnotequal
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
~~~~
@@ -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
`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
templatetag
View
6 tests/othertests/templates.py
@@ -134,6 +134,12 @@ def method(self):
'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"),
+ ### 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 ###########################################################
# Standard template with no inheritance
Please sign in to comment.
Something went wrong with that request. Please try again.