Unverified Commit d6ee61ea authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3093577 by dww, Krzysztof Domański, lauriii, Charlie ChX Negyesi,...

Issue #3093577 by dww, Krzysztof Domański, lauriii, Charlie ChX Negyesi, Fabianx: Let Twig without() filter take both arrays and strings as arguments

(cherry picked from commit 12dcba25)
parent 9f847ae7
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -651,8 +651,9 @@ public function createAttribute(array $attributes = []) {
   *
   * @param array|object $element
   *   The parent renderable array to exclude the child items.
   * @param string[] ...
   *   The string keys of $element to prevent printing.
   * @param string[]|string ...
   *   The string keys of $element to prevent printing. Arguments can include
   *   string keys directly, or arrays of string keys to hide.
   *
   * @return array
   *   The filtered renderable array.
@@ -666,10 +667,12 @@ public function withoutFilter($element) {
    }
    $args = func_get_args();
    unset($args[0]);
    foreach ($args as $arg) {
      if (isset($filtered_element[$arg])) {
        unset($filtered_element[$arg]);
      }
    // Since the remaining arguments can be a mix of arrays and strings, we use
    // some native PHP iterator classes to allow us to recursively iterate over
    // everything in a single pass.
    $iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($args));
    foreach ($iterator as $key) {
      unset($filtered_element[$key]);
    }
    return $filtered_element;
  }
+5 −0
Original line number Diff line number Diff line
@@ -19,6 +19,11 @@
<div><span {{ attributes.checked }}{{ attributes|without('checked') }}>Without boolean attribute.</span></div>
<div><span data-id="{{ attributes.id }}"{{ attributes|without('id') }}>Without string attribute.</span></div>
<div><span{{ attributes|without('id', 'class') }}>Without id and class attributes.</span></div>
{% set without_args = ['id', 'class'] %}
<div><span{{ attributes|without(without_args) }}>Without id and class attributes via an array.</span></div>
<div><span{{ attributes|without(without_args, 'checked') }}>Without any attributes via mixed array and string.</span></div>
<div><span{{ attributes|without('checked', without_args) }}>Without any attributes via mixed string then array.</span></div>
<div><span{{ attributes|without(without_args, ['id', 'checked']) }}>Without any attributes with duplicate "id" key.</span></div>
<div><span{{ attributes }}>All attributes again.</span></div>
<div id="{{ 'quotes Here!'|clean_id }}"><span class="{{ 'Gray like a bunny!'|clean_class }} {{ 'BEM__ized--Top Feature'|clean_class }}" id="{{ 'quotes Here!'|clean_id }}">ID and class. Having the same ID twice is not valid markup but we want to make sure the filter doesn't use \Drupal\Component\Utility\Html::getUniqueId().</span></div>
<div><strong>Rendered author string length:</strong> {{ quote.author|render|length }}.</div>
+16 −0
Original line number Diff line number Diff line
@@ -102,6 +102,22 @@ public function testTwigWithoutFilter() {
        'expected' => '<div><span checked>Without id and class attributes.</span></div>',
        'message' => 'Attributes printed without id and class attributes.',
      ],
      [
        'expected' => '<div><span checked>Without id and class attributes via an array.</span></div>',
        'message' => 'Attributes printed without an array of things (id and class).',
      ],
      [
        'expected' => '<div><span>Without any attributes via mixed array and string.</span></div>',
        'message' => 'Attributes printed without an array of keys then a string key.',
      ],
      [
        'expected' => '<div><span>Without any attributes via mixed string then array.</span></div>',
        'message' => 'Attributes printed without a string key then an array of keys.',
      ],
      [
        'expected' => '<div><span>Without any attributes with duplicate "id" key.</span></div>',
        'message' => 'Attributes printed without two arrays of keys with a duplicate key present in both arrays.',
      ],
      [
        'expected' => '<div><span id="quotes" checked class="red green blue">All attributes again.</span></div>',
        'message' => 'All attributes printed again.',