Skip to content

Commit d4b6489

Browse files
author
Pia-Git
authored
Merge pull request #9 from Paneon/feature/SHODVES2-122
Feature/shodves2 122
2 parents 3c24d23 + 914957d commit d4b6489

12 files changed

+210
-24
lines changed

src/Compiler.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
class Compiler
1616
{
1717

18-
/** @var String[] */
18+
/** @var Component[] */
1919
protected $components;
2020

2121
/** @var DOMDocument */
@@ -40,6 +40,7 @@ public function __construct(DOMDocument $document, LoggerInterface $logger)
4040
$this->document = $document;
4141
$this->logger = $logger;
4242
$this->lastCloseIf = null;
43+
$this->components = [];
4344
$this->banner = [];
4445

4546
$this->logger->debug("\n--------- New Compiler Instance ----------\n");
@@ -100,6 +101,41 @@ public function convertNode(DOMNode $node): DOMNode
100101
break;
101102
}
102103

104+
if (in_array($node->nodeName, array_keys($this->components))) {
105+
$currentComponent = $this->components[$node->nodeName];
106+
$this->handleIf($node);
107+
$this->handleFor($node);
108+
if ($node->hasAttributes()) {
109+
/** @var DOMAttr $attribute */
110+
foreach ($node->attributes as $attribute) {
111+
if (strpos($attribute->name, 'v-bind:') === 0 || strpos($attribute->name, ':') === 0) {
112+
$currentComponent->addProperty($attribute->name, $attribute->value, true);
113+
} else {
114+
$currentComponent->addProperty($attribute->name, $attribute->value, false);
115+
}
116+
}
117+
}
118+
$props = [];
119+
if (count($currentComponent->getProperties()) > 0) {
120+
foreach ($currentComponent->getProperties() as $property) {
121+
if ($property->isBinding()){
122+
$propName = substr($property->getName(), 1); //delete ':'
123+
$props[] = $propName.': '.$property->getValue();
124+
} else {
125+
$props[] = $property->getName().': "'.$property->getValue().'"';
126+
}
127+
}
128+
}
129+
$propsString = '';
130+
if (count($props) > 0) {
131+
$propsString = 'with { '.implode(', ', $props).' } ';
132+
}
133+
$include = $this->document->createTextNode('{% include "'.$currentComponent->getPath().'" '.$propsString.'%}');
134+
$node->parentNode->insertBefore($include, $node);
135+
$node->parentNode->removeChild($node);
136+
return $node;
137+
}
138+
103139
$this->stripEventHandlers($node);
104140
$this->handleFor($node);
105141
//$this->handleRawHtml($node, $data);
@@ -364,6 +400,11 @@ protected function replacePlaceholders(string $string)
364400
return $string;
365401
}
366402

