Skip to content

[Docs] Anonymous twig components #1058

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
Sep 7, 2023

Conversation

mariecharles
Copy link

@mariecharles mariecharles commented Aug 18, 2023

Q A
Bug fix? no
New feature? no
Tickets none
License MIT

Add documentation for the recently added support of anonymous twig components #802

Copy link
Contributor

@WebMamba WebMamba left a comment

Choose a reason for hiding this comment

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

Well done Marie 🎉😁

<twig:Button label="Click Me!" />
</div>

You can also define your component to allow overwriting attributes:
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this PR #1041, this is not true anymore. Now if you defined props in your component {% props label %} the label is not available by the attributes object but only with {{ label }}. The attributes object contains only passed to the object without a defined props

Copy link
Member

Choose a reason for hiding this comment

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

But won't the code below still work after #1041?

  • primary is in {% props so it will NOT be inside attributes but we WILL have a primary varaible
  • Then, we use that primary variable (boolean) to set the class to the string primary or secondary.

Copy link
Contributor

Choose a reason for hiding this comment

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

It was more about the sentence do you think overwritting is the right word to use here, or should we have more detail ?

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

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

Look great - I had just noticed this was missing moments ago when I looked for the docs :)

<twig:Button label="Click Me!" />
</div>

You can also define your component to allow overwriting attributes:
Copy link
Member

Choose a reason for hiding this comment

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

But won't the code below still work after #1041?

  • primary is in {% props so it will NOT be inside attributes but we WILL have a primary varaible
  • Then, we use that primary variable (boolean) to set the class to the string primary or secondary.

-----------------------

Sometimes, reusable elements do not require complex logic or injected service to render what it could be processed
from one template itself. (e.g. retrieving a customized primary button that could take a different label).
Copy link
Member

Choose a reason for hiding this comment

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

How about:

Sometimes a component is simple enough that it doesn't have any complex logic or injected services.
In this case, you can skip the class and only create the template. The component name is determined
by the location of the template (see `Twig Template Namespaces`_):

{% endblock %}
</button>

Then use your component with ``:`` to navigate through the directories:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Then use your component with ``:`` to navigate through the directories:
Then use your component with ``:`` to navigate through sub-directories (if there are any):

</twig:primary>
</div>

Now let's pass props to your button by defining a ``{% props %}`` tag in its view.
Copy link
Member

Choose a reason for hiding this comment

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

I think we should first show passing a normal "attribute" and show how that works very normally (show the {{ attributes }} being printed in the template). Maybe a role attribute, for example.

Then we can show how you can, in addition to an attribute, pass a prop using {% props}.

@weaverryan
Copy link
Member

Related PR is merged - the final tweaks on this are ready to be done :)

@seb-jean
Copy link
Contributor

The closing tag is not good:

</twig:primary>

You should put:

</twig:Button:Primary>

@mariecharles mariecharles force-pushed the doc/anonymous_twig_component branch from b96bc03 to 255def9 Compare August 29, 2023 07:16
@@ -1046,6 +1046,108 @@ And in your component template you can access your embedded block
{% block footer %}{% endblock %}
</div>

Anonymous TwigComponent
Copy link
Member

Choose a reason for hiding this comment

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

Anonymous Components

.. code-block:: html+twig

{# templates/components/Button/Primary.html.twig #}
<button class="primary">
Copy link
Member

Choose a reason for hiding this comment

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

It would be more flexible to immediately how attributes being used:

<button {{ attributes.defaults({ class: 'primary' }) }}>

We don't need to introduce the concept of attributes here, since it's not unique to anonymous components :)

{% endblock %}
</button>

Then pass any further data to your reusable "button" like so:
Copy link
Member

Choose a reason for hiding this comment

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

Like normal, you can pass extra attributes that will be rendered on the element:

{# renders as: #}
<button role="button" class="foo">Click Me!</button>

Now let's pass props to your "button" by defining a ``{% props %}`` tag in its view.
Copy link
Member

Choose a reason for hiding this comment

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

Let's reverse this section: show the usage first, then show the {% props syntax. Something like:

You can also pass a variable (prop) into your template:

<twig:Button role="button" icon="fa-plus" type="primary">Buy now!</twig:Button>

To tell the system that icon and type are props and not attributes, use the {% props tag at the top of your template:

{% props icon, type = 'primary' %}

<button {{ attributes.defaults({
    class: 'btn btn-'~type
} }}>
    {% block content %}{% endblock %}
    {% if icon %}
        <span class="fa-solid fa-{{ icon }}"></span>
    {% endif %}
</button>

I don't love the attributes.defaults() syntax, but it does make the components more flexible.

@mariecharles mariecharles force-pushed the doc/anonymous_twig_component branch from 255def9 to 2e1ea5a Compare September 6, 2023 17:43
@mariecharles
Copy link
Author

Thank you @weaverryan for your help

@weaverryan weaverryan force-pushed the doc/anonymous_twig_component branch from 2e1ea5a to 41f59f1 Compare September 7, 2023 14:51
@weaverryan
Copy link
Member

Gorgeous 😍 - great work Marie!

@weaverryan weaverryan merged commit cc09617 into symfony:2.x Sep 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants