Creating a single-directory component
This documentation needs review. See "Help improve this page" in the sidebar.
A single-directory component meets the following criteria
- It must be within your theme or module’s
components/
directory. Note that it can be nested within subdirectories (for examplecomponents/atoms/
,components/molecules/
, etc) - It must contain the following files (where
my-component
is the name of your component)my-component.component.yml
- this contains the definition of the component including name, status, schema, etcmy-component.twig
- this is the normal Twig file that contains markup as well as logic such as conditionals and loops to interact with the variables defined within the YML. (Note that the filename extension should be.twig
and not.html.twig
, as regularly seen in other theme template files.)
- It may contain other files such as CSS, JavaScript, source files (Sass, etc), images, documentation, etc
Note about creating the schema
Creating a schema within your my-component.component.yml
is mandatory for modules, but optional for themes. However it’s highly recommended to do so. Benefits include:
- Only components that have schemas can override other components.
- Using schemas will illuminate problems with your components earlier.
- Schemas will enable contributed modules (and maybe eventually core) to automatically generate forms to populate the component.
Note you can force all components within your theme to require schemas by adding the following to your themename.info.yml
.
enforce_prop_schemas: true
To create your first single-directory component, follow these steps
- Create a new directory called
components/
in your theme or module’s directory. - Create a new directory within your theme’s
components/
directory with the name of your new component (exmy-component
) . - Create two new files within this directory
- A twig file with the name of your component (ex
my-component.twig
) - A YAML file with the
*.component.yml
extension that is named with your component (exmy-component.component.yml
). View (or copy and paste) the example annotated YAML file to get started.
- A twig file with the name of your component (ex
- For the CSS and JavaScript to automatically load, they must be named after the component (ex.
my-component.css
, andmy-component.js
). - You can load additional styles, scripts, and dependencies using the
libraryOverrides
key within your component’s YML file if necessary.
The final directory structure will look something like this
|- my-theme
|- components
|- my-component
|- my-component.twig (required)
|- my-component.component.yml (required)
|- README.md
|- thumbnail.png
|- my-component.js
|- my-component.css
|- assets
|- img1.png
Component data validation
During development time the data provided to the props can be validated against the schema. This will give developers an early warning that something is off.
For schema to be validated, two conditions must be met:
- The
justinrainbow/json-schema
composer package must be installed. This can easily be installed viadrupal/core-dev
:
composer require drupal/core-dev --dev
- Assertions must be enabled. If assertions are disabled within your local environment, you can add the following to your
settings.php
to enable them:
ini_set('zend.assertions', 1);
Writing the schema for your components is mandatory if the component lives in a module or a theme that contains enforce_prop_schemas: true
in its info file.
Note that enforce_prop_schemas: false
only applies to the absence of a schema definition for the entire component. Even with this setting present, each individual element of the schema will be validated individually.
Overriding components provided by other modules or themes
Only themes can override components (modules cannot override). For a theme to override a component, use the replaces
key within the mytheme.component.yml
file.
In addition, both components must have schemas defined within their YML files, and the schemas’ props and slots must match.
The value of the replaces
key must refer to the other component using the machine name of the module/theme and the machine name of the component, delimited with a colon (:
). In the example below, sdc_theme_test
is the name of the theme that contains the component to be replaced, and my-card
is the machine name of that component.
replaces: 'sdc_theme_test:my-card'
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