Skip to content

[Twig] Tweaking docs for new HTML syntax #799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .doctor-rst.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ rules:
no_php_open_tag_in_code_block_php_directive: ~
# no_php_prefix_before_bin_console: ~
# no_php_prefix_before_composer: ~
no_space_before_self_xml_closing_tag: ~
# no_space_before_self_xml_closing_tag: ~
only_backslashes_in_namespace_in_php_code_block: ~
only_backslashes_in_use_statements_in_php_code_block: ~
ordered_use_statements: ~
Expand Down
107 changes: 59 additions & 48 deletions src/TwigComponent/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -778,9 +778,10 @@ child components works. Read `Live Nested Components`_.
Embedded Components
-------------------

.. versionadded:: 2.2
.. tip::

Embedded components were added in TwigComponents 2.2.
Embedded components (i.e. components with blocks) can be written in a more
readable way by using the `Component HTML Syntax`_.

You can write your component's Twig template with blocks that can be overridden
when rendering using the ``{% component %}`` syntax. These blocks can be thought of as
Expand Down Expand Up @@ -840,86 +841,96 @@ The ``with`` data is what's mounted on the component object.
.. note::

Embedded components *cannot* currently be used with LiveComponents.

Component HTML Syntax
---------------------

.. versionadded:: 2.8

This syntax was been introduced in 2.8 and is still experimental: it may change in the future.

Twig Components come with an HTML-like syntax to ease the readability of your template:

.. code-block:: html+twig

<twig:Alert></:Alert>
<twig:Alert></twig:Alert>
// or use a self-closing tag
<twig:Alert/>

You can pass props to your component by using HTML attributes. Suppose you have the following component:
<twig:Alert />

Passing Props as HTML Attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Passing props is done with HTML attributes. For example if you have this component::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Passing props is done with HTML attributes. For example if you have this component::
Passing props is done with HTML attributes. For example if you have this component:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdreesen actually, the double :: is needed. We use RST format instead of Markdown. code blocks are declared as .. code-block:: php. But since we have so many PHP code blocks, it's boring to do that. That's why we use a RST trick to tell it that any code following two :: is to be considered as PHP code.

Copy link
Contributor

@jdreesen jdreesen Apr 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't know that. Thx for the explanation.


#[AsTwigComponent]
class Alert
{
public string $message = '';
public bool $withActions = false;
public string $type = 'success';
}

You can pass the ``message``, ``withActions`` or ``type`` props as attributes:

.. code-block:: html+twig

// "withActions" property will be set to true
<twig:Alert withActions message="hello"></:Alert>
You can add the ':' prefix to your attribute to indicate that the value
should be compiled by Twig
// withActions will be set to true
<twig:Alert type="info" message="hello!" withActions />

To pass in a dynamic value, prefix the attribute with ``:`` or use the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just asking ... is this convention based on the : prefix imposed somehow to us? Otherwise, it looks strange to introduce this new convention when we all know and use the {{ ... }} to output the value of variables or expressions. Thanks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's borrowed from Vue, and also is used Blade Components. I agree that it feels like an "extra" thing, but it's also a very common syntax to see.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you can still use the {{ ... }}, the : is just a small shortcut.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so this is a very common syntax outside of Symfony. Then, it makes sense to have it too. Thanks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I found that it is more or less "needed" when you want to pass non-string values - like booleans or arrays:

<twig:Alert :showClose="false" :messages="['hello', 'world']" />

normal ``{{ }}`` syntax:

.. code-block:: html+twig
<twig:Alert message="hello" :user="user.id"/>

<twig:Alert message="hello!" :user="user.id" />

// equal to
<twig:Alert message="hello" user="{{ user.id }}"/>
<twig:Alert message="hello!" user="{{ user.id }}" />

// and pass object, or table, or anything you imagine
<twig:Alert :foo="['col' => ['foo', 'oof']]"/>

You can pass content directly inside your component.
<twig:Alert :foo="['col' => ['foo', 'oof']]" />

Passing Blocks to your Component
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can also pass content directly to your component:

.. code-block:: html+twig

<twig:Alert>
// any content you want
<div>
...
</div>
<twig:Alert type="success">
<div>Congratulations! You've won a free puppy!</div>
</twig:Alert>
Then in your component template, This becomes a block called content:

In your component template, this becomes a block named ``content``:

.. code-block:: html+twig

<div class="content">
{% block content %}
// and the content will appear in here
{% endblock %}
{% block footer %}
...
{% block footer %}
</div>

<div class="alert alert-{{ type }}">
{% block content %}
// the content will appear in here
{% endblock %}
</div>

In addition to the default block, you can also add named blocks:

.. code-block:: html+twig

<twig:Alert message="hello" :user="user.id">

<twig:Alert type="success">
<div>Congrats on winning a free puppy!</div>

<twig:block name="footer">
...
<button class="btn btn-primary">Claim your prize</button>
</twig:block>
</twig:Alert>

And in your component template you can access your embedded block

.. code-block:: html+twig

<div class="content">
{% block footer %}
...
{% block footer %}

<div class="alert alert-{{ type }}">
{% block content %}{% endblock %}
{% block footer %}{% endblock %}
</div>


Contributing
------------
Expand Down