Illustration of silhouette at podium with speech bubbles containing panels

Explaining Panels: Why I Use Panels

How to use Drupal's Panels module to transform data into design components.

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 hook_theme() and 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.

Entries like ‘item_list' and '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 calltheme() (directly or otherwise).

On the other hand, much of the Drupal core usage of hook_theme() is not at all design component minded. 'node','user''comment' all have entries in hook_theme(). In these elements you don't have to organize your data before calling code>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

Context >> Layout >> Content

But at execution time it is

Context >> Content >> Layout

Or the way I think of it

Drupal Data → transforming Drupal data into printable variables → design components for those variables to print in

Data (nodes) >> Configured transformation >> Design Components

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.