I have a component-based system using Paragraphs. I create the markup in Twig (Drupal 8), then pass the values of Paragraph fields to the component's properties. So for a super basic example:

{# card.html.twig #}

<div class="card">
    {% block content %}{% endblock %}
{# paragraph--card.html.twig #}

{% embed "card.html.twig" %}
    {% block content %}
        {{ content.field_content }}
    {% endfor %}
{% endembed %}

Then let's say in my Paragraph Type "Card", I have a field "Content" of type "Text (plain)". Pretty standard stuff.


But, what if I wanted to use another Paragraphs-managed component inside the content block? For example, what if I wanted to put a Button component inside the Card's content, where the button's text and action are determined by a Paragraphs field?

What I've tried

My first thought was to say, okay, if a Card is capable of having a Button, put optional Button fields in the Card Paragraph type, then in Twig, conditionally include the Button component file, and set its properties to the added Card Paragraph fields.

The problem with that...

But for one thing, this isn't very DRY. What if my Button component later changes its API/properties? I'd have to go update the Button Paragraph type, and the Card Paragraph type.

Furthermore, it's just not very flexible. I'm now essentially hardcoding Button support inside my Card component and Paragraph type, when ideally the component system would be flexible to put whatever other component you wanted inside the Card, in any order, without having to fiddle with the Twig files and add new fields to the Card Paragraph type.

To further illustrate the problem...

Another prime example of this functionality would be for a Tabber component. Inside each tab panel, I'd want to give my content editors the option of adding literally anything inside the panel—buttons, forms, cards, media objects, videos, etc.—in any order. How would I go about making this component and Paragraph type such that the content for each panel could use other components and Paragraphs?

What I've researched

I figured that for sure someone would have run into this issue with a Tabs component. From some Googling, apparently not really. Most of the examples of Tab components I've seen only accept plain text or markup for the panel content.

It seems to me I'd have to create a custom module and dig into the PHP side of things. I'd rather not go down this route, and preferably don't want to have to use modules at all if Twig + Paragraphs is powerful enough to do what I want.

Sorry if this is a bit long-winded. Also apologies in advanced if this is something simple and I'm overcomplicating it; I'm fairly new to Drupal.

  • 1
    Just print {{ content.button_field }} and create a separate template for the button component. – user72672 Sep 3 '19 at 22:00
  • Yes, Drupal already provides all the tools needed for this. To help understand, I'd start with one of the default themes, turn on theme debugging and read up about template suggestions. – Alfred Armstrong Sep 4 '19 at 8:36
  • @Jdrupal Thanks for the comment, but I'm not sure I understand. What do you mean by "template" in this context? If you mean a Twig file, I already have (button.twig.html), but the thing is, for reasons I described in "What I've tried" and "The problem with that" sections, I don't want to simply create fields for other components and put them in another component's paragraph type. – Jace Cotton Sep 4 '19 at 15:01
  • @AlfredArmstrong Thanks for the comment! I'm quite familiar with theme debugging and template suggestions, but as for one of the default themes, are there any examples you can think of with specific paragraph types that use other paragraphs as field values? (Or "components within components".) – Jace Cotton Sep 4 '19 at 15:02
  • The standard site building approach is to do the customisation at the field level (plus display settings at the entity level). Entities should generally not need to worry about their fields, just loop through them and delegate their display to their own templates. But I may be missing something about what you are trying to do. – Alfred Armstrong Sep 4 '19 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.