Skip to content

Commit 93027de

Browse files
committed
minor #2082 [TwigComponent][Doc] Twig code style & "boolean props" part (smnandre)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [TwigComponent][Doc] Twig code style & "boolean props" part Fix code style in Twig examples (to follow twig & symfony code conventions) Also rewrite/improved the paragraph about "boolean props" * explain how it works and why * increase visibility of the solutions (it's been some time I wanted to rewrite this part, as we often have questions) Commits ------- 8fbcd21 [TwigComponent][Doc] Twig code style & "boolean props" part
2 parents 348d260 + 8fbcd21 commit 93027de

File tree

1 file changed

+59
-52
lines changed

1 file changed

+59
-52
lines changed

src/TwigComponent/doc/index.rst

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Done! Now render it wherever you want:
3232

3333
.. code-block:: html+twig
3434

35-
{{ component('Alert', { message: 'Hello Twig Components!' }) }}
35+
{{ component('Alert', {message: 'Hello Twig Components!'}) }}
3636

3737
<twig:Alert message="Or use the fun HTML syntax!" />
3838

@@ -193,7 +193,7 @@ them as "props" via the a 2nd argument to ``component()``:
193193

194194
.. code-block:: twig
195195
196-
{{ component('Alert', { message: 'Successfully created!' }) }}
196+
{{ component('Alert', {message: 'Successfully created!'}) }}
197197
198198
{{ component('Alert', {
199199
type: 'danger',
@@ -235,7 +235,7 @@ available in every component template:
235235

236236
.. code-block:: html+twig
237237

238-
<div {{ attributes.defaults({ class: 'alert alert-'~ type }) }}>
238+
<div {{ attributes.defaults({class: 'alert alert-' ~ type}) }}>
239239
{{ message }}
240240
</div>
241241

@@ -295,17 +295,22 @@ prefix the attribute with ``:`` or use the normal ``{{ }}`` syntax:
295295
// pass object, array, or anything you imagine
296296
<twig:Alert :foo="{col: ['foo', 'oof']}" />
297297

298-
Boolean props require using the dynamic syntax:
298+
Boolean props are converted using PHP's type juggling rules. The
299+
string ``"false"`` is converted to the boolean ``true``.
300+
301+
To pass the boolean ``false``, you can pass a Twig expression
302+
``{{ false }}`` or use the dynamic syntax (with the ``:`` prefix):
299303

300304
.. code-block:: html+twig
301305

302-
{# in this example, the 'false' value is passed as a string
303-
(so it's converted automatically to the true boolean value) #}
306+
{# ❌ the string 'false' is converted to the boolean 'true' #}
304307
<twig:Alert message="..." withCloseButton="false" />
305308

306-
{# in the following examples, the 'false' value is passed as a boolean property #}
307-
<twig:Alert message="..." :withCloseButton="false" />
309+
{# ✅ use the 'false' boolean value #}
308310
<twig:Alert message="..." withCloseButton="{{ false }}" />
311+
312+
{# ✅ use the dynamic syntax #}
313+
<twig:Alert message="..." :withCloseButton="false" />
309314

310315
Don't forget that you can mix and match props with attributes that you
311316
want to render on the root element:
@@ -319,7 +324,7 @@ This requires Twig 3.7.0 or higher:
319324

320325
.. code-block:: html+twig
321326

322-
<twig:Alert{{ ...myAttributes }} />
327+
<twig:Alert {{ ...myAttributes }} />
323328

324329
We'll use the HTML syntax for the rest of the guide.
325330

@@ -341,7 +346,7 @@ close tag, it's passed to your component template as the block called
341346

342347
.. code-block:: html+twig
343348

344-
<div {{ attributes.defaults({ class: 'alert alert-'~ type }) }}">
349+
<div {{ attributes.defaults({class: 'alert alert-' ~ type}) }}">
345350
{% block content %}{% endblock %}
346351
</div>
347352

@@ -450,7 +455,7 @@ passed to ``mount()``.
450455
.. code-block:: html+twig
451456

452457
<twig:Alert
453-
:isSuccess="false"
458+
isSuccess="{{ false }}"
454459
message="Danger Will Robinson!"
455460
/>
456461

@@ -592,7 +597,7 @@ name is determined by the location of the template:
592597
.. code-block:: html+twig
593598

594599
{# templates/components/Button/Primary.html.twig #}
595-
<button {{ attributes.defaults({ class: 'primary' }) }}>
600+
<button {{ attributes.defaults({class: 'primary'}) }}>
596601
{% block content %}{% endblock %}
597602
</button>
598603

@@ -641,7 +646,7 @@ To tell the system that ``icon`` and ``type`` are props and not attributes, use
641646
{# templates/components/Button.html.twig #}
642647
{% props icon = null, type = 'primary' %}
643648

644-
<button {{ attributes.defaults({ class: 'btn btn-'~type }) }}>
649+
<button {{ attributes.defaults({class: 'btn btn-'~type}) }}>
645650
{% block content %}{% endblock %}
646651
{% if icon %}
647652
<span class="fa-solid fa-{{ icon }}"></span>
@@ -674,6 +679,17 @@ In your component template, this becomes a block named ``content``:
674679

675680
You can also add more, named blocks:
676681

682+
.. code-block:: html+twig
683+
684+
<div class="alert alert-{{ type }}">
685+
{% block content %}{% endblock %}
686+
{% block footer %}
687+
<div>Default Footer content</div>
688+
{% endblock %}
689+
</div>
690+
691+
Render these in the normal way.
692+
677693
.. code-block:: html+twig
678694

679695
<twig:Alert type="success">
@@ -685,17 +701,6 @@ You can also add more, named blocks:
685701
</twig:block>
686702
</twig:Alert>
687703

688-
Render these in the normal way.
689-
690-
.. code-block:: html+twig
691-
692-
<div class="alert alert-{{ type }}">
693-
{% block content %}{% endblock %}
694-
{% block footer %}
695-
<div>Default Footer content</div>
696-
{% endblock %}
697-
</div>
698-
699704
Passing content into your template can also be done with LiveComponents
700705
though there are some caveats to know related to variable scope.
701706
See `Passing Blocks to Live Components`_.
@@ -784,7 +789,7 @@ access to some properties or functions from higher components, that can be done
784789
{# templates/SuccessAlert.html.twig #}
785790
{% set name = 'Fabien' %}
786791
{% set message = 'Hello' %}
787-
{% component Alert with { type: 'success', name: 'Bart' } %}
792+
{% component Alert with {type: 'success', name: 'Bart'} %}
788793
Hello {{ name }} {# Hello Bart #}
789794
790795
{{ message }} {{ outerScope.name }} {# Hello Fabien #}
@@ -802,7 +807,7 @@ Remember though that the ``outerScope`` reference only starts once you're INSIDE
802807
{# templates/FancyProfileCard.html.twig #}
803808
{% component Card %}
804809
{% block header %}
805-
{% component Alert with { message: outerScope.this.someProp } %} {# not yet INSIDE the Alert template #}
810+
{% component Alert with {message: outerScope.this.someProp} %} {# not yet INSIDE the Alert template #}
806811
{% block content %}
807812
{{ message }} {# same value as below, indirectly refers to FancyProfileCard::someProp #}
808813
{{ outerScope.outerScope.this.someProp }} {# directly refers to FancyProfileCard::someProp #}
@@ -818,7 +823,7 @@ Inheritance & Forwarding "Outer Blocks"
818823

819824
The ``outerBlocks`` variable was added in 2.10.
820825

821-
The content inside a ``<twig:{Component}>`` tag should be viewed as living in
826+
The content inside a ``<twig:`` component tag should be viewed as living in
822827
its own, independent template, which *extends* the component's template. This means that
823828
any blocks that live in the "outer" template are not available. However, you
824829
*can* access these via a special ``outerBlocks`` variable:
@@ -831,8 +836,10 @@ any blocks that live in the "outer" template are not available. However, you
831836

832837
{% block body %}
833838
<twig:Alert>
834-
{# block('call_to_action') #} would not work #}
839+
{# this would NOT work... #}
840+
{{ block('call_to_action') }}
835841

842+
{# ...but this works! #}
836843
{{ block(outerBlocks.call_to_action) }}
837844
</twig:Alert>
838845
{% endblock %}
@@ -852,7 +859,7 @@ We already have a generic ``Alert`` component, so let's re-use it:
852859
.. code-block:: html+twig
853860

854861
{# templates/components/Alert.html.twig #}
855-
<div {{ attributes.defaults({ class: 'alert alert-'~ type }) }}">
862+
<div {{ attributes.defaults({class: 'alert alert-'~type}) }}">
856863
{% block content %}{% endblock %}
857864
</div>
858865

@@ -863,7 +870,7 @@ that's passed to it via the ``outerBlocks`` variable and forward it into ``Alert
863870

864871
{# templates/components/SuccessAlert.html.twig #}
865872
<twig:Alert type="success">
866-
{% component Alert with { type: 'success' } %}
873+
{% component Alert with {type: 'success'} %}
867874
{{ block(outerBlocks.content) }}
868875
</twig:Alert>
869876

@@ -884,7 +891,7 @@ component's template:
884891
.. code-block:: html+twig
885892

886893
{# templates/components/MyComponent.html.twig #}
887-
<div{{ attributes }}>
894+
<div {{ attributes }}>
888895
My Component!
889896
</div>
890897

@@ -904,7 +911,7 @@ Set an attribute's value to ``true`` to render just the attribute name:
904911
.. code-block:: html+twig
905912

906913
{# templates/components/Input.html.twig #}
907-
<input{{ attributes }}/>
914+
<input {{ attributes }}/>
908915

909916
{# render component #}
910917
<twig:Input type="text" value="" :autofocus="true" />
@@ -917,7 +924,7 @@ Set an attribute's value to ``false`` to exclude the attribute:
917924
.. code-block:: html+twig
918925

919926
{# templates/components/Input.html.twig #}
920-
<input{{ attributes }}/>
927+
<input {{ attributes }}/>
921928

922929
{# render component #}
923930
<twig:Input type="text" value="" :autofocus="false" />
@@ -929,7 +936,7 @@ To add a custom `Stimulus controller`_ to your root component element:
929936

930937
.. code-block:: html+twig
931938

932-
<div {{ attributes.defaults(stimulus_controller('my-controller', { someValue: 'foo' })) }}>
939+
<div {{ attributes.defaults(stimulus_controller('my-controller', {someValue: 'foo'})) }}>
933940

934941
.. versionadded:: 2.9
935942

@@ -958,16 +965,16 @@ the exception of *class*. For ``class``, the defaults are prepended:
958965
.. code-block:: html+twig
959966

960967
{# templates/components/MyComponent.html.twig #}
961-
<button{{ attributes.defaults({ class: 'bar', type: 'button' }) }}>Save</button>
968+
<button {{ attributes.defaults({class: 'bar', type: 'button'}) }}>Save</button>
962969

963970
{# render component #}
964-
{{ component('MyComponent', { style: 'color:red' }) }}
971+
{{ component('MyComponent', {style: 'color:red'}) }}
965972

966973
{# renders as: #}
967974
<button class="bar" type="button" style="color:red">Save</button>
968975

969976
{# render component #}
970-
{{ component('MyComponent', { class: 'foo', type: 'submit' }) }}
977+
{{ component('MyComponent', {class: 'foo', type: 'submit'}) }}
971978

972979
{# renders as: #}
973980
<button class="bar foo" type="submit">Save</button>
@@ -993,7 +1000,7 @@ You can take full control over the attributes that are rendered by using the
9931000
</div>
9941001

9951002
{# render component #}
996-
{{ component('MyComponent', { style: 'color:red;' }) }}
1003+
{{ component('MyComponent', {style: 'color:red;'}) }}
9971004

9981005
{# renders as: #}
9991006
<div style="color:red; display:block;">
@@ -1018,7 +1025,7 @@ You can take full control over the attributes that are rendered by using the
10181025
</div>
10191026

10201027
{# render component #}
1021-
{{ component('MyComponent', { style: 'color:red;' }) }}
1028+
{{ component('MyComponent', {style: 'color:red;'}) }}
10221029

10231030
{# renders as: #}
10241031
<div style="color:red;" style="color:red; display:block;"> {# style is rendered twice! #}
@@ -1038,7 +1045,7 @@ You can take full control over the attributes that are rendered by using the
10381045
</div>
10391046

10401047
{# render component #}
1041-
{{ component('MyComponent', { style: 'color:red;' }) }}
1048+
{{ component('MyComponent', {style: 'color:red;'}) }}
10421049

10431050
{# renders as: #}
10441051
<div style="display:block;" style="color:red;"> {# style is rendered twice! #}
@@ -1053,10 +1060,10 @@ Extract specific attributes and discard the rest:
10531060
.. code-block:: html+twig
10541061

10551062
{# render component #}
1056-
{{ component('MyComponent', { class: 'foo', style: 'color:red' }) }}
1063+
{{ component('MyComponent', {class: 'foo', style: 'color:red'}) }}
10571064

10581065
{# templates/components/MyComponent.html.twig #}
1059-
<div{{ attributes.only('class') }}>
1066+
<div {{ attributes.only('class') }}>
10601067
My Component!
10611068
</div>
10621069

@@ -1073,10 +1080,10 @@ Exclude specific attributes:
10731080
.. code-block:: html+twig
10741081

10751082
{# render component #}
1076-
{{ component('MyComponent', { class: 'foo', style: 'color:red' }) }}
1083+
{{ component('MyComponent', {class: 'foo', style: 'color:red'}) }}
10771084

10781085
{# templates/components/MyComponent.html.twig #}
1079-
<div{{ attributes.without('class') }}>
1086+
<div {{ attributes.without('class') }}>
10801087
My Component!
10811088
</div>
10821089

@@ -1100,14 +1107,14 @@ and footer. Here's an example of this:
11001107
.. code-block:: html+twig
11011108

11021109
{# templates/components/Dialog.html.twig #}
1103-
<div{{ attributes }}>
1104-
<div{{ attributes.nested('title') }}>
1110+
<div {{ attributes }}>
1111+
<div {{ attributes.nested('title') }}>
11051112
{% block title %}Default Title{% endblock %}
11061113
</div>
1107-
<div{{ attributes.nested('body') }}>
1114+
<div {{ attributes.nested('body') }}>
11081115
{% block content %}{% endblock %}
11091116
</div>
1110-
<div{{ attributes.nested('footer') }}>
1117+
<div {{ attributes.nested('footer') }}>
11111118
{% block footer %}Default Footer{% endblock %}
11121119
</div>
11131120
</div>
@@ -1162,7 +1169,7 @@ function where you define ``base`` classes that should always be present and the
11621169
{% props color = 'blue', size = 'md' %}
11631170

11641171
{% set alert = cva({
1165-
base: 'alert ',
1172+
base: 'alert',
11661173
variants: {
11671174
color: {
11681175
blue: 'bg-blue',
@@ -1222,7 +1229,7 @@ with the ``cva()`` function:
12221229
// ...
12231230
}) %}
12241231

1225-
<div class="{{ alert.apply({color, size}, attributes.render('class')) | tailwind_merge }}">
1232+
<div class="{{ alert.apply({color, size}, attributes.render('class'))|tailwind_merge }}">
12261233
{% block content %}{% endblock %}
12271234
</div>
12281235

@@ -1238,7 +1245,7 @@ when multiple other variant conditions are met.
12381245
{% props color = 'blue', size = 'md' %}
12391246

12401247
{% set alert = cva({
1241-
base: 'alert ',
1248+
base: 'alert',
12421249
variants: {
12431250
color: {
12441251
blue: 'bg-blue',
@@ -1291,7 +1298,7 @@ If no variants match, you can define a default set of classes to apply:
12911298
{% props color = 'blue', size = 'md' %}
12921299

12931300
{% set alert = cva({
1294-
base: 'alert ',
1301+
base: 'alert',
12951302
variants: {
12961303
color: {
12971304
blue: 'bg-blue',

0 commit comments

Comments
 (0)