Responsive Theming for Drupal (2014)

Chapter 6. Responsive Theming Using Omega

And then there’s Omega. If Zen and Aurora are on the lighter-weight side of base themes, Omega is definitely at the other end. It’s a feature-rich, Sass-based theme that can get you there quickly if you stay on the rails.

A Note About Versions

Omega rose to popularity in version 3, which is worlds different than version 4 (the currently recommended version). Here are just a handful of differences, and this barely scratches the surface:

§  Version 3 does not include any Sass integration or helpers of any kind, and version 4 highly recommends using Sass.

§  Version 3 organized stylesheets primarily by screen width and version 4 gives the user an SMACSS-based code structure by default.

§  Version 3 revolves around building layouts and configuring your theme all in the GUI, whereas version 4 does that stuff in code.

§  Version 3 relies on the Delta module and the Context module to create customized layouts for pages/sections, and version 4 relies on the power of Sass/Compass and a non-GUI “theme API” (discussed later in this chapter) for creating layouts.

§  Version 3 hasn’t seen an update for about a year and a half at this point, and version 4 gets frequent updates.

In this book, we will be talking about version 4, but if you’re the type of person who finds joy in clicking your way through the theming process, you might find a cozy home in version 3 despite the fact that it is stagnant at this point.

Pros and Cons

Omega 4 has a lot going on, for better or worse. Here are a few randomly picked examples:

§  It provides an innovative layout system that lets you define context-sensitive layouts, each with custom regions and CSS.

§  It contains a complete rewrite (“cleanup”) of all of Drupal core’s CSS so that things can be more easily overridden and CSS is more performant and follows best practices.

§  It contains a development extension with tools for things like LiveReload integration, a region demo mode, a browser width indicator for responsive theming, and more.

This is just the tip of the iceberg. Omega is big. So, as with most feature-rich tools, it’s a trade-off between having a powerful setup out of the box that can make you super productive (good) and feeling bogged down by having to do everything a certain way (bad) or feeling overwhelmed by everything that’s going on (also bad).

That said, that’s just the nature of having tools that do a lot for you, and which side you take is a personal decision. It says nothing about why Omega specifically is or isn’t a good tool.

Moving along, Omega is a very popular theme, coming in second only to Zen in the theme usage ranking. This means that the theme has a lot of eyes on it and a lot of people finding and fixing issues so you don’t have to, which is always a good thing. However, the numbers might be a little skewed since a huge chunk of the reported installs are undoubtedly version 3. This means that version 4 might be a good bit less popular than you would think based on the total number alone.

Another downside of the version 3 versus version 4 split is that a lot of the documentation and QA you find on “Omega” is actually for “Omega 3,” which can be frustrating for users trying to learn the ropes of version 4. That said, Omega’s official documentation for 4.x is quite good.

Finally, it should be noted that version 4 is maintained by Sebastian Siemssen (“fubhy”), who is quite well respected in the community, so that should definitely be a confidence booster to anyone window shopping for base themes.

Getting Started

Using Omega means that you’ll be setting up a subtheme of Omega and altering it with the full power of Sass/Compass at your fingertips. In other words, this section is almost identical to the corresponding sections on Aurora (Getting Started) and Zen (Getting Started). However, there are some tricky differences, as there always tend to be, so let’s start at the beginning.

Step 1: Install Sass/Compass

You’ll need to install Sass and Compass as outlined in Chapter 3.

Step 2: Create Your Subtheme Using Drush

Omega comes with very useful Drush integration, and creating a subtheme is a great example of this. Omega provides a Drush wizard that guides you through the process of creating a sub-theme, asking questions along the way, until finally exporting a customized and ready-to-hack-on subtheme based on your answers.

To trigger this, run:

drush omega-wizard

Here are the questions it will run you through, along with some tips for answering:

Please enter the name of the new subtheme [Omega Subtheme]:

Just enter the human-readable name for your theme. Typically this will be based on the name of the website, client, or app itself.

Please enter a machine-readable name for your new theme [omega_subtheme]:

Typically, the default (the value in the square brackets) will be fine. It just converts your subtheme name from the last answer to a machine name by lowercasing and replacing spaces with underscores.

Please choose a base theme for your new theme:

§  [0] : Cancel

§  [1] : Ohm (Subtheme of Omega) - Omega based demonstration theme. Serves as a best-practice reference for the Omega documentation. Ohm will be constantly updated as best practice evolves so shouldn’t be used in production.

§  [2] : Omega - A powerful HTML5 base theme framework utilizing tools like Sass, Compass, Grunt, Bower, Ruby Version Manager, Bundler and more.

