Drupal 8 Architecture: How to Get a Value from a Paragraph's Parent Entity
A common architectural model in Drupal is for one entity to reference another. For example, when using the Paragraphs module to build structured modular content, imagine that you have a paragraph type that references another paragraph type. The use case for this might be to build something like a grid of cards, an image gallery, or a carousel. The parent or "referencing paragraph" points to another paragraph type that contains an image, text, and title. Thus, the referencing paragraph is a container of multiple, similar sets of child entities that can be re-purposed in different manners depending on a setting in the referencing paragraph.
Use case
With this type of referenced entity paradigm, one can create a custom theme hook according to a setting in the referencing paragraph such as a select list with a set of "style options." In this way, we can theme with custom templates, HTML, and CSS depending on the style selection.
Getting started
The diagram below outlines our design pattern. In this, we see that the referencing paragraph has a select list, "Choose a Style" to select how the referenced entities will appear. The we see a visualization of "Cards" as one possible option.
Essentially you would create a regular paragraph type with an image and a textarea, "Image & Text." Then, create another paragraph type, "Image & Text Reference" that points to Image & Text. This is visualized below.
Once that's all setup, add content and ensure that your local Drupal environment is setup for theming and development. I like to use Docksal for my local setup which makes it easy to get up and running with Xdebug. In addition, you'll want Twig debugging enabled in your local settings files. See the resources section below for more information.
Debugging with Twig & Xdebug
Now that we've added some content, we can start to debug. Inspecting the elements in Chrome, we see that our theme hook is named paragraph
.
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'paragraph' -->
<!-- FILE NAME SUGGESTIONS:
* paragraph--image-text--default.html.twig
* paragraph--image-text.html.twig
* paragraph--default.html.twig
x paragraph.html.twig
-->
From the above information, we can leverage template_preprocess_paragraph
for further debugging using Xdebug. In the case of creating a custom theme hook, we can use the Drupal 8 API's function hook_theme_suggestions_HOOK_alter
where 'HOOK" is the discovered theme hook above; "paragraph
." In this way, we can use theme_suggestions_paragraph_alter
.
Using Paragraph's API function, getParentEntity()
, we can run Xdebug in the referenced paragraph bundle and evaluate the expression, $paragraph->getParentEntity()
. This "reaches" up to any values you'd like to retrieve from the referencing paragraph bundle and can make them available in the referenced paragraph bundle.
From the above, we see the value that's been set on our select list, "Choose a Style." Now we can leverage that as we like in our referenced paragraph theme hook.
if ($bundle === 'image_text') {
// We evaluate the expression in Xdebug.
// And from that, we set a variable and derive the value. ($host_value).
$host_value = $paragraph->getParentEntity()->field_style->value;
$suggestions[] = 'paragraph__' . $paragraph->bundle() . '__' . $view_mode . '__' . $host_value;
$suggestions[] = 'paragraph__' . $paragraph->bundle() . '__' . $host_value;
}
New theme suggestions
Once again, viewing Twig debug, we now have awesome new theme suggestions available.
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'paragraph' -->
<!-- FILE NAME SUGGESTIONS:
* paragraph--image-text--gallery.html.twig
* paragraph--image-text--default--gallery.html.twig
* paragraph--image-text--default.html.twig
* paragraph--image-text.html.twig
* paragraph--default.html.twig
x paragraph.html.twig
-->
Note the presence of:
* paragraph--image-text--gallery.html.twig
* paragraph--image-text--default--gallery.html.twig
These two new theme suggestions derive from the $host_value
we had set in theme hook definition and creation.
Summary
This is really just the tip of the iceberg of what can be accomplished using getParentEntity()
within paragraphs but it should come in really handy.
I'd also add that I've recently become a huge fan of Xdebug in combination with PHPStorm and it massively speeds up development and debugging. I used to use Kint, but no more, it was just too slow. It's really worth the time and effort to get up and running with Xdebug.
In addition, I started learning to use Adobe XD for the architectural diagram above. XD is an awesome free tool from Adobe that's very similar to the Sketch app.