diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php index 21755a5057..b6a2c296b0 100644 --- a/core/lib/Drupal/Core/Template/TwigEnvironment.php +++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php @@ -43,10 +43,6 @@ class TwigEnvironment extends \Twig_Environment { * The options for the Twig environment. */ public function __construct($root, CacheBackendInterface $cache, $twig_extension_hash, StateInterface $state, \Twig_LoaderInterface $loader = NULL, $options = []) { - // Ensure that twig.engine is loaded, given that it is needed to render a - // template because functions like TwigExtension::escapeFilter() are called. - require_once $root . '/core/themes/engines/twig/twig.engine'; - $this->templateClasses = []; $options += [ diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 377efe6dde..60a9bd4c2e 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -177,7 +177,7 @@ public function getFilters() { new \Twig_SimpleFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => TRUE, 'is_safe' => ['html']]), // Array filters. - new \Twig_SimpleFilter('without', 'twig_without'), + new \Twig_SimpleFilter('without', [$this, 'withoutFilter']), // CSS class and ID filters. new \Twig_SimpleFilter('clean_class', '\Drupal\Component\Utility\Html::getClass'), @@ -630,4 +630,37 @@ public function createAttribute(array $attributes = []) { return new Attribute($attributes); } + /** + * Removes child elements from a copy of the original array. + * + * Creates a copy of the renderable array and removes child elements by key + * specified through filter's arguments. The copy can be printed without these + * elements. The original renderable array is still available and can be used + * to print child elements in their entirety in the twig template. + * + * @param array|object $element + * The parent renderable array to exclude the child items. + * @param string[] ... + * The string keys of $element to prevent printing. + * + * @return array + * The filtered renderable array. + */ + public function withoutFilter($element) { + if ($element instanceof \ArrayAccess) { + $filtered_element = clone $element; + } + else { + $filtered_element = $element; + } + $args = func_get_args(); + unset($args[0]); + foreach ($args as $arg) { + if (isset($filtered_element[$arg])) { + unset($filtered_element[$arg]); + } + } + return $filtered_element; + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php index 7af10f5946..5b11298d69 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php @@ -113,6 +113,9 @@ protected function setUp() { * Tests white-listing of methods doesn't interfere with chaining. */ public function testWhiteListChaining() { + // Include the Twig engine so we can call twig_render_template(). + require_once $this->root . '/core/themes/engines/twig/twig.engine'; + $node = Node::create([ 'type' => 'page', 'title' => 'Some node mmk', diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index 177e01a511..48d1717fe3 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -133,20 +133,13 @@ function twig_render_template($template_file, array $variables) { * * @return array * The filtered renderable array. + * + * @deprecated in Drupal 8.5.x and will be removed before 9.0.0. Use + * \Drupal\Core\Template\TwigExtension::withoutFilter() instead. */ function twig_without($element) { - if ($element instanceof ArrayAccess) { - $filtered_element = clone $element; - } - else { - $filtered_element = $element; - } - $args = func_get_args(); - unset($args[0]); - foreach ($args as $arg) { - if (isset($filtered_element[$arg])) { - unset($filtered_element[$arg]); - } - } - return $filtered_element; + /** @var \Drupal\Core\Template\TwigExtension $extension */ + $extension = \Drupal::service('twig.extension'); + + return call_user_func_array([$extension, 'withoutFilter'], func_get_args()); }