Skip to content

Commit 2e4418c

Browse files
committed
Add twig example
1 parent 00525d8 commit 2e4418c

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

Writerside/boson.tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
<toc-element topic="psr7-adapter.md"
6060
toc-title="Other PSR-7 frameworks" />
6161
</toc-element>
62+
<toc-element toc-title="Examples">
63+
<toc-element topic="twig-components.md" />
64+
</toc-element>
6265
<toc-element topic="contribution.md" />
6366
<toc-element topic="license.md" />
6467

3.34 KB
Loading
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Twig Components
2+
3+
You can use Twig in [your Web Components](web-components-api.md). To do this,
4+
you need to follow a few simple steps.
5+
6+
<procedure title="1. Install Twig">
7+
First, you need to install <a href="https://twig.symfony.com/">the Twig</a>
8+
itself <a href="https://getcomposer.org/">using Composer</a>.
9+
<code-block lang="bash">
10+
composer require twig/twig
11+
</code-block>
12+
</procedure>
13+
14+
<procedure title="2. Create Twig Component">
15+
After that, you should create a component that supports twig rendering.
16+
<code-block lang="php">
17+
<![CDATA[
18+
use Boson\WebView\Api\WebComponents\ReactiveContext;
19+
use Boson\WebView\Api\WebComponents\WebComponent;
20+
use Boson\WebView\WebView;
21+
use Twig\Environment;
22+
use Twig\TemplateWrapper;
23+
24+
abstract class TwigComponent extends WebComponent
25+
{
26+
/**
27+
* In this case, the template will be initialized
28+
* once during the first render.
29+
*/
30+
private TemplateWrapper $template {
31+
get => $this->template ??= $this->twig->createTemplate(
32+
template: $this->renderTwig(),
33+
);
34+
}
35+
36+
public function __construct(
37+
protected readonly Environment $twig,
38+
ReactiveContext $ctx,
39+
WebView $webview,
40+
) {
41+
parent::__construct($ctx, $webview);
42+
}
43+
44+
abstract protected function renderTwig(): string;
45+
46+
/**
47+
* Override the default render behavior by
48+
* redirecting it to a Twig template
49+
*/
50+
#[\Override]
51+
final public function render(): string
52+
{
53+
return $this->template->render(\get_object_vars($this));
54+
}
55+
}
56+
]]>
57+
</code-block>
58+
</procedure>
59+
60+
61+
<procedure title="3. Create Instances">
62+
Now we need to define how exactly these components will be created, for
63+
this we should create our own instantiator, which will return new
64+
components on demand.
65+
<code-block lang="php">
66+
<![CDATA[
67+
68+
use Boson\WebView\Api\WebComponents\Instantiator\WebComponentInstantiatorInterface;
69+
use Boson\WebView\Api\WebComponents\ReactiveContext;
70+
use Boson\WebView\WebView;
71+
use Twig\Environment;
72+
use Twig\Loader\ArrayLoader;
73+
74+
final readonly class TwigComponentInstantiator implements
75+
WebComponentInstantiatorInterface
76+
{
77+
private Environment $twig;
78+
79+
public function __construct()
80+
{
81+
$this->twig = new Environment(new ArrayLoader());
82+
}
83+
84+
private function isTwigComponent(string $component): bool
85+
{
86+
return \is_subclass_of($component, TwigComponent::class);
87+
}
88+
89+
public function create(WebView $webview, ReactiveContext $context): object
90+
{
91+
$component = $context->component;
92+
93+
// Pass twig as a first argument in case of passed
94+
// component extends from TwigComponent class
95+
if ($this->isTwigComponent($component)) {
96+
return new $component($this->twig, $context, $webview);
97+
}
98+
99+
return new $component($context, $webview);
100+
}
101+
}
102+
]]>
103+
</code-block>
104+
</procedure>
105+
106+
<procedure title="4. Register Instantiator">
107+
To determine that a different instantiator should be used, it can
108+
be specified in the webview configs.
109+
110+
<code-block lang="php">
111+
<![CDATA[
112+
$webComponentsConfig = new WebComponentsCreateInfo(
113+
instantiator: new TwigComponentInstantiator(),
114+
);
115+
116+
$applicationConfig = new ApplicationCreateInfo(
117+
window: new WindowCreateInfo(
118+
webview: new WebViewCreateInfo(
119+
webComponents: $webComponentsConfig,
120+
),
121+
),
122+
);
123+
124+
$app = new Boson\Application($applicationConfig);
125+
]]>
126+
</code-block>
127+
</procedure>
128+
129+
<procedure title="5. Twig Components">
130+
And now we can create custom twig components!
131+
132+
<code-block lang="php">
133+
<![CDATA[
134+
class MyTwigComponent extends TwigComponent
135+
{
136+
protected array $items = [1, 2, 3];
137+
138+
protected function renderTwig(): string
139+
{
140+
return <<<'twig'
141+
<ul>
142+
{% for item in items %}
143+
<li>{{ item }}</li>
144+
{% endfor %}
145+
</ul>
146+
twig;
147+
}
148+
}
149+
]]>
150+
</code-block>
151+
152+
To register and check, just write a couple of lines
153+
154+
<code-block lang="php">
155+
<![CDATA[
156+
$app->webview->defineComponent('my-list', MyTwigComponent::class);
157+
158+
$app->webview->html = '<my-list />';
159+
]]>
160+
</code-block>
161+
162+
<img src="example-twig-components-result.png" alt="Example Result"/>
163+
164+
</procedure>

0 commit comments

Comments
 (0)