Just enter 2 here, because you want to use Omega.

Please choose a starterkit for your new theme:

§  [0] : Cancel

§  [1] : Default: Comes with a well organized Sass setup with heavy use of partials. (Provided by Omega)

Enter 1 here, obviously.

Please choose a destination type:

§  [0] : Cancel

§  [1] : Site (e.g. all or example.com)

§  [2] : Installation profile

§  [3] : Parent theme

Usually you’ll want to use 1 for this, because it will go in sites/all/themes or sites/sitename.com/themes, but if you’re building a distribution you might want it put directly into an install profile. For this example, let’s enter 1.

Please choose a site:

§  [0] : Cancel

§  [1] : all

You will get more options here if you have more directories under /sites than just /sites/all and /sites/default, and if you’re doing a multisite setup you will definitely want to be mindful of which directory gets the theme. In most cases, though, “all” should be fine, so we’ll enter 1.

Do you want to keep the starterkit’s readme files? (y/n)

Sure, why not? Let’s enter “y.”

Do you want to enable your new theme? (y/n):

Yep, might as well. Enter “y.”

Do you want to make your new theme the default theme? (y/n):

Again, might as well. Enter “y.”

That should be the end of the wizard, so you’ll see some output that looks like this, except with your custom theme name on the last line instead of “Theme Name”:

Beginning to build libraries.make.

selectivizr downloaded from https://github.com/fubhy/selectivizr/archive/master.zip.

html5shiv downloaded from https://github.com/fubhy/html5shiv

  /archive/master.zip.

respond downloaded from https://github.com/fubhy/respond/archive

  /master.zip.

matchmedia downloaded from https://github.com/fubhy/matchmedia/archive/master.zip.

pie downloaded from https://github.com/fubhy/pie/archive/master.zip.

You have successfully created the theme Theme Name (theme_name) in

  sites/all/themes.

So now we can head on over to sites/all/themes/theme_name (or whatever you named yours) and check out our brand new subtheme.

Drush Integration

When I said that Omega has good Drush integration, I meant it. Here’s the full list of Drush commands that come bundled with Omega:

§  omega-export (oexp): Exports the theme settings of a given theme from the database to the .info file.

§  omega-guard (ogrd): Runs guard for the given theme including Compass and LiveReload by default. We will discuss this in a bit.

§  omega-revert (orev): Reverts the theme settings of a given theme by deleting them from the database.

§  omega-subtheme (osub): Creates an Omega subtheme in one step. Requires you to provide options/flags to the command rather than answering questions like the wizard does. Useful for scripting, but not recommended for human usage.

§  omega-wizard (owiz): Guides you through a wizard for generating a subtheme. This is the proper way for people to create sub-themes.

Also, if you happen to run into a Drush error, you likely need to clear Drush’s cache using this command:

drush cc drush

Taking an Omega Tour

There’s a lot going on in the average Omega subtheme directory. Let’s take a deep dive. Here’s what the tree looks like (given a subtheme with a machine name of “test”):

├── bower.json

├── config.rb

├── css

│   ├── test.hacks.css

│   ├── test.no-query.css

│   ├── test.normalize.css

│   └── test.styles.css

├── Gemfile

├── Gruntfile.js

├── Guardfile

├── images

│   └── README.txt

├── js

│   └── test.behaviors.js

├── libraries

│   ├── html5shiv

│   │   ├── html5shiv.js

│   │   ├── html5shiv.min.js

│   │   ├── html5shiv-printshiv.js

│   │   └── html5shiv-printshiv.min.js

│   ├── matchmedia

│   │   ├── matchmedia.js

│   │   └── matchmedia.min.js

│   ├── pie

│   │   ├── PIE.htc

│   │   └── PIE.js

│   ├── respond

│   │   ├── respond.js

│   │   └── respond.min.js

│   └── selectivizr

│       ├── selectivizr.js

│       └── selectivizr.min.js

├── libraries.make

├── logo.png

├── package.json

├── preprocess

│   ├── page.preprocess.inc

│   └── README.md

├── process

│   ├── page.process.inc

│   └── README.md

├── sass

│   ├── abstractions

│   │   └── README.md

│   ├── base

│   │   ├── _forms.scss

│   │   ├── _lists.scss

│   │   ├── _media.scss

│   │   ├── README.md

│   │   ├── _tables.scss

│   │   └── _typography.scss

│   ├── components

│   │   ├── _navigation.scss

│   │   ├── README.md

│   │   └── _search.scss

│   ├── README.md

│   ├── test.hacks.scss

│   ├── test.no-query.scss