403+
public function registerComponent(string $componentName, string $componentPath)
404+
{
405+
$this->components[strtolower($componentName)] = new Component($componentName, $componentPath);
406+
}
407+
367408
protected function addSingleLineBanner(string $html)
368409
{
369410
return $this->builder->createComment(implode('', $this->banner))."\n".$html;

src/Component.php

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,40 @@
88

99
class Component
1010
{
11-
/** @var string */
12-
protected $assetPath;
13-
14-
/** @var string */
15-
protected $targetPath;
11+
/** @var String[] */
12+
protected $components = [];
13+
/**
14+
* @var string
15+
*/
16+
protected $name;
17+
/**
18+
* @var string
19+
*/
20+
protected $path;
1621

17-
/** @var string */
18-
protected $fileName;
22+
/** @var Property[] */
23+
protected $properties = [];
1924

20-
/** @var DOMDocument */
21-
protected $document;
25+
public function __construct(string $name = '', string $path = '')
26+
{
27+
$this->name = $name;
28+
$this->path = $path;
29+
}
2230

23-
protected $templateHtml;
24-
protected $data;
25-
protected $templateElement;
26-
protected $rootElement;
31+
public function getName(){
32+
return $this->name;
33+
}
2734

28-
/** @var String[] */
29-
protected $components = [];
35+
public function getPath(){
36+
return $this->path;
37+
}
3038

31-
public function __construct(string $assetPath = '', string $targetPath = '')
39+
/**
40+
* @return Property[]
41+
*/
42+
public function getProperties(): array
3243
{
33-
$this->assetPath = $assetPath;
34-
$this->targetPath = $targetPath;
35-
36-
$this->fileName = '';
37-
$this->document = new DOMDocument();
44+
return $this->properties;
3845
}
3946

4047
/**
@@ -55,8 +62,13 @@ public function loadFile(string $fileName): self
5562
return $this;
5663
}
5764

58-
public function registerComponents($name, $path)
65+
public function registerComponents(string $name, string $path)
5966
{
6067
$this->components[$name] = $path;
6168
}
62-
}
69+
70+
public function addProperty(string $name, string $value, bool $isBinding = false) {
71+
$this->properties[] = new Property($name, $value, $isBinding);
72+
}
73+
74+
}

src/Property.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Paneon\VueToTwig;
4+
5+
class Property
6+
{
7+
/**
8+
* @var string
9+
*/
10+
protected $name;
11+
/**
12+
* @var string
13+
*/
14+
protected $value;
15+
/**
16+
* @var bool
17+
*/
18+
protected $isBinding;
19+
20+
public function __construct(string $name, string $value, bool $isBinding)
21+
{
22+
$this->name = $name;
23+
$this->value = $value;
24+
$this->isBinding = $isBinding;
25+
}
26+
27+
/**
28+
* @return string
29+
*/
30+
public function getName(): string
31+
{
32+
return $this->name;
33+
}
34+
35+
/**
36+
* @return string
37+
*/
38+
public function getValue(): string
39+
{
40+
return $this->value;
41+
}
42+
43+
/**
44+
* @return bool
45+
*/
46+
public function isBinding(): bool
47+
{
48+
return $this->isBinding;
49+
}
50+
51+
}

tests/VueComponentTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Paneon\VueToTwig\Tests;
4+
5+
class VueComponentTest extends AbstractTestCase
6+
{
7+
/**
8+
* @dataProvider dataProvider
9+
* @throws \Exception
10+
*/
11+
public function testComponent($html, $expected)
12+
{
13+
$compiler = $this->createCompiler($html);
14+
15+
$compiler->registerComponent('ChildComponent', '/templates/ChildComponent.twig');
16+
17+
$actual = $compiler->convert();
18+
19+
$this->assertEqualHtml($expected, $actual);
20+
}
21+
22+
public function dataProvider()
23+
{
24+
return $this->loadFixturesFromDir('vue-component');
25+
}
26+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
{% include "/templates/ChildComponent.twig" %}
3+
</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<div>
3+
<ChildComponent/>
4+
</div>
5+
</template>
6+
<script>
7+
export default {
8+
name: 'component-with-child.vue',
9+
component: {
10+
ChildComponent,
11+
}
12+
};
13+
</script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
{% for a in listOfProducts %}{% include "/templates/ChildComponent.twig" with { string: "string", product: productA } %}{% endfor %}
3+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<div>
3+
<ChildComponent v-for="a in listOfProducts" string="string" :product="productA" />
4+
</div>
5+
</template>
6+
<script>
7+
export default {
8+
name: 'component-with-for.vue'
9+
};
10+
</script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
{% if a > 5 %}{% include "/templates/ChildComponent.twig" with { string: "string", product: productA } %}{% endif %}
3+
</div>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<div>
3+
<ChildComponent v-if="a > 5" string="string" :product="productA"/>
4+
</div>
5+
</template>
6+
<script>
7+
export default {
8+
name: 'component-with-if.vue'
9+
};
10+
</script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
{% include "/templates/ChildComponent.twig" with { product: testProduct, string: "Test" } %}
3+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div>
3+
<ChildComponent :product="testProduct" string="Test" />
4+
</div>
5+
</template>
6+
7+
<script>
8+
export default {
9+
name: 'ComponentWithPropVue',
10+
};
11+
</script>

0 commit comments

Comments
 (0)