added an include function

This commit is contained in:
Fabien Potencier
2012-11-15 13:20:44 +01:00
parent 83c7fc6432
commit f4f88a51e2
15 changed files with 257 additions and 9 deletions
+1
View File
@@ -1,5 +1,6 @@
* 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
+80
View File
@@ -0,0 +1,80 @@
``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
+1
View File
@@ -14,3 +14,4 @@ Functions
dump
date
template_from_string
include
+9 -9
View File
@@ -19,23 +19,23 @@ You can add additional variables by passing them after the ``with`` keyword:
.. 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::
@@ -68,9 +68,9 @@ placed just after the template name. Here some valid examples:
.. 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.
+38
View File
@@ -190,6 +190,7 @@ class Twig_Extension_Core extends Twig_Extension
'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)),
);
}
@@ -1216,3 +1217,40 @@ function twig_test_iterable($value)
{
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();
}
}
@@ -0,0 +1,17 @@
--TEST--
"include" function
--TEMPLATE--
FOO
{{ include("foo.twig") }}
BAR
--TEMPLATE(foo.twig)--
FOOBAR
--DATA--
return array()
--EXPECT--
FOO
FOOBAR
BAR
@@ -0,0 +1,17 @@
--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
@@ -0,0 +1,10 @@
--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--
@@ -0,0 +1,8 @@
--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.
@@ -0,0 +1,16 @@
--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.
@@ -0,0 +1,10 @@
--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.
@@ -0,0 +1,10 @@
--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
@@ -0,0 +1,12 @@
--TEST--
"include" function
--TEMPLATE--
{{ include(["foo.twig", "bar.twig"]) }}
{{- include(["bar.twig", "foo.twig"]) }}
--TEMPLATE(foo.twig)--
foo
--DATA--
return array()
--EXPECT--
foo
foo
@@ -0,0 +1,16 @@
--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,
@@ -0,0 +1,12 @@
--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