Issue #2591515 by joelpittet, Cottser, lauriii, NickWilde, kostyashupenko, alexpott, xjm: Move twig_without() to the TwigExtension where all the other filters are and deprecate

8.7.x
Alex Pott 2019-01-22 12:46:01 +00:00
parent 5fbbbde83d
commit 9dfb602168
No known key found for this signature in database
GPG Key ID: 31905460D4A69276
4 changed files with 79 additions and 15 deletions

View File

@ -60,6 +60,7 @@ class TwigEnvironment extends \Twig_Environment {
// Ensure that twig.engine is loaded, given that it is needed to render a
// template because functions like TwigExtension::escapeFilter() are called.
// @todo remove in Drupal 9.0.0 https://www.drupal.org/node/3011393.
require_once $root . '/core/themes/engines/twig/twig.engine';
$this->templateClasses = [];

View File

@ -177,7 +177,7 @@ class TwigExtension extends \Twig_Extension {
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'),
@ -641,4 +641,37 @@ class TwigExtension extends \Twig_Extension {
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;
}
}

View File

@ -2,6 +2,7 @@
namespace Drupal\Tests\system\Kernel\Theme;
use Drupal\Core\Extension\Extension;
use Drupal\KernelTests\KernelTestBase;
/**
@ -120,4 +121,39 @@ class TwigFilterTest extends KernelTestBase {
}
}
/**
* Test "twig_without" filter function.
*
* @expectedDeprecation twig_without() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Template\TwigExtension::withoutFilter(). See https://www.drupal.org/node/3011154.
* @group legacy
*/
public function testLegacyTwigWithoutFunction() {
// Load the twig engine to ensure twig_without() exists.
$twig_engine = new Extension($this->root, 'theme_engine', 'core/themes/engines/twig/twig.info.yml', 'twig.engine');
$twig_engine->load();
$filter_test = [
'red' => '#F00',
'green' => '#0F0',
'blue' => '#00F',
];
// Filter out red key.
$result_without_red = twig_without($filter_test, 'red');
$expected_without_red = $filter_test;
unset($expected_without_red['red']);
$this->assertSame($expected_without_red, $result_without_red);
// Filter nothing and check the array is unaltered.
$result_unaltered = twig_without($filter_test);
$this->assertSame($filter_test, $result_unaltered);
// Filter out blue and green.
$result_without_blue_green = twig_without($filter_test, 'blue', 'green');
$expected_without_blue_green = $filter_test;
unset($expected_without_blue_green['blue']);
unset($expected_without_blue_green['green']);
$this->assertSame($expected_without_blue_green, $result_without_blue_green);
}
}

View File

@ -133,20 +133,14 @@ function twig_render_template($template_file, array $variables) {
*
* @return array
* The filtered renderable array.
*
* @deprecated in Drupal 8.7.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;
@trigger_error('twig_without() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Template\TwigExtension::withoutFilter(). See https://www.drupal.org/node/3011154.', E_USER_DEPRECATED);
/** @var \Drupal\Core\Template\TwigExtension $extension */
$extension = \Drupal::service('twig.extension');
return call_user_func_array([$extension, 'withoutFilter'], func_get_args());
}