Simplify Complex Site Development with Drupal Panels
There is a large ecosystem of Drupal modules that provide tools to assist in laying out items on a page. Drupal core provides blocks and entity field rendering while contrib adds a multitude of additional options including Display Suite, Entity Views Attach, Context, Panels, and many more. Anyone who has built an even moderately-complex Drupal site has likely used a mix of these modules and knows that it’s easy to run into development and theming inefficiencies.
The Drupal Panels module is a powerful page layout tool that can solve just about *all* page layout use-cases in Drupal and alleviates most, if not all, duplication and inconsistency issues. I find that the more I use Panels, the more I want to use them.
The Great Thing About Panels
Building a Drupal site is often compared to playing in a toybox, assembling building blocks using functionality provided by the rich ecosystem of modules. But sometimes it can feel as though you’re working with building blocks from 15 different manufacturers who each have their own ideas of how a building block should be made. And a few of them seem to think that what you really need is a sewing kit instead.
Panels brings some sanity to this world. Panels takes the bucket of mismatched toys, fixes them up, and delivers a fine set of Legos™. In conjunction with the closely-related cTools and Page Manager modules, Panels provides a way to consistently interact with page components, even those provided by other modules, giving them all roughly the same functionality and ability to be pieced together in almost limitless ways within the Panels ecosystem. Its drag-and-drop interface allows site administrators to fit together, modify, and reuse components as they build out pages. The result is greater design flexibility, a quicker deployment timeframe for new pages, and a reduction in the amount of custom code and theming needed for rich solutions.
An essential feature of any page layout tool is the ability to support a variety of layout templates. It’s easy to build layouts for Panels, and – if you’re using Panels to render all content – you only need to build a layout once in order to use it anywhere. Whether rendering a view with a sidebar, a node, a taxonomy term, your homepage, or a small embedded component on a page (e.g., via a Mini Panel), any and all of them can make use of a single library of layouts. This feature will reduce the duplication of your efforts as well as the surface area for bugs.
Panels bring consistency to the rendering path. Rather than some items being attached as pseudo-fields, others via Context, and others injected directly into a node’s render array wherever they see fit (yes, I’m looking at you, core “author and date information”), all page components simply need be exposed as cTools content types and added to the page layout as panes. Thankfully, there’s broad support in the contrib space for cTools so there’s scarcely anything in all of “Drupaldom” that isn’t exposed as a cTools content type. Any pane, i.e., an instance of a cTools content type can leverage style, access, context, and other plugins built for any other pane, maximizing code reuse. So if you write code to conditionally hide a piece of content based on complex permissions requirements, you can easily apply the same logic to any other pane with just a few clicks in the UI.
Contexts provide the information necessary to render a pane that requires data to be rendered properly. Contexts can be hard coded, derived from the environment (the URL or currently-logged-in user), or derived from relationships between entities. If you’d like to render the author field of a specific node, as long as a node context is available, you can render that field as a pane on any page.
Panels are fully exportable with excellent features integration. Hurray!
Drupal Panels in Action: the Kresge Foundation
We recently worked with the Kresge Foundation to re-launch their Drupal-based website. The site design had a wide variety of design elements – slideshows, sliders, Twitter feeds, etc. We wanted to not only build pages that reflected the designs, but also deliver a toolkit of designed components that could be assembled in various ways by both developers and content editors. The Panels ecosystem allowed us to easily to construct and assemble highly-modular components.
Global Site layout
A Drupal theme typically defines a set of “regions” into which you can place content through the core block interface. Unfortunately this approach suffers from significant limitations around exportability and rendering options compared to what Panels offers. Thankfully, the Panels Everywhere module solves these problems. It lets you move away from Drupal’s relatively inflexible concept of page regions by overriding page.tpl.php with a Panels layout of your own choosing/definition. This means that everything rendered to the page is rendered through Panels.
Take a look at the simple configuration for the Kresge Foundation site to see how each pane maps to a section of the visible page:
You’ll note that the “tabs” pane on the left does not map to any visible region; that’s because the tabs are only visible to logged-in site administrators
All global components go in the Panels configuration, which in this case is using a simple 1-region layout. The pane in the middle, labeled “Page content,” contains the main content Drupal has rendered for the page; in our homepage example here, it’s the green section, which is, itself, a Panels page. Not only that, but our header and footer are Mini Panels. So we have Panels within Panels…it’s very powerful stuff!
Panels Everywhere is even more powerful if there are to be separate “sections” of the site that need a radically different layout/configuration. In that case it’s as easy as configuring a new variant for each section. Each variant can use an entirely different layout and pane configuration. Selection rules dictate when to use each variant. This was not needed for the Kresge site, however. The primary advantage of using Panels Everywhere for Kresge was to allow exporting the site-wide layout to code.
Node / Entity Rendering
The Kresge Foundation site primarily makes use of Entity Panels not just to render nodes, but also to render all entities, even those such as Paragraphs or Fieldable Panels Panes that are primarily meant to be embedded on pages and don’t have detail pages all their own. Here’s a little taste of the admin interface for Entity Panels where you can see which entity types, bundles, and view modes Entity Panels is instructing Panels to render:
Now let’s take a look at how we used this on the Kresge site. Here’s a type of page that we call a “Focus Area detail” page: specifically, the Harvesting Leading Practices page. The entire page is configured in Panels, but I’ve called out a few of the more interesting components:
Note that there are other good ways to use Panels to render nodes, including Panelizer and Panels’ built-in node_view task handler, but a discussion of those options exceeds the scope of this article.
There are usually at least some pages in a Drupal site that are not based on an entity. On the Kresge site, such pages include the home page, search results page, and various listing pages such as Library and Grants Awarded.
Page Manager — with Panels — will let you construct a custom page at any path in your Drupal site. This is straightforward enough if you’re creating a new page, as we did for the Kresge home page and listing pages. But in the case of the search results on the Kresge site, the page we wanted to customize already existed; it was provided by the Search API module. In this case, we used the Page Manager Existing Pages module to “take over” the rendering of the existing search results path and bring it into Page Manager. In the same way literally any page generated by Drupal can have its output controlled by Panels, with no custom coding required.
The Kresge Foundation site also uses the Clean Panels Markup module. This module provides a pane style plugin that provides an easy-to-use and consistent means to control the tags, classes, and IDs that wrap any pane when it is rendered. This reduces the amount of theme function or template overrides that are necessary to achieve basic theming tasks.
Tremendous Flexibility via Reusable Components
Panels also simplifies both development and theming by allowing complex functionality to be encapsulated and re-used in multiple places. For example, the Kresge Foundation uses the following design element both on their homepage and a variety of other node pages:
This component was built as a mini panel. This made it available to be embedded on any page, or rendered inside of any other entity. So we embedded it directly on the homepage (itself a Panels page) *and* put it in a new Paragraph bundle called “Programs and Practices.” As easily as that (and through the magic of Paragraphs), Kresge gained the ability for editors to embed this component almost anywhere.
We built a small library of these sorts of components that Kresge’s content editors can now use to embed rich components into their pages without having to touch any code.
“Component-based design” is a web development approach that’s been growing in popularity and for good reason. Websites aren’t magazines; they’re far more dynamic than that. Editors and site builders want the flexibility to compose a wide variety of pages without having to employ custom development and theming for every iteration. In my experience, Panels is the most effective approach to achieving this in Drupal. When seeing a new design, I usually find myself thinking, “What layouts will I need? And how will I get those design elements into panes?” Once the building blocks are amassed, then it’s just a matter of piecing them together.
Other key modules to look at — which were also used on the Kresge site — include Panelizer, Fieldable Panels Panes, and Pane. If you’d like to experiment more with what’s possible with Panels, I’d recommend taking a look at the Panopoly distribution. It employs many of the techniques highlighted here, plus many more to show you what’s possible with Panels.