From f7e676fcce1db79546a4c81a681e92ff6887619d Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Fri, 17 Apr 2020 19:22:31 +0200 Subject: [PATCH] Support v-for="(item, index)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds rudimentary support for iterating over a value with the optional second argument for the index. (Because lists and objects are so similar in PHP, this also doubles as support for iterating over an object with the optional second argument for the key; the optional third argument for the index in that case is not supported, though.) Note that, due to the limited JS evaluation in this templating engine, there’s not a whole lot you can do with the index. In the WikibaseLexeme use case, the index is only actually used in a part of the template that’s never server-side rendered; the loop still has to be declared using the index form even for the PHP renderer, though. The unrelated change from v-else="" to v-else in the fixtures was generated by `npm run-script populate-fixtures`, presumably due to a newer Vue.js version now being used – we don’t commit the package-lock.json (yet?). I figured I might as well add it, since one of the fixtures is changed anyways to test the feature. --- src/Component.php | 15 +++++++++++++-- tests/integration/fixture/gloss_widget.html | 6 +++--- tests/integration/fixture/lemma_widget.html | 2 +- tests/php/TemplatingTest.php | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Component.php b/src/Component.php index 6c9443d..8a727e8 100644 --- a/src/Component.php +++ b/src/Component.php @@ -240,10 +240,21 @@ private function handleFor( DOMNode $node, array $data ) { list( $itemName, $listName ) = explode( ' in ', $node->getAttribute( 'v-for' ) ); $node->removeAttribute( 'v-for' ); - foreach ( $data[$listName] as $item ) { + if ( preg_match( '/\((?P[^,]+)\s*,\s*(?P[^\)]+)\)/', $itemName, $matches ) ) { + $itemName = $matches['itemName']; + $keyName = $matches['keyName']; + } else { + $keyName = null; + } + + foreach ( $data[$listName] as $key => $item ) { $newNode = $node->cloneNode( true ); $node->parentNode->insertBefore( $newNode, $node ); - $this->handleNode( $newNode, array_merge( $data, [ $itemName => $item ] ) ); + $newData = array_merge( $data, [ $itemName => $item ] ); + if ( $keyName !== null ) { + $newData[$keyName] = $key; + } + $this->handleNode( $newNode, $newData ); } $this->removeNode( $node ); diff --git a/tests/integration/fixture/gloss_widget.html b/tests/integration/fixture/gloss_widget.html index 6d29613..22a3559 100644 --- a/tests/integration/fixture/gloss_widget.html +++ b/tests/integration/fixture/gloss_widget.html @@ -3,14 +3,14 @@
- + diff --git a/tests/integration/fixture/lemma_widget.html b/tests/integration/fixture/lemma_widget.html index 285a249..fe2346d 100644 --- a/tests/integration/fixture/lemma_widget.html +++ b/tests/integration/fixture/lemma_widget.html @@ -7,7 +7,7 @@ {{lemma.language}} -
+
  • diff --git a/tests/php/TemplatingTest.php b/tests/php/TemplatingTest.php index 0d12618..6244613 100644 --- a/tests/php/TemplatingTest.php +++ b/tests/php/TemplatingTest.php @@ -196,6 +196,24 @@ public function testTemplateWithForLoopMustache_RendersCorrectValues() { assertThat( $result, is( equalTo( '

    12

    ' ) ) ); } + public function testTemplateWithForLoopWithIndex_RendersValuesAndIndices() { + $result = $this->createAndRender( + '

    {{index}}: {{item}}

    ', + [ 'list' => [ 10, 20 ] ] + ); + + assertThat( $result, is( equalTo( '

    0: 101: 20

    ' ) ) ); + } + + public function testTemplateWithForLoopWithKey_RendersValuesAndKeys() { + $result = $this->createAndRender( + '

    {{key}}: {{item}}

    ', + [ 'list' => [ 'ten' => 10, 'twenty' => 20 ] ] + ); + + assertThat( $result, is( equalTo( '

    ten: 10twenty: 20

    ' ) ) ); + } + public function testTemplateWithAttributeBinding_ConditionIsFalse_AttributeIsNotRendered() { $result = $this->createAndRender( '

    ', [ 'condition' => false ] );
{{gloss.language}} - + {{gloss.value}} ({{senseId}}) - +