Drupal Libraries
In a Drupal 10 theme, stylesheets (CSS) and JavaScript (JS) are loaded through the same system for modules and themes, for everything: asset libraries.
Drupal uses a high-level principle: assets (CSS or JS) are only loaded if you tell Drupal it should load them. Drupal does not load all assets on every page because it slows down front-end performance.
In the context of component-based theming, we are going to create a library for each individual component we build in Storybook. Each library will have all the CSS and JavaScript (if any), the component needs to render as expected.
NOTE: Drupal libraries are only intended to work in Drupal. The method attach_library is ignored inside of Storybook. In Storybook we use Webpack to generate the CSS and JavaScript for components.
Structure of a library
In your editor, open training_theme.libraries.yml (located in your theme's root). You will notice the global library already declared which includes all of the global theme styles that apply to all pages on the site (i.e. typography, brand colors, global styles, etc.). The global library looks something like this:
global:
css:
# The SMACSS category, "base", is loaded before other categories. Drupal 8/9
# loads stylesheets based on the SMACSS ordering of:
# base, layout, component, state, theme
base:
dist/css/bootstrap.css: {}
dependencies:
- "training_theme/icons"
- "training_theme/fonts"global: This is the library name. When we build component's individual libraries, the library name will always be the name of the component it is for.
css: This is the asset we want to include in the library. Usually
cssand/orjs.base: The ordering category, in this case
base, is loaded before other categories. Drupal 10 loads stylesheets based on the SMACSS ordering:base,layout,component,state, andtheme. All of the components we create will use thecomponentordering. Drupal also groups/aggregates together assets that belong to the same category for performance reasons.dist/css/bootstrap.css: { }: This is the path to the asset relative to the root of the theme. All assets in our theme are compiled into
dist/cssordist/js. A library can have both of these assets. The path can also include multiple lines of assets. Say you are building a library for a component that uses a third party stylesheet, in addition to the path above you could include a new line with the path for the third party stylesheet. Same goes for JS assets.dependencies: Here we can declare any global dependencies we want to load on every page. In this case we want to make custom icons and fonts loaded globally.
Analyzing the 50/50 component
Let's see how our 50/50 component is rendered in Drupal.
In the root of your Drupal theme, open
training_theme.libraries.ymlin your editor (replacetraining_themeif you used a different name for your theme).Somewhere in the file you will find the following definition for our 50/50 teaser:
teaser:
css:
component:
dist/css/teaser.css: {}Libraries are great because Drupal only loads what we need when we need it to avoid having to load assets that our page or component may never use. This helps with the site's performance.
Attaching a library
But when is this library called in Drupal? There are many ways to load a library, but one of the most common ways to do this is through the attach_library method. Let's revisit out teaser.twig template to see how this is done.
In your editor, open
src/patterns/components/teaser/teaser.twigReview the top of the file. Sure enough there is our call to the teaser library:
The attach_library function takes a path parameter which we are declaring by using the theme's namespace (the namespace is registered by the Components Libraries module), then the name of the library we want to attach (i.e. training_theme/teaser).
With the code above, we are telling Drupal that whenever we render the 50/50 teaser component, its library should be attached so the styles for the component can be applied.
Last updated