Nov 06 2016
Nov 06

A recent Drupal 8 project of ours had some great requirements around it’s landing pages, aimed at reusing existing components in a range of layouts and combinations. Paragraphs quickly established itself as the site-building tool of choice and Flexbox always wins for me as the CSS grid/layout approach, so we looked at how the two could be combined to give the client the flexibility they needed, without over-complicating the editor experience.

For me this is a great example of multi-disciplinary team communication. The site builders didn’t quite know what flexbox was capable of and us front-end devs weren’t up to date on Drupal 8’s layout sitebuilding tools, and neither groups of developers fully considered what would be best for the content editors.

The site builder’s perspective

There are of course other approaches to layout in Drupal - Panels being the most obvious but at the time it’s 8.x branch wasn’t fleshed out enough (though it sounds it's progressed a lot) and it’s UI/UX seemed a little overkill for this project. Blocks being fieldable in Drupal 8 also makes them an option but the limitations around user permissions and the fact that they each have their own edit screen ruled them out from the “ease of editing” perspective.

Paragraphs attached to a Landing page content type gave us one edit location per landing page and structured content that can easily be mapped to existing design components.

But Paragraphs isn’t a layout tool… and we certainly don’t want to nest paragraphs inside paragraphs just to get the markup structure needed to apply a complex grid to it!!

The front-enders perspective

So Flexbox is amazing! If you haven’t looked at it, I’d recommend starting with this visual guide to get an idea of what it’s capable of. It’s also simple enough to write in fallbacks for older browser so there are no excuses not to start using it.

You can of course use any grid system but one of the big advantages of Flexbox is that you don’t have to set widths on the grid items. You want all the children to sit next to each other and for their widths to distribute evenly in the amount of space you have? Flexbox is your friend. You want one of those children to have a width and the rest to fill the space around it?? Flexbox is your best friend :)

The other big advantage is you don’t need to nest grids. All of the grid items can be siblings of each other (within reason of course).

One row (and by row I mean strictly visual row, as no actual grouping is needed) can be two columns, the next row can be three and the third row can just be one full width column. Or you can have one half width column with just white space next to it and the next row goes back to three columns.

Now that might only make sense in my head so here is an example of the kind of layout I’m talking about:

So when a design comes in with a whole range of different column sizes and spacing, don’t curse the designer, thank Flexbox.

Now we have a grid system capable of displaying our single level of paragraph content in any position and at any column size we can fathom. What’s the glue?

Classy Paragraphs of course!

Classy paragraphs lets you specify a predefined list of classes (or combination of classes) in Drupal that can be selected when adding a paragraph’s content. Once specified you can add a select field to your paragraph type and then the content edit can not only re-order the paragraphs but they can give choose what flexbox layout it should have.

The disadvantage is the editor can’t see the grid visually like they can in something like Panels, instead just the name you’ve associated with the class but preview works pretty well in Drupal 8.

You can of course do the same thing in Drupal 7.

We launched a few weeks ago, and each of the top level landing pages, including the homepage is built this way. We’ve simplified the layout options somewhat and thought it a good generic enough candidate to bundle up in a Drupal 8 ‘feature’ module (being just config and css) called Paragrahs layout which you can now download from and add to your paragraph based landing pages too.

Layout Paragraphs
Dec 03 2014
Dec 03

Panelizer is a great module for being able to modify the layout of a page on a per-node basis. However, its greatest strength can sometimes be its greatest weakness. We found this out the hard way when a client asked us to help them add a block on every single page of their site directly beneath the h1 page title. Read on for how we approached this issue.


One of our clients with a pretty content-heavy site asked us to help them place a new block on every single page of their site. A pretty straightforward request, sure. But they wanted it to appear directly beneath the h1 page title on every page. At first glance, this looked like something core’s Block module could handle. Except that the page content is grouped together, so there was no way in the UI to place the new Block directly beneath the page title.

There are many possible approaches to this, but we had to work within the existing structure of the site and there are also multiple modules handling the layout of pages. For instance the Panelizer module is being used for some content types and standard nodes/templates for others. They are also using Views pages and one or two Page manager pages. So we needed a solution that would cover all these bases.

The trickiest part, and the focus of this article was the Panelizer pages. The Panelizer module is much like its parent, Panels, except Panelizer allows you to “Panelize” a page on a per-node basis. So with Panels we might create a Panels page, and apply the use of that page to a content-type. This means that we need only change the layout of the Panels page and it automatically applies to any page based on that.

Panelizer, however, works by doing this on a per node basis. So, a user could modify the layout of a single node page. For example, let’s say node/56 is a page called “Company Expenses”. The user wants to show some content taken from the company report, but we wants it laid out in a very custom and specific way. The layout is a little too complex or cumbersome for just using the WYSIWYG editor, and perhaps it is not intended to be reused anywhere else. This is where Panelizer is great. It gives users the flexibility to make changes to the layout AND content of a page, without having to touch any code. But...

“its greatest strength can sometimes be its greatest weakness.”

When a user does change the layout or the content, the page is then in an “Overridden” state. This means that any changes to the default Panelizer template, will not be reflected on overridden pages. In this case of our client, there were hundreds of pages where their layout/content was overridden. We could have just given them instructions on how to manually place the block using the Panelizer interface, but it would have been a lot of work to manually edit hundreds of pages, so we decided to look at a way to automate it.

Option 1: Preprocess page

The first place I looked was preprocessing of the page. I hoped that by using a general hook_preprocess_page I could simply add an additional element to the page array that would get rendered. Unfortunately, the Panels content of the page is already rendered to markup by the time it gets to hook_preprocess_page, so that wasn't going to work for us.

Option 2: Pre render/alter hook

The next road I went down was trying to do the same thing as above, but with a more targeted hook. Sometimes modules will provide the pre render or alter hook for you. I did some Googling and looked through the Panelizer documentation, the first function I came across was hook_preprocess_panels_pane(). I tried it out but found that it was preprocessing the individual panes within a region. I needed to actually provide a new pane, so it wasn't going to help us.

I then started to dig around in the actual Panelizer code. That is when I found calls to panelizer_pre_render(). This seemed to be perfect as it specifically targeted the exact thing I was trying to modify. One of the arguments that is passed to this function is the $display object of the entity. The display has a $content property which is an array of "panes". I thought this was going to be perfect. I could insert my own pane into this array and it should just work. It did work to some degree in that I could insert a pane, but for some reason I could not modify the order of the panes. The requirement was to have this new block appear directly beneath the h1 page title. I tried re-ordering the array elements. I tried using the 'position' property but nothing I did could change the order of elements at this point. At first I was just adding in an array but later I found the function panels_add_pane() function. I hoped this would help but unfortunately I still could not modify the order of the panes.

Option 3: Update hook/programmatic load/save

After some more research I came across the interesting approach outlined in this blog post. Basically it outlines how you can programmatically load a Panelizer entity and add in a new pane. It does in code what you would do through the Panels interface by clicking the gear icon then clicking 'Add Content', placing it in a region and then clicking 'Save'. I decided to write an update hook that would do something very similar. Here is my code:

First I wanted to grab all the Panelized nodes that are overridden. This function handles querying for them:

function example_block_pane_update() {
// Load all overridden nodes.
$panelizer_nodes = db_select('panelizer_entity', 'e')->fields('e', array('entity_id'))->condition('entity_type', 'node')->condition('did', 0, '<>')->groupBy('e.entity_id')->execute()->fetchCol('entity_id');
// Pass to function which will add my_block block.

Notice that I am querying the panelizer_entity table looking for any entities that have the column “did” set to zero. This “did” column is a foreign key to an entry in the panels_display table, or the "display object" essentially. What I found was that all of our overridden nodes had their did set to zero. So this was how I queried the database for the entity id’s that I wanted to update. Note: I did find some anomalies with this approach. There were a handful of entities which had zero for did but were not listed as overridden. I was unable to determine why this was the case. It could be that I am making the wrong assumption about the did in this case but I wasn't able to find a more definitive answer at this stage. If you are aware of the answer please comment to let me know.

Now that I have queried and found all the overridden Panelizer nodes, I want to loop through these and add in my new block. Here is my function that handles it.

function example_add_block_pane_nodes($nids) {
$nodes = node_load_multiple($nids);
foreach ($nodes as $nid => $node) {
// Set region based on layout.
switch ($node->panelizer['page_manager']->display->layout) {
case 'landing_page':
$region = 'primary';

case 'sub_landing_page':
$region = 'main';

case 'onecol':
$region = 'middle';
// Check if matching type.
if ($region) {
$panes = array();
$my_block_pane_exists = FALSE;
// Load the display.
if ($display = panels_load_display($node->panelizer['page_manager']->display->did)) {
// Get this display's panes.
$panes = $display->content;
// Reset the panes.
$display->content = array();
$display->panels[$region] = array();
// Loop through and add in our new pane.
foreach ($panes as $pid => $pane) {
// If my_block pane already exists we can skip this.
if ($pane->type == 'block' && $pane->subtype == 'my_block') {
$my_block_pane_exists = TRUE;
// Set content.
$display->panels[$region][] = $pid;
$display->content[$pid] = $pane;
// Add a new pane after the node_title pane.
if ($pane->type == 'node_title' || $pane->type == 'page_title') {
$new_pane = panels_new_pane('block', 'my_block', TRUE);
$new_pane->panel = $region;
$display->panels[$region][] = $new_pane->pid;
$display->content[$new_pane->pid] = $new_pane;
// Finished reordering pane's, now save.
if (!$my_block_pane_exists) {

Some things to take note of here:

  • I set the $region value based on the layout for this entity. This is because the regions within the layouts can have different names.
  • The main foreach loop was modelled after the submit function panels_edit_display_form_submit() which is in panels/includes/
  • Since we want this new pane to appear directly beneath the page title, we simply check as we loop through each pane if it is the page/node title and if it is we create the new pane using panels_new_pane() and apply it as the next element in the panels and content arrays on the display object.

The above functions were placed into an update hook and so we updated a large number of Panelized nodes in one go. I then wrote some tests that would test creating a new Panelizer node (using the default) and to look at some of the existing to ensure that my_block was present. 


Panelizer is a great module, so long as you are aware of this kind of potential issue. It can be particularly confusing to users who probably wouldn't consider the issue that even though you have the flexibility to change the layout/structure/content of a page, it then means that it can be incredibly difficult to automatically make changes to the layout/structure/content of those pages in the future. I think this kind of issue can be mitigated by careful design and site architecture. Perhaps instead of allowing the entire page to be Panelized, only certain parts? During the planning phase of a project you should consider whether users really need the flexibility to change the layout of every single page and again this should be weighed against the ability to later maintain those pages.

Panelizer Panels Layout
Aug 29 2013
Aug 29

Over the past few months our site has undergone a total re-design // upgrade from Drupal 6 => 7.   The priority was to rebuild functionality and migrate content quickly and cleanly – permissions schemes and editing privileges for our content contributors took a backseat. Now that the site has been launched and stabilized, we’ve begun to look at some of the tools we used to try to figure out how and if we can train our librarians to use them.

On our old site, we made pretty heavy use of blocks (particularly for sidebar items) – since we had to rebuild these pieces of content anyways, we tried to put them in more flexible containers.  We started looking at panels – we found Panopoly.  This tool worked really well for us.  We could (and did) use panel pages, custom panel layouts, views as panel panes, mini panels as blocks, blocks as mini panels, etc.  But when we started to turn over content editing responsibilities to our librarians, we discovered that the default settings were way too powerful for what they needed to do.  The interface was overwhelming and privileges were set too high – our content editors had too many options.  We had to scale back.


The first step was to lock down Panelizer privileges on the home page – we were clued into this one when one of the librarians told us that she was seeing a “Change Layout” button on the site’s front page.  That meant she (or any other content editor) could have changed the layout of the home page with two button clicks.  Not good.

We probably could have done this a few different ways – we chose to change the renderer of the home page (built as a panel page) from “In-Place Editor” to “Standard”. Of course this means that we (admins) can’t use the groovy Panelizer interface when we want to edit content on the home page – but that’s cool since we know that those content regions are mini-panels and can be edited elsewhere.


That took care of the home page, but the librarians were still seeing too many options on the other pages (see first screenshot) – we could get rid of the In-Place Editor on all pages, but we’d have to make those configurations on each panel page (or page that had been panelized) and we would lose the slick, drag-and-drop editing interface. So we hit the permissions table.

We found that the permissions were set way too high. In the screenshots that follow, you’ll see what we left on – note that we have 11 roles in the table. The 3rd column from the left is admin, the 4th is editor (librarians) and the last one on the right is portal manager, which we made for development purposes. When we apply these changes to the production site, we’ll set editor privileges to the same as the portal manager on development. So just pay attention to the one on the far right – these are the only permissions we need for our use case: giving librarians permission to to edit layout and add panel content to basic web pages.

permissionstable2 permissionstable3 permissionstable1 permissionstable7

All other panel, panel pane, panelizer, etc. privileges in the table need to be locked down. Note that some of the permissions we turned on were specific to a content type (our “Web Page” content) and that this will vary depending on your needs.

Restricting these permissions reduces access to the editing interface.  Our librarians will no longer see “gear” buttons – they’ll only see “Customize This Page” and “Change Layout” .


But when they click “Customize This Page” and try to change panel content, they still get bombarded with too many editing options (see the first screenshot) – we can fix that. The Panelizer configuration allows you to adjust settings for allowed content per content authoring method.


Since we’re locking down Panelizer settings for the “Web Page” content type, that’s where we’re headed in the configuration table.


This is where we want to be – lots of boxes to uncheck, lots of buttons to push.

That’s cool – all our librarians need to do is add lists of links, images and text, and (ideally) to be able to reuse the content they create elsewhere.

Here are the settings we used:

allowedcontent3 allowedcontent4 allowedcontent5

The result?  Content editors can now…

…choose layout:


…add, edit, move, delete content to the regions within this layout:


…add links, images, text or reusable content:


Note that if they do want to reuse content, they have to specify that in the editor:

Jul 02 2013
Jul 02

For as long as I've been working with Drupal, there's been a wonderful tension on how to make Drupal not look like Drupal. People have taken great pride in being able to recognize a Drupal site both from the rendered page in a browser, and by looking at the code. How frustrating for graphic designers who want to create an experience, not just decorate Drupal! With a greater understanding of the contributed module space, it becomes infinitely easier to make Drupal look like your solution, instead of making your solution look like Drupal.

Each major revision of Drupal has seen a new point-and-click tool introduced into the contrib space. In Drupal 5 we got Panels. In Drupal 6 we got Display Suite and in Drupal 7 we got Omega. It's been fascinating to watch the evolution of our layout tool kit…and frustrating for new-to-Drupalers to know which one to pick. If we oversimplify what these UI-based layout tools do, we can divide the tools out as follows:

  1. Breaking down and altering the node.tpl.php file (e.g. Display Suite).
  2. Breaking down and altering the page.tpl.php file (e.g. Omega and Context ).
  3. Building up new layouts by pulling in specified Drupal components at the page or region level (e.g. Panels).

As you can see, the approaches are somewhat complementary, except when they're not. This can make it difficult to know which suite of modules (and themes) you should choose for your particular project. I'm an early adopter of Panels. I know it. I love it. (I helped write the D6 book on it.) And I'm delighted to see some of the concepts developed in Panels going into Drupal 8. BUT! I also know it's not the right tool for every site builder and themer. So where do you start?

Display Suite

First up: Display Suite. This is a beautiful little module. It fits politely into Drupal's existing administrative interface for managing content type fields. The very first time I installed Display Suite I used it to break my Blog display into the classic two column WordPress display: one side for the content, and one side with the date. It was a little bit revolutionary for me that I could just click a few things and never have to open a text editor to make a two-col layout. Yum!

I also feel in love with Drupal's built-in View Modes after playing with Display Suite. Instead of perverting Views I was able to get fine grained control of my nodes through Display Suite. (Don't pretend like you haven't used Views to "fix" the Default layout of your content type. We've all done it at least once.) If it sounds like the breath of fresh air you've been looking for, check out our free video series on using Display Suite.


Next up: Panels. I won't lie, there's a learning curve associated with this very powerful module. If you just want to shuffle some fields around in your content type display, this is not the module for you. You should use Panels, however, when you need to: display a block in multiple locations for different contexts; alter the layout of core Drupal pages, such as the taxonomy page; or provide different layouts under different conditions, such as the homepage for an authenticated or anonymous visitor. Yes, bits and pieces of these elements can also be found in other modules, such as Context (we'll get to that in a minute), but in most other cases you are spread across multiple configuration screens, instead of having a single control interface. Before rushing out to install Panels, take a look at our free video series on using Panels by the TWIG initiative lead, Jen Lampton. I hope that you end up loving Panels as much as I do, but we can still be friends if you decide it's overkill for your needs.


Finally we come to my nemesis, the base theme Omega. Ages ago I recorded a little video of myself unpacking Omega for the first time. Back then it was hard to use, undocumented, and very frustrating for anyone who was used to doing things "The Drupal Way". The video (shouldn't) exist any more because Omega has grown up a lot. It's become easier to use, and very well loved by a lot of Drupalers.

The 3.x branch of Omega was essentially its own theming system. Where most themes encourage you to take a series of Regions and sub-divide them using Blocks, Omega goes the other way, allowing you to collect Regions into Zones and Sections. Omega, as far as I know, was the first theme to integrate with CTools, allowing you to export your point-and-clicked theme settings to code. We cover both of these features in our video series Introduction to Omega 3.x. Watching the videos is a great way to explore Omega without the commitment. (And if someone else has already committed you to Omega, the videos are a great way to get up to speed.)

Be careful though! The Omega 4.x series takes OUT the pointy-clicky tools and puts them back in code, so make sure you're grabbing the right version when you download the theme. Or, if you want to move forward the the latest-and-greatest version of Omega, consider combining it with Panels for your layout. The base theme offers good integration with my favorite layout module.

So there you have it: three different approaches to altering the layout of your Drupal site. With these three powerhouse tools there's no reason for your Drupal sites to ever look Drupally again.

May 10 2013
May 10
Responsive & adaptive grids with Susy, Sass & Compass in Drupal 7

Here at Advomatic we've experimented with several approaches to responsive design over the past few years. I think the "mobile first" philosophy became popular right in the nick of time. There was a point when we'd detect if the user was on a mobile device and then deliver a separate mobile theme. This meant two instances of a site to develop for and maintain. I can't imagine doing that now, given the amount of device width/height possibilities and device-specific bugs that exist out there. So, now we work on layout with the goal of accommodating the content rather than the device. To accommodate a responsive and flexible layout, it's best to get your site on a grid. There are tons of options out there, but we've found one in particular helps you quickly get rolling and set up with a column layout that can adjust to whatever device you need your site to display on (and is fun to work with, too). Lately, it's been part of our holy trinity for responsive theming: Sass, Compass and Susy.

First things first: ditch pixels

One big first step to responsiveness in your site is to stop using pixel units for measurements. We use em units because they are proportional to any parent measurement, and therefore flexible and responsive. If we have a base font-size set on the body element of 16px, and our #footer is set to 1.6em, that #footer font-size will automatically scale up or down accordingly if the body's (or any parent element to #footer, for that matter) font-size changes. To manually figure out exactly what em value you should be using for an element, you can use a commonly used formula: target ÷ context = result... or you could do it the easy way with a Sass function:

// Create em() for setting font-sizes in pixels.
@function em($target, $context: $base-font-size) {
   @if $target == 0 { @return 0 }
   @return $target / $context + 0em;

// Example usage: font-size: em(21px);
// This will set the font-size to 21px in relation to the browser's base font size if it has not been established in any parent element, or in relation to $base-font-size which is a variable you can set in your Sass.

// Example usage 2: font-size: em(12px, 10px);
// This will set the font-size to 12px in relation to a parent element's font-size of 10px.

Get on the grid

If you're doing front end development these days, you're probably familiar with the concept of grid-based design and translating a comp into a fully fluid or adaptive layout via HTML/CSS. We frequently use Zen 5 as a base theme and have been big fans over the years because it comes loaded with many of the best tools for front end/theme development, while also pretty lean as far as bloat goes. While it's important to be able to build themes for browsers that can handle fancy bells and whistles, we also need to support older browsers that don't. Zen 5 already has Sass and Compass integrated. As far as a grid framework goes, we use Susy instead of Zen Grids... this has just come down to personal preference. Zen Grids is also a great system. Susy is a responsive grid framework/plugin for Compass, and it allows you to build on top of either a "magic", static or completely fluid grid.

  • "Magic" grids are the default - they have an elastic container that responds to font sizes when set with em units, and is fluid on the inside. It's container size gets calculated according to the widths of your columns and gutters.
  • Static grids are just that - all containers and column widths are not flexible and this is the traditional grid style. As such, it does not collapse when the viewport is smaller than the grid is wide. Even though you may specify pixel values for the column sizes, Susy converts to a percentage of the container size. The container size, like the magic grid, gets calculated according to the widths of your columns and gutters.
  • Fluid grids are truly flexible layouts that respond to the width of the viewport. By default the container width is 100%. However, as with any grid type you choose, you can specify this with the $container-width variable (such as "$container-width: 70%").

Set it all up

To add Susy to your theme, there are a few things you'll need to do.

  1. If you haven't already, install Sass and Compass.

    sudo apt-get install rubygems
    sudo gem update
    sudo gem install sass

    sudo gem install compass

  2. Set up a Compass project in your theme directory.

    This is already done for you with Zen 5. If you're not using Zen 5 or a contrib theme that has this done already (look for a config.rb file in the theme directory), then set up your Compass project by going to your theme directory in your favorite command line interface and run:

    compass create nameofyourtheme

    This will add a "config.rb" file to your theme, and is where the Compass project settings are located.

  3. Then, install Susy.

    sudo gem install susy

  4. Require Susy in your Compass project.

    Open up the config.rb file and add the following (wherever "requires" are located):

    require "susy"

  5. @include susy and add grid settings to your _base.scss (or equivalent "global" Sass file).

    We usually stick any of our grid settings in the _base.scss file that comes with Zen so that the grid variables set there are available to any other Sass stylesheet in the theme (because Zen's base gets @imported in them all). You'll also want to place them in whatever Sass file you're using that gets imported into any file where you'll be doing responsive styling/layout. For example:

    @import "susy";
    $total-columns: 12;             // a 12-column grid
    $column-width: 4em;            // each column is 4em wide
    $gutter-width: 1em;            // 1em gutters between columns
    $grid-padding: $gutter-width;  // grid-padding equal to gutters

After installing Susy, and getting your Compass project set up properly for the theme, you'll want to tweak those default grid settings that you just added (total columns, column width, grid padding, etc...) for the purpose of your own design. Using those settings, Susy will automatically figure out the math and put percentage widths on internal grid elements, as well as a max-width on the container (should you use a non-fluid grid). By default, all Susy grids are "magic." If you want to use one of the other types of grids, you would do that by setting the $container-style variable. For example, to build a 5 column-wide mobile first "magic" layout, we can do something like this:

$total-columns: 5;
$column-width: 3em;
$gutter-width: .75em;
$grid-padding: $gutter-width;

Making things happen at different viewport sizes

Another handy part of Susy is its at-breakpoint() mixin. This can be used in replacement of a long and drawn out media query that targets specific pixel-based min-width or max-width values of the viewport. Something we do frequently for adaptive/responsive layouts (where there are established, comp-determined breakpoints for mobile, tablet, desktop), is set variables for different numbers of grid columns.

$mobile   : 5;
$tablet   : 11;
$desktop  : 16;

So if you're building in a mobile first manner like this, and you want something to happen at a certain breakpoint in your Sass, you can use at-breakpoint() with your column count variables as an argument.

#content {
  @include span-columns(5);
  @include at-breakpoint($desktop) {
    @include span-columns(13, $desktop);
    @include prefix(3, $desktop);

In this situation, #content normally spans 5 columns wide, which is the default/mobile width of the grid in this example. When the viewport is at the desktop breakpoint (16 columns can fit in the viewport), the width of #content will change. span-columns(13, $desktop) means "make this 13 columns wide, out of 16 total columns". prefix(3, $desktop) means "add 3 columns of empty space beforehand." So #content becomes 16 columns wide in total, however only 13 columns of space are usable and contain content, since we added 3 columns of padding to the start. A different, non-layout related way of using at-breakpoint() is to maybe change some kind of style at a given breakpoint.

padding-bottom: em(15px);
@include at-breakpoint($desktop) {
  padding-bottom: em(85px);
  background: url("bg-content.png") 162px 100% no-repeat;

Having at-breakpoint() at the ready is a great way of releasing yourself of the mindset and clutter of maintaining several pixel-based breakpoints in your site, and helps future-proof things since device sizes are fluctuating so wildly as time goes on. Since Sass supports code nesting, it has become standard operating procedure for us to use at-breakpoint() at the end of things in a selector's nested styles, so that they override any established defaults (which are usually the mobile version styles if we are building mobile-first).

Alternatively, Aurora

While we normally use Zen and add Susy in manually (replacing Zen Grids), some themes have Susy, Sass and Compass (and other front end goodies) baked in already. Aurora is also a Sass & Compass-powered minimalist theme with a focus on best practices for HTML5 and front end development within Drupal. It has a number of cool features like Google Chrome Frame and Typekit integration. Aurora encourages the use of Panels' HTML5 Sections layout instead of using the standard Drupal left/right sidebar block regions for sidebars. Aurora also suggests you use the Blockify module to turn all the little things on the page that normally get rendered in a page template variable into blocks that you can assign to regions via Drupal's block admin page. There are a number of features in Aurora which have been pulled out and put into a separate module, so that any theme can make use of them. That module is called Magic and some of it's best features are the ability to exclude certain CSS/JS from being included, exporting of theme settings, enhancement of CSS aggregation and adding a viewport width indicator - which is very helpful when developing a responsive site to check all your breakpoints and everything in between.


Susy provides a great way of quickly getting your site layout blocked out and can produce any kind of grid you need. What has your experience been like using Susy in Drupal?

Oct 17 2012
Oct 17

Though Panels comes with several built-in layotus for you to choose from, you’ll find that these don’t always suit your needs. Fortunately, there’s also a layout designer that anyone can use to create a new layout with panels. In this lesson you will learn how to use the Panels layout designer for rapid prototyping.

Oct 17 2012
Oct 17

Drupal site builders have long wanted to rearrange the display of each piece of content. The page manager module provides us with a default node view context we can use to accomplish just this. In this lesson you will learn how to break an article into two columns.

Oct 03 2012
Oct 03

Now that you’ve manually created a new variant for your front page, this lesson will teach you a much faster way to duplicate an existing variant. This technique is useful if your variants are very similar to one another.

Oct 03 2012
Oct 03

Panels and the Page manager module allow you to create different versions of the same page (called variants) under different circumstances. In this lesson you will learn how to build two different versions of the content on your home page. People who are logged in to your site will see a different home page than people who are not.

Sep 26 2012
Sep 26

Each piece of content placed into a panel has it’s own configuration settings, covering everything from display style to access control. In this lesson we will take a tour through the settings for each pane.

Sep 26 2012
Sep 26

Drupal would like to assume that every page on your website will use the same layout. As it turns out, this is often not the case. The home page of your site, in particular, regularly uses a different layout. In this lesson we will demonstrate how you can use Panels to build a unique home page layout for your site.

Sep 26 2012
Sep 26

In this first series of Panels videos on you will learn how to use the panels module to take your Drupal website to the next level.  When you reach the limits of what Drupal alone allows you to do with it’s layouts, adding Panels to your site enables you to create more sophisticated displays of your content.  

Here are just a few things the Panels module makes easy:

  • Divide the display of your content into multiple columns
  • Place blocks into the center of your pages
  • Use different layouts on the same page, under different circumstances

Because Panels works with the Page Manager module in ctools, you get all the benefits of the page manager, as well as complex control of your layouts. Page manager allows you to take over many of the ‘default’ displays in Drupal, including the display of content (nodes), profiles (users), category listings (taxonomy), and also the edit forms for each of these entities.

Jul 25 2012
Jul 25

In this lesson we cover the basics of using Display Suite to modify the layout of a particular content type. We cover all the potential templates, adding classes to regions, and lots of configurations to set to taylor the layout to your needs. We also discuss how you can create your own template files and layouts for your own customizations.

Jul 05 2012
Jul 05

Though Initiative Owners are doing a fantastic job of keeping up with their individual initiatives, we've recently heard that the community would like more visibility on D8 progress in general. We've been trying to find the right format and we've got something for you to check out!

The D8 team of Initiative Owners and its supporters want to make it easier for you to find the most important issues to work on, so we've put together a summary page that we'll be updating it every two weeks, and more frequently on an as-needed basis.

The purpose of this page is to give an overview of progress of all the initiatives, as well as to let you know how each individual initiative is fairing and where they need your help the most.

Here's what's in the page right now:

1) High-level Schedule overview: the most important D8 dates are listed here.

2) High-level Progress overview: progress across all initiatives in 3 phases (discovery, design, development) are clearly visible

3) Calendar overview: Don't miss another important meeting, subscribe to this gcal, or check back on this page to see what's coming up

4) Initiative Info: A general overview of the initiative lead, and some important information links are centralized here.

5) Important places to help: Each initiative has important things they need your help with -- here's where we'll point you to the top issues to look into right now.

6) Scrum notes: We meet bi-weekly, and want to share the discussion topics and next steps with you all. Transparency about the progress and next steps will help you know how things are going.

This is only the first version of this bi-weekly information overview, but we hope it's useful for the community to see what's happening on D8 and to help you identify the most impactful issues for D8 so you can get involved.

If you've got ideas for us, or feedback on this format, please feel free to contact me on twitter at @svettes or via email

Jul 05 2012
Jul 05

Though Initiative Owners are doing a fantastic job of keeping up with their individual initiatives, we've recently heard that the community would like more visibility on D8 progress in general. We've been trying to find the right format and we've got something for you to check out!

The D8 team of Initiative Owners and its supporters want to make it easier for you to find the most important issues to work on, so we've put together a summary page that we'll be updating it every two weeks, and more frequently on an as-needed basis.

The purpose of this page is to give an overview of progress of all the initiatives, as well as to let you know how each individual initiative is fairing and where they need your help the most.

Here's what's in the page right now:

1) High-level Schedule overview: the most important D8 dates are listed here.

2) High-level Progress overview: progress across all initiatives in 3 phases (discovery, design, development) are clearly visible

3) Calendar overview: Don't miss another important meeting, subscribe to this gcal, or check back on this page to see what's coming up

4) Initiative Info: A general overview of the initiative lead, and some important information links are centralized here.

5) Important places to help: Each initiative has important things they need your help with -- here's where we'll point you to the top issues to look into right now.

6) Scrum notes: We meet bi-weekly, and want to share the discussion topics and next steps with you all. Transparency about the progress and next steps will help you know how things are going.

This is only the first version of this bi-weekly information overview, but we hope it's useful for the community to see what's happening on D8 and to help you identify the most impactful issues for D8 so you can get involved.

If you've got ideas for us, or feedback on this format, please feel free to contact me on twitter at @svettes or via email

Jan 13 2012
Jan 13

As default, Omega uses the h1.title in region--content.tpl.php.
When using panels, the panel title is used in $title. But what will happen if you want to use your headline inside your panel-layout? A use case might be a project where you have both sidebars in some parts of the project and panels in another part "simulating" a sidebar, for instance with block-styled content in the left panel pane, while main content goes into the right one. Now you will have the headline "within" the main content area on a sidebar display, while it's above the main content area on a panel display. If classic blocks are situated in a sidebar and block-styled content in a sidebar-like panel pane, they will now have a different upper margin relatively to the site header and the headline might also "flip" over the blocks on the left hand side.

As this is difficult to explain only using words, we have a little scheme here:

Our goal is that the H1 title headline "optically" behaves the same in the panel context as if we would just have a normal sidebar. So how to do this?

First, we have to add the title to the panel template.
If you use one of Omegas default panel layouts, copy and paste the layout from Omega to yourtheme/panels/layouts/ and open the *.tpl file. Add the h1 to the position where you want ot to appear (normally the main content part).

<h1 class="title" id="page-title"><?php print $display->get_title(); ?></h1>

($display->get_title() will catch the title that is defined in the panel.)

For custom templates, just add this code snippet to the place you want the title to be displayed.

Now the title should be displayed at the correct position. Or, at least, one of two, as now it is probably displayed twice, since it's still in region--content.tpl.php
However, we can't just remove it from there, because it should still be displayed if we are on a non panel page.

To check if the page is displayed with panels, you can use this function.

function has_panel() {
if (panels_get_current_page_display()) {
return true;
return false;

Put this in your template.php

Copy and paste the region--content.tpl from omega to your themes template folder and add the has_panel condition to the title request.

This should look like this:

<?php if ($title): ?>

Transform it to:

<?php if ($title && !has_panel()): ?>

Now it should work! Don't forget to set the titles in Panels now.

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web