From 17766341f8fa605c2342fea34fbe1d938dfaf605 Mon Sep 17 00:00:00 2001
From: webchick <webchick@24967.no-reply.drupal.org>
Date: Sat, 29 Dec 2012 00:54:13 -0800
Subject: [PATCH] Issue #1873442 by fabpot: Fixed Refactored core Twig
 integration.

---
 core/lib/Drupal/Core/CoreBundle.php           | 38 ++++++-
 .../Drupal/Core/Template/TwigExtension.php    | 58 +++++++++++
 core/lib/Drupal/Core/Template/TwigFactory.php | 98 -------------------
 .../Drupal/Core/Template/TwigNodeVisitor.php  | 10 +-
 core/themes/engines/twig/twig.engine          |  2 +-
 5 files changed, 99 insertions(+), 107 deletions(-)
 create mode 100644 core/lib/Drupal/Core/Template/TwigExtension.php
 delete mode 100644 core/lib/Drupal/Core/Template/TwigFactory.php

diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 3f91b32ae8d1..691e6e744380 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -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')));
+  }
 }
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
new file mode 100644
index 000000000000..898fdf8280b6
--- /dev/null
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -0,0 +1,58 @@
+<?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';
+  }
+}
+
diff --git a/core/lib/Drupal/Core/Template/TwigFactory.php b/core/lib/Drupal/Core/Template/TwigFactory.php
deleted file mode 100644
index ef1a40d83028..000000000000
--- a/core/lib/Drupal/Core/Template/TwigFactory.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?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;
-  }
-}
diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
index 0cf54655f545..710faa074a7c 100644
--- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
+++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
@@ -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()
       );
     }
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index e7de4cf9e8a3..e496bc9e294d 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -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();
   }
-- 
GitLab