Wanna know my rules when I am writing templates in PatternLab for Drupal view modes such as teasers, cards, search results, etc? Read on, my friend...
BEM Classes for Streamlined Classes
Classes used in the card view mode should be prefixed with card__
not node__
- We need to make sure that CSS for cards does not leak out into other components
- We need to make sure we have as little selector specificity as possible - so we have
.card__content
instead of.card .node__content
in our CSS.
Card Variations
If you want to have slight variations for cards, please add that as an option in the classes
array. Examples of this might be for a card for a specific content type, or a card when there is no image present, or a card that has the image on the left/right.
[ "card", content_type ? "card--" ~ content_type, image ? "card--has-image" : "card--no-image", alignment ? "card--" ~ alignment, ] %}
This will print:
We can then apply overrides using these variations. For example, if the date field on a event is bold
but but on a blog is not, we can have code like so:
.card__date { color: $c-grey--darkest; } .card--event .card__date { font-weight: $fw--bold; }
Avoid Twig Blocks
Try not to use Twig blocks in view modes - {% block image %} If we use Twig blocks, then in the Drupal template anything can be put in the {% block %}
to override it. If we change the order of things in the {% block %}
in PL, this will have no effect in Drupal, since the Drupal version will be overriding it.
For example, the Drupal template could have something like this:
Avoid Drupal Templates
Try to avoid having templates based on specific content types for view modes. This is usually necessary for Full
view mode, but for Teaser
, Card
, etc let's try to keep them more generic.
If you need to use a content-type template, that is fine; but it should be the exception, not the rule.
In general, since each content type Card
should be similar, then each content type should be able to use the same node--card.html.twig
template file.
Avoid {% if not page %}
{% if not page %}
Should not be needed in view modes. A Card
or Teaser
will never be a full page. For the same reason, we can usualy leave this out in the content type full view mode templates, since the full view mode will always be a page.
Do Not Hardcode Heading Levels
Unless you know that the Card
view mode is never going to have a
item above it, do not set
or
etc as the heading element.
We do not want to have a HTML structure like this:
Page Title
Views Card Block Title
Card Title
Card Title
Card Title
Instead, we would like this:
Page Title
Views Card Block Title
Card Title
Card Title
Card Title
In general, view modes will take a
, so let's place that as our default.
Then, in our Drupal template, we can set the element depending on whether it has a parent
or not; for example, if it is in a 'Related Content' building block and that building block has a title such as: Read More Like This
.
Read More Like This
We can do so in the Drupal template with a variation of this:
If the above returns as false, our default h2
from the PL pattern will kick in.
Use Prefixes for Variables
Let's use prefixes for variables, using {{ card_content }}
instead of {{ content }}
. This will help avoid global variables being used by accident in our components (unless we want them to, such as the image_alt
variable from data.json
). The {{ content }}
if used, will not necessarily print the content of your component when that component is used outside of its own context: for example, if you print a card in a views list in a sample page.
Variables for Specific Content Types
If there's a variable for a specific content type, such as the location field for an event card, we can just wrap that in an {% if %}
statement, like so:
Then that variable will not print in any other content type's template.