Can I Stop PatternLab Variants from Inheriting Data from their Parent Component

I have a card component with a title, image, text, and link. How come all my card variants are inheriting all the values from the default one? Short answer, you don't. It's a feature, not a bug.

Where this really becomes frustrating is when you have a pattern that lists a number of items in an array. In that case, all variants will have (at least) that many items, even though you may want fewer.

For illustration:

list.twig has something like this:

 {% for list_item in list_items %} 
  {{ list_item }} 
{% endfor %} 

 

Then list.yml has something like this:

 list_items: 
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
    - include(): pattern: content-teaser
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
-- loads of more teasers for the main listing page 

Now you want to create a variant of list such as list~related-articles, but with only 2 items. You'd expect this would work

 list_items: 
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
    - include(): pattern: content-teaser 

But, no. This will still render as many items as were in the parent component. That's the beauty (a feature, not a bug) of PatternLab's inheritance system. To stop it you need to do something like this:

 list_items: 
  - join(): 
    - include(): pattern: content-teaser 
  - join(): 
    - include(): pattern: content-teaser 
    - - - and so on, so each extra one is basically set to 'false' 

When we do this with a component such as a card, we might also want to have variants such as card~no-image, card~no-text, etc. In this case, we'd have a card.yml like so:

​card_title: 'My Card Title' 
card_image: '' 
card_text: 'The text of the card will go here'
​

However, if we create variants, each of the items in card will be inherited to the variant. You'll notice this if you try to create one super mega component for all variants of a hero component for example (hero title, pre-title, sub-title, image, alignment, cta buttons, etc).

 

In this case, what I do is create a default component card.yml or hero.yml and give it only values for items that will more than likely be in all variants (basically whatever you are going to mark as a required field in Drupal (or whatever CMS you are using)), then set all others to 'false' in the component. Now when I create variants I only need to override the specifics for that variant, since everything else that is being inherited is already set to false. I also create a 'Kitchen Sink' version of the component which shows every item in action but DO NOT create this as the default/reference component.

 

My default card.yml might look like this:

card_title: 'My Card Title' 
card_image: false 
card_text: false 

Now my variants can look as simple as:

card~with-image.yml

​card_image: ''

And card~long-title will be just one line:

 card_title: 'This is a long title on a card just to illustrate what happens when it wraps to more than one line' 

And that is why this is a feature, not a bug - it allows us to write variants very simply and quickly. Is there a better way of doing this? I'm not aware of one. If you are, drop it in the comments. Thanks.

 

Filed Under:

  1. Drupal Planet
  2. PatternLab
  3. Frontend Development