Using your new single-directory component
This documentation needs work. See "Help improve this page" in the sidebar.
Figure out the component ID
To use a component you'll need to know the component ID. This is the machine name of the module or theme that provides the component, plus the name of the component itself, separated by a colon. Examples:
{module}:{component}.Example:sdc_example:buttonwhere sdc_example is the module name, and button is the component name.{theme}:{component}.Example:olivero:chipwhere olivero is the theme name, and chip is the component name
Once you know the component ID there are two ways you can make use of it.
Using your component through a render array
SDC comes with its own render element in order to be usable from PHP code. This is the preferred way if you want to keep your theme shareable and agnostic and make Drupal aware of your component usage.
Model:
| Render property | PHP type | Description |
| #component | String | Mandatory. Full component ID: {provider}:{component_id} |
| #variants (since Drupal 11.2+, not supported before) | String | Optional. Name of the variant to use. |
| #slots | Array | Optional. Associative array, keyed by slot ID. Each value is a Drupal renderable. |
| #props | Array | Optional. Associative array, keyed by prop ID. Each value must be valid according to the prop JSON schema. |
| #attributes | Attribute | Drupal 11.3+ Only: Optional. Attribute object, or if associative array, will be converted to an Attribute object. |
Notes:
- "Universal"
#cacheand#attachedrender properties are available.
Most of the time, you will use this render element as the return value of configurable plugins related to display building:
- BlockPluginInterface::build()
- FormatterInterface::viewElements()
- LayoutInterface::build()
- StylePluginBase::render()
- ...
Example:
<?php
return [
'#type' => 'component',
'#component' => 'sdc_examples:my-cta',
'#props' => [
'label' => t('Click Me'),
],
'#slots' => [
'body' => [
'#type' => 'html_tag',
'#tag' => 'span',
'#value' => t('I am a render array in a slot.'),
]
],
];Using your component in Twig template
Twig functions
When using a render element is not possible, you can use your component in an *.html.twig template use Twig’s built in include or embed functions, according to the way you are printing slots in your template:
| Slot in the component template | When called from another template |
|---|---|
{{ label }} |
{{ include('provider:my_component', {label: label}, with_context = false) }} |
{% block label %}{% endblock %} |
{% embed 'provider:my_component' only %} |
{% block label %}{{ label }}{% endblock %} |
Compatible with both include and embed |
Use include():
Use the Twig include() function if there is no data being sent to slots or if you are printing your slots as Twig variables in the component template.
Example of how to include the sdc_examples:my-button component from a Drupal Twig template:
{{ include('sdc_examples:my-button', { text: 'Click Me', iconType: 'external' }, with_context = false) }}You’ll need to provide the component ID ([module/theme name]:[component]) of the component.
with_context = false parameter is optional but recommended to avoid unexpected side-effects.
Read more about include() in the Twig documentation.
Use {% embed %}:
Use a Twig {% embed %} tag only if you are using Twig blocks to manage your slots in the component template.
Example of how to pass in a slot (Twig block) in a card component:
{% embed 'sdc_examples:my-card' with { header: label } only %}
{% block card_body %}
{{ content.field_media_image }}
{{ content|without('field_media_image') }}
{{ include('sdc_examples:my-button', { text: 'Like', iconType: 'like' }, with_context = false) }}
{% endblock %}
{% endembed %}only keyword is optional but recommended to avoid unexpected side-effects.
Read more about embed in the Twig documentation.
About {% include %} tag
This tag is not recommended according to Twig documentation:
It is recommended to use the include function instead as it provides the same features with a bit more flexibility:
- The include function is semantically more "correct" (including a template outputs its rendered contents in the current scope; a tag should not display anything)
- The include function is more "composable"
- The include function does not impose any specific order for arguments thanks to named arguments.
Source: https://twig.symfony.com/doc/3.x/tags/include.html
Slots & props data in a Drupal template
Some templates are providing distinct variables for data expected in slots and props:
In node.html.twig:
contentvariable has the data to send to slotsnodevariable has the data to send to props
In user.html.twig:
contentvariable has the data to send to slotsuservariable has the data to send to props
And so on.
Example with icons from the Core's Icon API, which can be send to both slots and props.
| In component definition | In the presenter template | In the component template |
slots: |
{{ include('my_theme:button', { |
{{ icon }} |
props: |
{{ include('my_theme:button', { |
{{ icon(icon.pack_id, icon.icon_id, icon.settings) }} |
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion