Super Simple Drupal Layout with Region View Modes

Combining Drupal core’s view modes and theme regions with a small home-grown module created a new way to lay out node pages.

The resulting module, Region View Modes, places copies of nodes, rendered through specific view modes, into theme regions. Yes, those are the same regions into which you would normally place blocks. There’s no new layout system here. You use the one you already have: your theme.

Once enabled, using the module is pretty easy:

  • Visit the Manage Display page for any content type (e.g. Article)
  • Expand the Custom Display Settings section
  • Check the view mode for one or more theme:region combinations. For example, Bartik theme: Sidebar first region
  • Click Save at the bottom of the page
  • You’ll now see the activated view mode(s) near the top of the page. Click on one.
  • Reorder, hide, or change the settings for any fields
  • View a node of that content type

Here’s a demo:

That’s all you need to know to use the module, but if you’re curious about how it works, read on!

A bit of history

I strive to keep Drupal site builds lean and mean, a practice we’ve come to call Minimalist Drupal Development.

While working on some recent projects, I needed a bit more control over the placement of fields on some content types. Like most Drupal site builders, I’d normally reach for Display Suite or Panels, but those are big modules, and they include a lot of functionality that I don’t usually need.

Or maybe I’d create a Views display block using the current node as a contextual filter and then placing the block via context. It works, but how many admin pages must I visit to set that up? It’s cumbersome. And what if I’m going to minimalist extremes and not even using Views? (It’s not that crazy of an idea!)

One project, a distribution for the Cornell University College of Agriculture and Life Sciences (CALS), was inspired by the lean simplicity of the energy.gov redesign. The developers on that project used BEAN and some blockreference fields to allow page editors to choose which blocks would appear on the page. Ooo. Page editors can choose where they want blocks to go? And their choices will be versioned and part of their editorial workflow?

I thought, Cool!, but how do they get those blocks to show up outside of the main content region? Apparently, they used a combination of Field Groups and Display Suite to create regions within the content area and placed the fields there.

And it looks like it worked great, but doesn’t Drupal already have regions defined by themes? Why do we need two layout systems?

The CALS folks also wanted version-able block placement that was compatible with a draft/review/publish workflow. Like energy.gov, blockreference was the ticket!

But for CALS, I did something simpler for layout. I found that I could implement hook_page_alter() or hook_page_build() and mess with the entire page render array! Whoa!

Moving the blockreference field content was as easy as this:

/**
 * Implements hook_page_alter().
 *
 * Moves content from blockreference fields into the sidebar regions of the theme.
 */
function BASE_THEME_page_alter(&$page) {
  if (isset($page['content']['system_main']['nodes'])) {
    // Get the first node _from the render array_.
    $node = current($page['content']['system_main']['nodes']);

    if (isset($node['field_first_sidebar_blocks'])) {
      $page['sidebar_first'][] = $node['field_first_sidebar_blocks'];
      unset($page['content']['system_main']['nodes'][$node['#node']->nid]['field_first_sidebar_blocks']);
    }

    if (isset($node['field_second_sidebar_blocks'])) {
      $page['sidebar_second'][] = $node['field_second_sidebar_blocks'];
      unset($page['content']['system_main']['nodes'][$node['#node']->nid]['field_second_sidebar_blocks']);
    }
  }
}

The actual code has a few more checks in it to ensure that we’re on a node page, but that’s the meat of it. Sure beats adding and configuring a whole new module!

Challenges of scale

Another project, for the University of New England, had some layout requirements for their event pages (like this one). They wanted the date, time, and location displayed in a column on the left. On the right were to go the share, video stream, and registration links. Since that info was just a bunch of fields on the event content type, it made sense to use the ‘CALS Technique’ to alter the page render array and put those fields in regions, too!

Then the same thing happened for news. And then some other content types.

At that point, the hook_page_alter() implementation began to get a little unwieldy. I needed a way for any developer to easily assign fields to regions for any content type, all while ensuring that their choices were preserved in code (via the Features module, in this case).

A module is born

That’s when it clicked. We’d already been using view modes to display our content types in different display contexts, like teasers in listing pages. Couldn’t the theme sidebar region be considered another display context?

Drupal comes with built-in view modes like full and teaser. Turns out that declaring new view modes is insanely easy with hook_entity_info_alter(). What if I just made view modes for each of the regions in the active theme?

Site builders could activate them and then just drag and drop reorder, set the display format, and show and hide fields in them.

And what if, when displaying the full node, I could generate the render array for that view mode and put it directly in the theme region?

So that’s what I did. The code became Region View Modes, and the simple combination of view modes and theme regions resulted in some interesting emergent properties:

  • You can now place fields on the page more than once. For example, you could place an image field in the main content area and a sidebar. The formatter settings for each view mode are separate, so you could put a large image in the main content and a thumbnail (with a link!) in the sidebar. Or you could show the ‘summary or trimmed’ format of the main body field in the highlighted region, as a sort of TL;DR section at the top of the page. Or you could put it in the sidebar.
  • Field Groups work in region view modes, so you could, for example, combine multiple fields into a collapsible region.
  • Display Suite layouts and Field Collections will happily render in region view modes, as will pseduo-fields.
  • If you use blockreference fields, you can version and moderate your block placement.
  • Like any other view mode, the display settings are exportable into Feature modules, so this method is compatible with code-driven Drupal development.
  • Region view modes are set per theme, so your layout can vary (if you choose) between enabled themes.

There are many ways to lay out Drupal node pages and there’s no one right way. But if you’re looking for a simple, lightweight, and flexible layout solution, I hope you’ll give Region View Modes a try.