Skip to content

Commit 68d5cf3

Browse files
committed
Implement v-for
1 parent 57b8b7d commit 68d5cf3

File tree

5 files changed

+130
-20
lines changed

5 files changed

+130
-20
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,28 @@
44

55
Compile vue files to twig templates with PHP
66

7+
## Directives
8+
9+
|Directive|Implemented|
10+
|---------|:---------:|
11+
|v-text||
12+
|v-html||
13+
|v-show|:white_check_mark:|
14+
|v-if|:white_check_mark:|
15+
|v-else|:white_check_mark:|
16+
|v-else-if|:white_check_mark:|
17+
|v-for|:white_check_mark:|
18+
|v-on|:white_check_mark:|
19+
|v-bind||
20+
|v-model||
21+
|v-pre||
22+
|v-cloak||
23+
|v-once||
24+
25+
## Other Functionalities
26+
27+
|Functionality|Implemented|
28+
|:------------|:---------:|
29+
|Slots||
30+
|Components||
31+
|Filters||

src/Compiler.php

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ public function convertNode(DOMNode $node): DOMNode
6666
// }
6767

6868
$this->stripEventHandlers($node);
69-
//$this->handleFor($node);
69+
$this->handleFor($node);
7070
//$this->handleRawHtml($node, $data);
7171

72-
//$this->handleAttributeBinding($node);
72+
$this->handleAttributeBinding($node);
7373

7474
foreach (iterator_to_array($node->childNodes) as $childNode) {
7575
$this->convertNode($childNode);
@@ -92,13 +92,16 @@ private function handleAttributeBinding(DOMElement $node)
9292
{
9393
/** @var DOMAttr $attribute */
9494
foreach (iterator_to_array($node->attributes) as $attribute) {
95-
dump($attribute->name);
95+
9696
if (strpos($attribute->name, 'v-bind:') !== 0 && strpos($attribute->name, ':') !== 0) {
97-
dump("- skip");
97+
var_dump("- skip: ". $attribute->name);
9898
continue;
9999
}
100100

101101
$name = substr($attribute->name, 1);
102+
$value = $attribute->value;
103+
var_dump('- handle: '.$name.' = '.$value);
104+
102105
if (is_bool($value)) {
103106
if ($value) {
104107
$node->setAttribute($name, $name);
@@ -180,29 +183,45 @@ private function handleIf(DOMElement $node): void
180183
}
181184
}
182185

183-
private function handleFor(DOMNode $node)
186+
private function handleFor(DOMElement $node)
184187
{
185-
if ($this->isTextNode($node)) {
186-
return;
187-
}
188-
189188
/** @var DOMElement $node */
190189
if (!$node->hasAttribute('v-for')) {
191190
return;
192191
}
193192

194-
[$itemName, $listName] = explode(' in ', $node->getAttribute('v-for'));
195-
196-
// Start For
197-
if (strpos($itemName, ',') !== false) {
198-
[$keyName, $itemName] = explode(',', $itemName);
199-
$keyName = trim($keyName, ' (');
200-
$itemName = trim($itemName, ') ');
201-
$startFor = $this->document->createTextNode('{% for ' . $itemName . ' in ' . $listName . ' %}' .
202-
'{% set ' . $keyName . ' = index0 %}');
203-
} else {
204-
$startFor = $this->document->createTextNode('{% for ' . $itemName . ' in ' . $listName . ' %}');
193+
[$forLeft, $listName] = explode(' in ', $node->getAttribute('v-for'));
194+
195+
/*
196+
* Variations:
197+
* (1) item in array
198+
* (2) key, item in array
199+
* (3) key, item, index in object
200+
*/
201+
202+
// (1)
203+
$forCommand = '{% for ' . $forLeft . ' in ' . $listName . ' %}';
204+
205+
if (strpos($forLeft, ',')) {
206+
$forLeft = str_replace('(', '', $forLeft);
207+
$forLeft = str_replace(')', '', $forLeft);
208+
209+
$forLeftArray = explode(',', $forLeft);
210+
211+
$forValue = $forLeftArray[0];
212+
$forKey = $forLeftArray[1];
213+
$forIndex = $forLeftArray[2] ?? null;
214+
215+
// (2)
216+
$forCommand = '{% for ' . $forKey . ', ' . $forValue . ' in ' . $listName . ' %}';
217+
218+
if ($forIndex) {
219+
// (3)
220+
$forCommand .= ' {% set ' . $forIndex . ' = loop.index0 %}';
221+
}
205222
}
223+
224+
$startFor = $this->document->createTextNode($forCommand);
206225
$node->parentNode->insertBefore($startFor, $node);
207226

208227
// End For

tests/VueForTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Macavity\VueToTwig\Tests;
4+
5+
use Macavity\VueToTwig\Compiler;
6+
7+
class VueForTest extends AbstractTestCase
8+
{
9+
/**
10+
* @dataProvider dataProvider
11+
* @throws \Exception
12+
*/
13+
public function testFor($html, $expected)
14+
{
15+
$document = $this->createDocumentWithHtml($html);
16+
$compiler = new Compiler($document);
17+
18+
$actual = $compiler->convert();
19+
20+
$this->assertEqualHtml($expected, $actual);
21+
}
22+
23+
public function dataProvider()
24+
{
25+
return $this->loadFixturesFromDir('vue-for');
26+
}
27+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<div>
2+
{% for item in items %}
3+
<div>
4+
{{ item.text }}
5+
</div>
6+
{% endfor %}
7+
{% for key, item in items %}
8+
<div>A</div>
9+
{% endfor %}
10+
{% for key, val in object %}
11+
<div>B</div>
12+
{% endfor %}
13+
{% for key, val in object %}
14+
{% set index = loop.index0 %}
15+
<div>C</div>
16+
{% endfor %}
17+
<div>
18+
{% for item in items %}
19+
<div>
20+
{{ item.text }}
21+
</div>
22+
{% endfor %}
23+
</div>
24+
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<div>
3+
<div v-for="item in items">
4+
{{ item.text }}
5+
</div>
6+
<div v-for="(item, key) in items">A</div>
7+
<div v-for="(val, key) in object">B</div>
8+
<div v-for="(val, key, index) in object">C</div>
9+
<div>
10+
<div v-for="item in items" :key="item.id">
11+
{{ item.text }}
12+
</div>
13+
</div>
14+
</div>
15+
</template>

0 commit comments

Comments
 (0)