Skip to content
Snippets Groups Projects
Commit 17766341 authored by Angie Byron's avatar Angie Byron
Browse files

Issue #1873442 by fabpot: Fixed Refactored core Twig integration.

parent 07fe32f5
Branches
Tags
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -15,6 +15,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
......@@ -117,9 +118,8 @@ public function build(ContainerBuilder $container) {
$container->register('user.tempstore', 'Drupal\user\TempStoreFactory')
->addArgument(new Reference('database'))
->addArgument(new Reference('lock'));
$container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
->setFactoryClass('Drupal\Core\Template\TwigFactory')
->setFactoryMethod('get');
$this->registerTwig($container);
// Add the entity query factory.
$container->register('entity.query', 'Drupal\Core\Entity\Query\QueryFactory')
......@@ -249,4 +249,36 @@ public function build(ContainerBuilder $container) {
$container->addCompilerPass(new RegisterAccessChecksPass());
}
/**
* Registers Twig services.
*/
protected function registerTwig(ContainerBuilder $container) {
$container->register('twig.loader.filesystem', 'Twig_Loader_Filesystem')
->addArgument(DRUPAL_ROOT);
$container->setAlias('twig.loader', 'twig.loader.filesystem');
$container->register('twig', 'Drupal\Core\Template\TwigEnvironment')
->addArgument(new Reference('twig.loader'))
->addArgument(array(
// This is saved / loaded via drupal_php_storage().
// All files can be refreshed by clearing caches.
// @todo ensure garbage collection of expired files.
'cache' => TRUE,
'base_template_class' => 'Drupal\Core\Template\TwigTemplate',
// @todo Remove in followup issue
// @see http://drupal.org/node/1712444.
'autoescape' => FALSE,
// @todo Remove in followup issue
// @see http://drupal.org/node/1806538.
'strict_variables' => FALSE,
// @todo Maybe make debug mode dependent on "production mode" setting.
'debug' => TRUE,
// @todo Make auto reload mode dependent on "production mode" setting.
'auto_reload' => FALSE,
))
->addMethodCall('addExtension', array(new Definition('Drupal\Core\Template\TwigExtension')))
// @todo Figure out what to do about debugging functions.
// @see http://drupal.org/node/1804998
->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')));
}
}
<?php
/**
* @file
* Definition of Drupal\Core\Template\TwigExtension.
*
* This provides a Twig extension that registers various Drupal specific extensions to Twig.
*
* @see \Drupal\Core\CoreBundle
*/
namespace Drupal\Core\Template;
/**
* A class for providing Twig extensions (specific Twig_NodeVisitors, filters and functions).
*
* @see \Drupal\Core\CoreBundle
*/
class TwigExtension extends \Twig_Extension {
public function getFunctions() {
// @todo re-add unset => twig_unset if this is really needed
return array(
// @todo Remove URL function once http://drupal.org/node/1778610 is resolved.
'url' => new \Twig_Function_Function('url'),
// These functions will receive a TwigReference object, if a render array is detected
'hide' => new TwigReferenceFunction('twig_hide'),
'render_var' => new TwigReferenceFunction('twig_render_var'),
'show' => new TwigReferenceFunction('twig_show'),
);
}
public function getFilters() {
return array(
't' => new \Twig_Filter_Function('t'),
);
}
public function getNodeVisitors() {
// The node visitor is needed to wrap all variables with
// render_var -> twig_render_var() function.
return array(
new TwigNodeVisitor(),
);
}
public function getTokenParsers() {
return array(
new TwigFunctionTokenParser('hide'),
new TwigFunctionTokenParser('show'),
);
}
public function getName()
{
return 'drupal_core';
}
}
<?php
/**
* @file
* Definition of Drupal\Core\Template\TwigFactory.
*
* This provides a factory class to construct Twig_Environment objects and use
* them in combination with the Drupal Injection Container.
*
* @see \Drupal\Core\CoreBundle
*/
namespace Drupal\Core\Template;
/**
* A class for constructing Twig_Environment objects.
*
* This is used for constructing and configuring a system wide Twig_Environment
* object that is integrated with the Drupal Injection Container.
*
* @see \Drupal\Core\CoreBundle
*/
class TwigFactory {
/**
* Returns a fully initialized Twig_Environment object.
*
* This constructs and configures a Twig_Environment. It also adds Drupal
* specific Twig_NodeVisitors, filters and functions.
*
* To retrieve the system wide Twig_Environment object you should use:
* @code
* $twig = drupal_container()->get('twig');
* @endcode
* This will retrieve the Twig_Environment object from the DIC.
*
* @return Twig_Environment
* The fully initialized Twig_Environment object.
*
* @see twig_render
* @see TwigNodeVisitor
* @see TwigReference
* @see TwigReferenceFunction
*/
public static function get() {
// @todo Maybe we will have our own loader later.
$loader = new \Twig_Loader_Filesystem(DRUPAL_ROOT);
$twig = new TwigEnvironment($loader, array(
// This is saved / loaded via drupal_php_storage().
// All files can be refreshed by clearing caches.
// @todo ensure garbage collection of expired files.
'cache' => TRUE,
'base_template_class' => 'Drupal\Core\Template\TwigTemplate',
// @todo Remove in followup issue
// @see http://drupal.org/node/1712444.
'autoescape' => FALSE,
// @todo Remove in followup issue
// @see http://drupal.org/node/1806538.
'strict_variables' => FALSE,
// @todo Maybe make debug mode dependent on "production mode" setting.
'debug' => TRUE,
// @todo Make auto reload mode dependent on "production mode" setting.
'auto_reload' => FALSE,
));
// The node visitor is needed to wrap all variables with
// render -> twig_render() function.
$twig->addNodeVisitor(new TwigNodeVisitor());
$twig->addTokenParser(new TwigFunctionTokenParser('hide'));
$twig->addTokenParser(new TwigFunctionTokenParser('show'));
// @todo Figure out what to do about debugging functions.
// @see http://drupal.org/node/1804998
$twig->addExtension(new \Twig_Extension_Debug());
$reference_functions = array(
'hide' => 'twig_hide',
'render' => 'twig_render',
'show' => 'twig_show',
// @todo re-add unset => twig_unset if this is really needed
);
$filters = array(
't' => 't'
);
// These functions will receive a TwigReference object, if a render array is detected
foreach ($reference_functions as $function => $php_function) {
$twig->addFunction($function, new TwigReferenceFunction($php_function));
}
foreach ($filters as $filter => $php_function) {
$twig->addFilter($filter, new \Twig_Filter_Function($php_function));
}
// @todo Remove URL function once http://drupal.org/node/1778610 is resolved.
$twig->addFunction('url', new \Twig_Function_Function('url'));
return $twig;
}
}
......@@ -11,8 +11,8 @@
* Provides a Twig_NodeVisitor to change the generated parse-tree.
*
* This is used to ensure that everything that is printed is wrapped via
* twig_render() function so that we can write for example just {{ content }}
* in templates instead of having to write {{ render(content) }}.
* twig_render_var() function so that we can write for example just {{ content }}
* in templates instead of having to write {{ render_var(content) }}.
*
* @see twig_render
*/
......@@ -45,7 +45,7 @@ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
}
}
if ($node instanceof \Twig_Node_Print) {
// Our injected render needs arguments passed by reference -- in case of render array
// Our injected render_var needs arguments passed by reference -- in case of render array
$this->isReference = TRUE;
}
......@@ -55,7 +55,7 @@ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
/**
* Implements Twig_NodeVisitorInterface::leaveNode().
*
* We use this to inject a call to render -> twig_render()
* We use this to inject a call to render_var -> twig_render_var()
* before anything is printed.
*
* @see twig_render
......@@ -66,7 +66,7 @@ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) {
$class = get_class($node);
return new $class(
new \Twig_Node_Expression_Function('render', new \Twig_Node(array($node->getNode('expr'))), $node->getLine()),
new \Twig_Node_Expression_Function('render_var', new \Twig_Node(array($node->getNode('expr'))), $node->getLine()),
$node->getLine()
);
}
......
......@@ -69,7 +69,7 @@ function twig_render_template($template_file, $variables) {
* @see render
* @see TwigNodeVisitor
*/
function twig_render($arg) {
function twig_render_var($arg) {
if ($arg instanceof TwigReference) {
$arg = &$arg->getReference();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment