mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-05 06:56:51 +00:00
Merge branch '1.x' into 2.x
* 1.x: exposed a way to access template data and methods in a portable way removed optimization as it's not compatible with Symfony cache system
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
* 1.28.0 (2016-XX-XX)
|
||||
|
||||
* exposed a way to access template data and methods in a portable way
|
||||
* changed context access to use the PHP 7 null coalescing operator when available
|
||||
* added the "with" tag
|
||||
* added support for a custom template on the block() function
|
||||
|
||||
+19
-3
@@ -42,10 +42,18 @@ templates from a database or other resources.
|
||||
the evaluated templates. For such a need, you can use any available PHP
|
||||
cache library.
|
||||
|
||||
To load a template from this environment you just have to call the
|
||||
``loadTemplate()`` method which then returns a ``Twig_Template`` instance::
|
||||
Rendering Templates
|
||||
-------------------
|
||||
|
||||
$template = $twig->loadTemplate('index.html');
|
||||
To load a template from a Twig environment, call the ``load()`` method which
|
||||
returns a ``Twig_TemplateWrapper`` instance::
|
||||
|
||||
$template = $twig->load('index.html');
|
||||
|
||||
.. note::
|
||||
|
||||
Before Twig 1.28, you should use ``loadTemplate()`` instead which returns a
|
||||
``Twig_Template`` instance.
|
||||
|
||||
To render the template with some variables, call the ``render()`` method::
|
||||
|
||||
@@ -59,6 +67,14 @@ You can also load and render the template in one fell swoop::
|
||||
|
||||
echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here'));
|
||||
|
||||
.. versionadded:: 1.28
|
||||
The possibility to render blocks from the API was added in Twig 1.28.
|
||||
|
||||
If a template defines blocks, they can be rendered individually via the
|
||||
``renderBlock()`` call::
|
||||
|
||||
echo $template->renderBlock('block_name', array('the' => 'variables', 'go' => 'here'));
|
||||
|
||||
.. _environment_options:
|
||||
|
||||
Environment Options
|
||||
|
||||
@@ -34,14 +34,18 @@ You can disable access to the context by setting ``with_context`` to
|
||||
{# 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::
|
||||
And if the expression evaluates to a ``Twig_Template`` or a
|
||||
``Twig_TemplateWrapper`` instance, Twig will use it directly::
|
||||
|
||||
// {{ include(template) }}
|
||||
|
||||
// deprecated as of Twig 1.28
|
||||
$template = $twig->loadTemplate('some_template.twig');
|
||||
|
||||
$twig->loadTemplate('template.twig')->display(array('template' => $template));
|
||||
// as of Twig 1.28
|
||||
$template = $twig->load('some_template.twig');
|
||||
|
||||
$twig->display('template.twig', array('template' => $template));
|
||||
|
||||
When you set the ``ignore_missing`` flag, Twig will return an empty string if
|
||||
the template does not exist:
|
||||
|
||||
@@ -153,13 +153,17 @@ Twig supports dynamic inheritance by using a variable as the base template:
|
||||
|
||||
{% extends some_var %}
|
||||
|
||||
If the variable evaluates to a ``Twig_Template`` object, Twig will use it as
|
||||
the parent template::
|
||||
If the variable evaluates to a ``Twig_Template`` or a ``Twig_TemplateWraper``
|
||||
instance, Twig will use it as the parent template::
|
||||
|
||||
// {% extends layout %}
|
||||
|
||||
// deprecated as of Twig 1.28
|
||||
$layout = $twig->loadTemplate('some_layout_template.twig');
|
||||
|
||||
// as of Twig 1.28
|
||||
$layout = $twig->load('some_layout_template.twig');
|
||||
|
||||
$twig->display('template.twig', array('layout' => $layout));
|
||||
|
||||
You can also provide a list of templates that are checked for existence. The
|
||||
|
||||
@@ -50,14 +50,18 @@ The template name can be any valid Twig expression:
|
||||
{% include some_var %}
|
||||
{% include ajax ? 'ajax.html' : 'not_ajax.html' %}
|
||||
|
||||
And if the expression evaluates to a ``Twig_Template`` object, Twig will use it
|
||||
directly::
|
||||
And if the expression evaluates to a ``Twig_Template`` or a
|
||||
``Twig_TemplateWrapper`` instance, Twig will use it directly::
|
||||
|
||||
// {% include template %}
|
||||
|
||||
// deprecated as of Twig 1.28
|
||||
$template = $twig->loadTemplate('some_template.twig');
|
||||
|
||||
$twig->loadTemplate('template.twig')->display(array('template' => $template));
|
||||
// as of Twig 1.28
|
||||
$template = $twig->load('some_template.twig');
|
||||
|
||||
$twig->display('template.twig', array('template' => $template));
|
||||
|
||||
You can mark an include with ``ignore missing`` in which case Twig will ignore
|
||||
the statement if the template to be included does not exist. It has to be
|
||||
|
||||
@@ -304,7 +304,30 @@ class Twig_Environment
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a template by name.
|
||||
* Loads a template.
|
||||
*
|
||||
* @param string|Twig_TemplateWrapper|Twig_Template $name The template name
|
||||
*
|
||||
* @return Twig_TemplateWrapper
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
if ($name instanceof Twig_TemplateWrapper) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if ($name instanceof Twig_Template) {
|
||||
return new Twig_TemplateWrapper($this, $name);
|
||||
}
|
||||
|
||||
return new Twig_TemplateWrapper($this, $this->loadTemplate($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a template internal representation.
|
||||
*
|
||||
* This method is for internal use only and should never be called
|
||||
* directly.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param int $index The index if it is an embedded template
|
||||
@@ -313,6 +336,8 @@ class Twig_Environment
|
||||
*
|
||||
* @throws Twig_Error_Loader When the template cannot be found
|
||||
* @throws Twig_Error_Syntax When an error occurred during compilation
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function loadTemplate($name, $index = null)
|
||||
{
|
||||
|
||||
+31
-11
@@ -13,7 +13,13 @@
|
||||
/**
|
||||
* Default base class for compiled templates.
|
||||
*
|
||||
* This class is an implementation detail of how template compilation currently
|
||||
* works, which might change. It should never be used directly. Use $twig->load()
|
||||
* instead, which returns an instance of Twig_TemplateWrapper.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract class Twig_Template
|
||||
{
|
||||
@@ -270,18 +276,34 @@ abstract class Twig_Template
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all block names.
|
||||
* Returns all block names in the current context of the template.
|
||||
*
|
||||
* This method is for internal use only and should never be called
|
||||
* directly.
|
||||
* This method checks blocks defined in the current template
|
||||
* or defined in "used" traits or defined in parent templates.
|
||||
*
|
||||
* @param string $name The block name
|
||||
* @param array $context The context
|
||||
* @param array $blocks The current set of blocks
|
||||
*
|
||||
* @return array An array of block names
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function getBlockNames()
|
||||
public function getBlockNames(array $context = null, array $blocks = array())
|
||||
{
|
||||
return array_keys($this->blocks);
|
||||
if (null === $context) {
|
||||
@trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED);
|
||||
|
||||
return array_keys($this->blocks);
|
||||
}
|
||||
|
||||
$names = array_merge(array_keys($blocks), array_keys($this->blocks));
|
||||
|
||||
if (false !== $parent = $this->getParent($context)) {
|
||||
$names = array_merge($names, $parent->getBlockNames($context));
|
||||
}
|
||||
|
||||
return array_unique($names);
|
||||
}
|
||||
|
||||
protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
|
||||
@@ -295,6 +317,10 @@ abstract class Twig_Template
|
||||
return $template;
|
||||
}
|
||||
|
||||
if ($template instanceof Twig_TemplateWrapper) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
return $this->env->loadTemplate($template, $index);
|
||||
} catch (Twig_Error $e) {
|
||||
if (!$e->getTemplateName()) {
|
||||
@@ -595,12 +621,6 @@ abstract class Twig_Template
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// useful when calling a template method from a template
|
||||
// this is not supported but unfortunately heavily used in the Symfony profiler
|
||||
if ($object instanceof self) {
|
||||
return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset());
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2016 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exposes a template to userland.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
final class Twig_TemplateWrapper
|
||||
{
|
||||
private $env;
|
||||
private $template;
|
||||
|
||||
/**
|
||||
* This method is for internal use only and should never be called
|
||||
* directly (use Twig_Environment::load() instead).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function __construct(Twig_Environment $env, Twig_Template $template)
|
||||
{
|
||||
$this->env = $env;
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the template.
|
||||
*
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*
|
||||
* @return string The rendered template
|
||||
*/
|
||||
public function render($context = array())
|
||||
{
|
||||
return $this->template->render($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the template.
|
||||
*
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*/
|
||||
public function display($context = array())
|
||||
{
|
||||
return $this->template->display($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a block is defined.
|
||||
*
|
||||
* @param string $name The block name
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBlock($name, $context = array())
|
||||
{
|
||||
return $this->template->hasBlock($name, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns defined block names in the template.
|
||||
*
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*
|
||||
* @return string[] An array of defined template block names
|
||||
*/
|
||||
public function getBlockNames($context = array())
|
||||
{
|
||||
return $this->template->getBlockNames($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a template block.
|
||||
*
|
||||
* @param string $name The block name to render
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*
|
||||
* @return string The rendered block
|
||||
*/
|
||||
public function renderBlock($name, $context = array())
|
||||
{
|
||||
ob_start();
|
||||
$this->displayBlock($name, $context);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a template block.
|
||||
*
|
||||
* @param string $name The block name to render
|
||||
* @param array $context An array of parameters to pass to the template
|
||||
*/
|
||||
public function displayBlock($name, $context = array())
|
||||
{
|
||||
$context = $this->env->mergeGlobals($context);
|
||||
$level = ob_get_level();
|
||||
ob_start();
|
||||
try {
|
||||
$this->template->displayBlock($name, $context);
|
||||
} catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_Source
|
||||
*/
|
||||
public function getSourceContext()
|
||||
{
|
||||
return $this->template->getSourceContext();
|
||||
}
|
||||
}
|
||||
@@ -130,6 +130,7 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider getGetAttributeWithTemplateAsObject
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetAttributeWithTemplateAsObject($useExt)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Tests_TemplateWrapperTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testHasGetBlocks()
|
||||
{
|
||||
$twig = new Twig_Environment(new Twig_Loader_Array(array(
|
||||
'index' => '{% block foo %}{% endblock %}',
|
||||
'index_with_use' => '{% use "imported" %}{% block foo %}{% endblock %}',
|
||||
'index_with_extends' => '{% extends "extended" %}{% block foo %}{% endblock %}',
|
||||
'imported' => '{% block imported %}{% endblock %}',
|
||||
'extended' => '{% block extended %}{% endblock %}',
|
||||
)));
|
||||
|
||||
$wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index'));
|
||||
$this->assertTrue($wrapper->hasBlock('foo'));
|
||||
$this->assertFalse($wrapper->hasBlock('bar'));
|
||||
$this->assertEquals(array('foo'), $wrapper->getBlockNames());
|
||||
|
||||
$wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index_with_use'));
|
||||
$this->assertTrue($wrapper->hasBlock('foo'));
|
||||
$this->assertTrue($wrapper->hasBlock('imported'));
|
||||
$this->assertEquals(array('imported', 'foo'), $wrapper->getBlockNames());
|
||||
|
||||
$wrapper = new Twig_TemplateWrapper($twig, $twig->loadTemplate('index_with_extends'));
|
||||
$this->assertTrue($wrapper->hasBlock('foo'));
|
||||
$this->assertTrue($wrapper->hasBlock('extended'));
|
||||
$this->assertEquals(array('foo', 'extended'), $wrapper->getBlockNames());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user