│   ├── test.normalize.scss

│   ├── test.styles.scss

│   └── variables

│       ├── _colors.scss

│       ├── _legacy.scss

│       ├── README.md

│       └── _typography.scss

├── screenshot.png

├── template.php

├── templates

│   └── README.md

├── test.info

├── theme

│   └── README.md

└── theme-settings.php

Pretty intimidating, huh? Well, the good news is that a lot of that can safely be ignored for now, such as some of the configuration files (such as GemfileGuardfile, and Gruntfile.js, among others), the compiled CSS, and everything under /libraries. Here’s a trimmed down version of the same thing, with everything we won’t need to concern ourselves with removed:

├── config.rb

├── images

├── js

│   └── test.behaviors.js

├── preprocess

│   ├── page.preprocess.inc

├── process

│   ├── page.process.inc

├── sass

│   ├── abstractions

│   ├── base

│   │   ├── _forms.scss

│   │   ├── _lists.scss

│   │   ├── _media.scss

│   │   ├── _tables.scss

│   │   └── _typography.scss

│   ├── components

│   │   ├── _navigation.scss

│   │   └── _search.scss

│   ├── test.hacks.scss

│   ├── test.no-query.scss

│   ├── test.normalize.scss

│   ├── test.styles.scss

│   └── variables

│       ├── _colors.scss

│       ├── _legacy.scss

│       └── _typography.scss

├── screenshot.png

├── template.php

├── templates

├── theme

That’s a much less scary directory tree, no? And most of those subdirectories are pretty self-explanatory. Here’s some info on each of them:

├── images: theme-specific images such as background images and icons go here.

├── js: theme-specific JS that doesn't make sense to put into a custom module

    goes here

├── preprocess: implementations of preprocess functions go here

├── process: implementations of process functions go here

├── sass: this holds all of your SCSS files

│   ├── abstractions: Sass mixins, extends and functions for general use.

│   ├── base: styles for basic HTML elements (no classes or IDs) go here.

│   ├── components: i.e., "modules" in SMACCS (as discussed in Chapter 5).

        More on this below.

│   └── variables: reusable Sass variables such as colors, font-stacks, borders,

        etc., go here.

├── templates: this holds all of your theme's .tpl.php files.

├── theme: this neat directory holds all of your themename_* functions that

    would typically go in template.php in other themes. More on this below.

Of those, there are perhaps only two that are a bit tricky.

The first, /sass/components, can be a bit confusing because the typical question is “what is a component?” Luckily, Omega throws us a bone with a README.md in that directory that tells us exactly that. In the words of the README, “Components are discrete parts of your page that should sit within the regions of your layouts. You should try to abstract your components as much as possible to promote reuse throughout the theme.”

Some common examples in Drupal include things like blocks, specific content types such as viewing an article node (and the individual fields can be subcomponents), individual forms such as the login form and the search form, and specific views.

The second tricky directory is /theme, which is interesting for two reasons. One, because in just about any other theme, you’d put all that stuff (i.e., themename*, such as themename_breadcrumb() and themename_button()) into template.php, and two, because it has some neat auto-discovery of filenames based on the functions they contain. The gist is that you can create files in the convention of <thing-you-are-theming>.theme.inc which contain themename_thing-you-are-theming_() implementations and it will auto-load them, enabling you to split all that stuff up really cleanly and easily.

For example, if you need to implement themename_breadcrumb(), put it in theme/breadcrumb.theme.inc. Note that underscores should become hyphens in filenames, so if you’re implementing themename_menu_link() you’ll want to put it in theme/menu-link.theme.inc.

Responsive Layouts Using Singularity Grids

Omega, like Aurora, encourages using the Singularity grid system. We’ve already discussed that one (see Chapter 4), so for the sake of completeness, let’s talk about a popular alternative by the name of Susy. Susy is a well thought-out grid system which was also used by Aurora before Aurora’s own the switch to Singularity.

First of all, you’ll need to install Susy, since it doesn’t come by default. This is easy enough by just running:

gem install susy

Along with that, you’ll also probably want to add it to your Gemfile.

Secondly, if you’re familiar with Sass and getting acquainted with Susy, it can be very helpful to turn on the debugging grid backgrounds like this:

@include susy-grid-background

You will want to do this under each at-breakpoint to see the different grids take effect.

Now we can build a grid with Susy. We’ll start by adding some configuration variables. Create a new file in /sass/variables called _layout.scss, and fill it up with something like this:

$total-columns  : 7;

$column-width   : 4em;

$gutter-width   : 1em;

$grid-padding   : $gutter-width;

