Illustration of silhouette at podium with speech bubbles containing panels
In my last blog post I explained what the Panels Suite is and does. I explained how Panels itself is a User Interface on top of
theme(). That technical explanation of Panels underlines what I think is its main conceptual virtue:
Panels encourages a mental model of pulling data into a specific design component
At Palantir we're working with Design Components that are created in static prototypes. Design Components are the reusable pieces of front-end code that compose a design system. Design Components should not know about Drupal's internal implementation details. We're not alone in this thinking. (Inside the Drupal community, and outside of it).
The task of "theming a node" is now "print this node so that it renders as this design component." Unfortunately Drupal core does not have
hook_design_component(); It has
hook_theme(). Some of the entries in
hook_theme() from core are essentially design components.
'table' are design components. They are conceptually based around their HTML rendering. They make sense independent of Drupal. To use them as a Drupal Developer you need to get your data organized before you call
theme() (directly or otherwise).
On the other hand, much of the Drupal core usage of
hook_theme() is not at all design component minded.
'comment' all have entries in
hook_theme(). In these elements you don't have to organize your data before calling
theme(). You can give
theme() a node object and after that
template_preprocesss_node() has to do a ton of work before hitting the template.
It's no coincidence that the design component-ish
hook_theme() entries have minimal preprocessing or no preprocessing whatsoever. The design component-ish entries like
‘item_list' know what the HTML will look like but have no idea what your data is other than you were able to get it into a list. The non-design component entries like node know exactly what the Drupal-meaning of the data is but know very little about the markup they will produce on most production sites.
Panels unites the two mindsets. It knows what the incoming data is (A node context, a user context, etc) and it knows what design component it will print as (the layout plugins.) If you put a debug statement inside of
panels_theme() you will see the names of layouts and style plugins. These
hook_theme() entries are more of the design components-ish
hook_theme() entries. They know what their markup will be. And the part of Panels most people pay attention to, the drag-and-drop interface, is where you control how the data of a node is going to prepare itself for the design component.
And here is where the admin UI of Panels might set up a confusing mental model.
How it looks in the Panels admin UI
But at execution time it is
Or the way I think of it
Drupal Data → transforming Drupal data into printable variables → design components for those variables to print in
The next time I get into a discussion about Panels at a meetup, DrupalCamp, or DrupalCon, I think I'll first ask, "Does Panels let you think about building websites the way you want to think about building websites?" I like to think about passing variables into encapsulated configuration associated with a specific design component. I prefer that mental model to the "show and hide based on globals" mental model of Core's Blocks or the "just call
theme() on a node and figure out the overrides later" mental model encouraged by
node--[content-type].tpl.php. As the Drupal community asks itself again how it wants to do rendering, let's also ask "how do we want to think about rendering?"
The rise of design component thinking in the wider Web development world is not turning back. Web Components and modern front end MVC frameworks encapsulate design components. They do not care about every single implementation detail and layer of a node object. They care about getting variables ready for printing and updating. Panels module may fall out of the picture once Web Components fully mature. Until then, Panels allows for us to think in ways we will need to think for Web Components to work with Drupal.