* 1.12.0 (2012-XX-XX)
+ * added an include function (does the same as the include tag but in a more flexible way)
* added the ability to set default values for macro arguments
* added support for named arguments for filters, tests, and functions
* moved filters/functions/tests syntax errors to the parser
--- /dev/null
+``include``
+===========
+
+.. versionadded:: 1.12
+ The include function was added in Twig 1.12.
+
+The ``include`` function returns the rendered content of a template:
+
+.. code-block:: jinja
+
+ {{ include('template.html') }}
+ {{ include(some_var) }}
+
+Included templates have access to the variables of the active context.
+
+If you are using the filesystem loader, the templates are looked for in the
+paths defined by it.
+
+The context is passed by default to the template but you can also pass
+additional variables:
+
+.. code-block:: jinja
+
+ {# template.html will have access to the variables from the current context and the additional ones provided #}
+ {{ include('template.html', {foo: 'bar'}) }}
+
+You can disable access to the context by setting ``with_context`` to
+``false``:
+
+.. code-block:: jinja
+
+ {# only the foo variable will be accessible #}
+ {{ include('template.html', {foo: 'bar'}, with_context = false) }}
+
+.. code-block:: jinja
+
+ {# no variables will be accessible #}
+ {{ include('template.html', with_context = false) }}
+
+And if the expression evaluates to a ``Twig_Template`` object, Twig will use it
+directly::
+
+ // {{ include(template) }}
+
+ $template = $twig->loadTemplate('some_template.twig');
+
+ $twig->loadTemplate('template.twig')->display(array('template' => $template));
+
+When you set the ``ignore_missing`` flag, Twig will return an empty string if
+the template does not exist:
+
+.. code-block:: jinja
+
+ {{ include('sidebar.html', ignore_missing = true) }}
+
+You can also provide a list of templates that are checked for existence before
+inclusion. The first template that exists will be rendered:
+
+.. code-block:: jinja
+
+ {{ include(['page_detailed.html', 'page.html']) }}
+
+If ``ignore_missing`` is set, it will fall back to rendering nothing if none
+of the templates exist, otherwise it will throw an exception.
+
+When including a template created by an end user, you should consider
+sandboxing it:
+
+.. code-block:: jinja
+
+ {{ include('page.html', sandboxed = true) }}
+
+Arguments
+---------
+
+ * ``template``: The template to render
+ * ``variables``: The variables to pass to the template
+ * ``with_context``: Whether to pass the current context variables or not
+ * ``ignore_missing``: Whether to ignore missing templates or not
+ * ``sandboxed``: Whether to sandbox the template or not
dump
date
template_from_string
+ include
.. code-block:: jinja
- {# the foo template will have access to the variables from the current context and the foo one #}
- {% include 'foo' with {'foo': 'bar'} %}
+ {# template.html will have access to the variables from the current context and the additional ones provided #}
+ {% include 'template.html' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
- {% include 'foo' with vars %}
+ {% include 'template.html' with vars %}
You can disable access to the context by appending the ``only`` keyword:
.. code-block:: jinja
{# only the foo variable will be accessible #}
- {% include 'foo' with {'foo': 'bar'} only %}
+ {% include 'template.html' with {'foo': 'bar'} only %}
.. code-block:: jinja
- {# no variable will be accessible #}
- {% include 'foo' only %}
+ {# no variables will be accessible #}
+ {% include 'template.html' only %}
.. tip::
.. code-block:: jinja
- {% include "sidebar.html" ignore missing %}
- {% include "sidebar.html" ignore missing with {'foo': 'bar} %}
- {% include "sidebar.html" ignore missing only %}
+ {% include 'sidebar.html' ignore missing %}
+ {% include 'sidebar.html' ignore missing with {'foo': 'bar} %}
+ {% include 'sidebar.html' ignore missing only %}
.. versionadded:: 1.2
The possibility to pass an array of templates has been added in Twig 1.2.
'cycle' => new Twig_Function_Function('twig_cycle'),
'random' => new Twig_Function_Function('twig_random', array('needs_environment' => true)),
'date' => new Twig_Function_Function('twig_date_converter', array('needs_environment' => true)),
+ 'include' => new Twig_Function_Function('twig_include', array('needs_environment' => true, 'needs_context' => true)),
);
}
{
return $value instanceof Traversable || is_array($value);
}
+
+/**
+ * Renders a template.
+ *
+ * @param string template The template to render
+ * @param array variables The variables to pass to the template
+ * @param Boolean with_context Whether to pass the current context variables or not
+ * @param Boolean ignore_missing Whether to ignore missing templates or not
+ * @param Boolean sandboxed Whether to sandbox the template or not
+ *
+ * @return string The rendered template
+ */
+function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false)
+{
+ if ($withContext) {
+ $variables = array_merge($context, $variables);
+ }
+
+ if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) {
+ $sandbox = $env->getExtension('sandbox');
+ if (!$alreadySandboxed = $sandbox->isSandboxed()) {
+ $sandbox->enableSandbox();
+ }
+ }
+
+ try {
+ return $env->resolveTemplate($template)->display($variables);
+ } catch (Twig_Error_Loader $e) {
+ if (!$ignoreMissing) {
+ throw $e;
+ }
+ }
+
+ if ($isSandboxed && !$alreadySandboxed) {
+ $sandbox->disableSandbox();
+ }
+}
--- /dev/null
+--TEST--
+"include" function
+--TEMPLATE--
+FOO
+{{ include("foo.twig") }}
+
+BAR
+--TEMPLATE(foo.twig)--
+FOOBAR
+--DATA--
+return array()
+--EXPECT--
+FOO
+
+FOOBAR
+
+BAR
--- /dev/null
+--TEST--
+"include" function allows expressions for the template to include
+--TEMPLATE--
+FOO
+{{ include(foo) }}
+
+BAR
+--TEMPLATE(foo.twig)--
+FOOBAR
+--DATA--
+return array('foo' => 'foo.twig')
+--EXPECT--
+FOO
+
+FOOBAR
+
+BAR
--- /dev/null
+--TEST--
+"include" function
+--TEMPLATE--
+{{ include(["foo.twig", "bar.twig"], ignore_missing = true) }}
+{{ include("foo.twig", ignore_missing = true) }}
+{{ include("foo.twig", ignore_missing = true, variables = {}) }}
+{{ include("foo.twig", ignore_missing = true, variables = {}, with_context = true) }}
+--DATA--
+return array()
+--EXPECT--
--- /dev/null
+--TEST--
+"include" function
+--TEMPLATE--
+{{ include("foo.twig") }}
+--DATA--
+return array();
+--EXCEPTION--
+Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2.
--- /dev/null
+--TEST--
+"include" function
+--TEMPLATE--
+{% extends "base.twig" %}
+
+{% block content %}
+ {{ parent() }}
+{% endblock %}
+--TEMPLATE(base.twig)--
+{% block content %}
+ {{ include("foo.twig") }}
+{% endblock %}
+--DATA--
+return array();
+--EXCEPTION--
+Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3.
--- /dev/null
+--TEST--
+"include" tag sandboxed
+--TEMPLATE--
+{{ include("foo.twig", sandboxed = true) }}
+--TEMPLATE(foo.twig)--
+{{ foo|e }}
+--DATA--
+return array()
+--EXCEPTION--
+Twig_Sandbox_SecurityError: Filter "e" is not allowed in "index.twig" at line 2.
--- /dev/null
+--TEST--
+"include" function accepts Twig_Template instance
+--TEMPLATE--
+{{ include(foo) }} FOO
+--TEMPLATE(foo.twig)--
+BAR
+--DATA--
+return array('foo' => $twig->loadTemplate('foo.twig'))
+--EXPECT--
+BAR FOO
--- /dev/null
+--TEST--
+"include" function
+--TEMPLATE--
+{{ include(["foo.twig", "bar.twig"]) }}
+{{- include(["bar.twig", "foo.twig"]) }}
+--TEMPLATE(foo.twig)--
+foo
+--DATA--
+return array()
+--EXPECT--
+foo
+foo
--- /dev/null
+--TEST--
+"include" function accept variables and with_context
+--TEMPLATE--
+{{ include("foo.twig") }}
+{{- include("foo.twig", with_context = false) }}
+{{- include("foo.twig", {'foo1': 'bar'}) }}
+{{- include("foo.twig", {'foo1': 'bar'}, with_context = false) }}
+--TEMPLATE(foo.twig)--
+{% for k, v in _context %}{{ k }},{% endfor %}
+--DATA--
+return array('foo' => 'bar')
+--EXPECT--
+foo,global,_parent,
+global,_parent,
+foo,global,foo1,_parent,
+foo1,global,_parent,
--- /dev/null
+--TEST--
+"include" function accept variables
+--TEMPLATE--
+{{ include("foo.twig", {'foo': 'bar'}) }}
+{{- include("foo.twig", vars) }}
+--TEMPLATE(foo.twig)--
+{{ foo }}
+--DATA--
+return array('vars' => array('foo' => 'bar'))
+--EXPECT--
+bar
+bar