Easy enough, right? We want a seven-column grid where each column is 4ems wide and each gutter is 1em wide, plus we also have 1em of padding.

As for making individual elements conform to the grid, this is also quite simple using the span-columns() mixin. The basic syntax for this mixin is as follows:

span-columns(<$columns> [<omega> , <$context>, <$padding>, <$from>, <$style>])

As for what those placeholders mean:

§  <$columns>: The number of columns to span.

§  <omega>: Optional flag to signal the last element in a row.

§  <$context>: Current nesting context. Default: $total-columns.

§  <$padding>: Optional padding applied inside an individual grid element. Given as a length (in the same units as the grid) or a list of lengths (from-direction to-direction). Default: false.

§  <$from>: The origin direction of your document flow. Default: $from-direction.

§  <$style>: Optionally return static lengths for grid calculations. Default: $container-style.

With that in mind, aligning things into the grid is as simple as adding that mixin to them, like so:

#login-form {

  @include span-columns(3, 12);

}

Now is a good time to note that Omega also relies heavily on Breakpoint, as does Aurora, so the knowledge from Chapter 4 on targeting specific breakpoints will be true here as well.

Making Use of Custom Layouts

One of Omega’s unique features is the ability to create completely custom layouts and tell the site to use them on specific pages.

In Omega 3.x, this was done in the UI, but Omega 4.x forces you to do it in code. To start, you’ll need to copy the layouts/ directory and its contents from the base Omega theme, then paste it into the subtheme you created.

Once inside the subtheme’s layouts/ directory, rename “simple” to whatever you’d like to call your new layout. For example, if you’re creating a layout to be used on directory pages, you could call it “directory.”

Once that’s done, you’ll also need to rename the other miscellaneous files inside that directory by replacing “simple” with “directory.” This will include three files: sass/layouts/simple.layout.scsslayouts/simple-layout.tpl.php, and layouts/simple.layout.inc.

So rename those files by replacing “simple” with “directory,” then make sure to open them up and find/replace all other instances of that word.

Now that that’s done, let’s talk about what those files do:

LAYOUTNAME.layout.inc

This file provides some basic info about the layout and lists the regions within it. You can change the regions by adding new ones or removing default ones. As a quick example, if you want to add a new “Featured” region, you’d need to add regions[featured] = Featured in this file. Note that if you’re adding a new region or changing region names, you must also have a matching region in the .info file.

LAYOUTNAME-layout.tpl.php

This is just a regular old Drupal page template for the layout. This is where the regions listed in LAYOUTNAME.layout.inc will actually be outputted, so don’t forget to update this file as well if you change your regions in the .inc file.

NEWLAYOUT.layout.scss

This is an SCSS file that generates the CSS which actually builds the layout. It makes use of Susy and Compass, so you should feel right at home.

So now you have the three ingredients you need for your layout: CSS (i.e., Sass), HTML/content (i.e., the .tpl.php file), and some metadata (i.e., the .inc file). It’s a lot like a mini one-template theme if you think about it in that regard.

From here, the process should seem fairly straightforward. Add your Sass rules to the .layout.scss file and customize your regions in the .inc and the .tpl.php files, along with customizing your static markup in the .tpl.php file.

The next step in the process is to make the layout actually apply to some page(s) on the site. There are a few ways you can do this. The easiest way is by using the Delta module in combination with Context or Panels to switch layouts based on a GUI-defined set of rules in one of those two modules.

That said, in the spirit of getting our hands dirty and maintaining absolute control, I’d like to focus on the code-based method for applying a layout. That is, rather than using a GUI-based solution like Delta + Context to choose layouts based on certain URLs or triggers, we can swap layouts as needed in code so that we have full control.

Open up your subtheme’s template.php file and throw in something that looks like this:

function THEMENAME_omega_layout_alter(&$layout) {

  if (arg(0) == 'node' && is_numeric(arg(1))) {

    $nid = arg(1);

    $node = node_load($nid);

    if (isset($node) && $node->type == 'page') {

      $layout = 'LAYOUTNAME';

    }

  }

}

You’ll want to update the THEMENAME and LAYOUTNAME in that chunk of code, but other than that it should be fairly straightforward. As you can see, that code applies the LAYOUTNAME layout to all Page nodes. You can use the full power of the Drupal API and PHP to select a layout here, so there’s really a lot of power. Plus, if you get stuck, you can always fall back on Delta along with Context or Panels to rescue you.

And there we have it. As I mentioned earlier, there’s really a lot to Omega and we only touched on a few basics. If you want to see more of what Omega brings to the table, check out Joel Moore’s demo video.