mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	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:
		| @@ -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 @@ class ExtendsNode(Node): | ||||
|                 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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -134,6 +134,12 @@ TEMPLATE_TESTS = { | ||||
|     '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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user