Skip to content

Commit 2e14522

Browse files
committed
Implement $firstMixin / $firstComponent function
1 parent 1cb7b0e commit 2e14522

3 files changed

Lines changed: 86 additions & 2 deletions

File tree

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,41 @@ Contact us
130130
Footer of Contact page
131131
</footer>
132132
```
133+
134+
### Fallback component
135+
136+
This package also include a function to get the first defined mixin/component
137+
among given names:
138+
139+
```pug
140+
component page
141+
| Page component
142+
143+
+#{$firstComponent('customPage', 'page')}
144+
```
145+
146+
Output:
147+
148+
```html
149+
Page component
150+
```
151+
152+
And if `customPage` component is defined, it will be used instead:
153+
```pug
154+
component page
155+
| Page component
156+
157+
component customPage
158+
| CustomPage component
159+
160+
+#{$firstComponent('customPage', 'page')}
161+
```
162+
163+
Output:
164+
165+
```html
166+
CustomPage component
167+
```
168+
169+
(`$firstComponent` becomes `firstComponent` if you use pug-php or js-phpize)
170+
`$firstMixin` is also available as an alias.

src/Phug/Component/ComponentExtension.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Phug\AbstractPlugin;
77
use Phug\Ast\NodeInterface;
88
use Phug\Compiler\Event\NodeEvent;
9+
use Phug\Compiler\Event\OutputEvent;
910
use Phug\CompilerEvent;
1011
use Phug\Parser\NodeInterface as ParserNodeInterface;
1112
use Phug\Parser\Node\CodeNode;
@@ -113,13 +114,37 @@ public function handleNodeEvent(NodeEvent $event): void
113114
}
114115
}
115116

117+
public function handleOutputEvent(OutputEvent $event): void
118+
{
119+
$event->setOutput(
120+
implode("\n", [
121+
'<?php',
122+
'$firstMixin = function (string ...$names) use (&$__pug_mixins) {',
123+
' foreach ($names as $name) {',
124+
' if (isset($__pug_mixins[$name])) {',
125+
' return $name;',
126+
' }',
127+
' }',
128+
' throw new \\InvalidArgumentException("No defined mixin/component in [".implode(", ", $names)."]");',
129+
'};',
130+
'$firstComponent = $firstMixin;',
131+
'?>',
132+
]).
133+
$event->getOutput()
134+
);
135+
}
136+
116137
public function attachEvents(): void
117138
{
118-
$this->getContainer()->getCompiler()->attach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
139+
$compiler = $this->getCompiler();
140+
$compiler->attach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
141+
$compiler->attach(CompilerEvent::OUTPUT, [$this, 'handleOutputEvent']);
119142
}
120143

121144
public function detachEvents(): void
122145
{
123-
$this->getContainer()->getCompiler()->detach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
146+
$compiler = $this->getCompiler();
147+
$compiler->detach(CompilerEvent::NODE, [$this, 'handleNodeEvent']);
148+
$compiler->detach(CompilerEvent::OUTPUT, [$this, 'handleOutputEvent']);
124149
}
125150
}

tests/Phug/Component/ComponentExtensionTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,27 @@ public function testBasicMixinAreStillFine()
325325
])));
326326
}
327327

328+
/**
329+
* @covers ::handleOutputEvent
330+
*/
331+
public function testFirstMixin()
332+
{
333+
$this->assertSame("<p>5</p>\nHello", $this->renderAndFormat(implode("\n", [
334+
'mixin foo($num)',
335+
' p=$num',
336+
' block',
337+
'+#{$firstMixin("biz", "foo", "bar")}(5)',
338+
' | Hello',
339+
])));
340+
$this->assertSame("<p>5</p>\nHello", $this->renderAndFormat(implode("\n", [
341+
'component foo($num)',
342+
' p=$num',
343+
' block',
344+
'+#{$firstComponent("biz", "foo", "bar")}(5)',
345+
' | Hello',
346+
])));
347+
}
348+
328349
/**
329350
* @covers ::__construct
330351
* @covers ::getOptions

0 commit comments

Comments
 (0)