Aug 02 2018
Aug 02

One of the most popular components on any website I've worked on is the card component.  Depending on the website, the card component is used to group various pieces of content into a container which can be used throughout your website.  Here’s an example of a card component in one of our projects.

In some instances, a card can be a user profile, content teaser/excerpt, latest news or events.  Today we will build a card component which will contain the information for the latest events.  This card can be used in the /events page to list all the latest events taking place.  The card can also be used in other pages and it may need to be displayed slightly different than the original card, this transformation is called "variations" and is usually achieved by passing a modifier CSS class to the original component which we can use to write different styles for the card.  More on this later.

Let's get started

First, let's take a look at what we are building so we have a visual of the code we will be writing.

Component Example 1

As you can see from the images above, our card takes different shapes but the information in it remains the same or similar.  This is a common practice to modify components based on where and how they are being displayed.

Let's build the card

Identify component's fields

Before starting to write any code, let's take a close look at the card images to identify the fields or data elements the card needs.  From the images above we can see the following fields will be needed:

  • Image
  • Title
  • Subtitle
  • Excerpt
  • Label or category
  • Label for comments
  • Label for time posted

Typically, components are built following the Atomic Design approach which basically means breaking things down into small pieces (atoms) and then combining those pieces to build more elaborate components.

In the interest of time, we are going to skip building each piece as its separate component and instead we will build the card as a whole.  I recently wrote a blog post on building flexible headings which demonstrate the approach I usually take when building components.

Architecting the component fields

We know the fields we need but it is helpful to determine what type of fields they are and what they will be called.  The table below gives us a good visual of our fields architecture.

List of Example Component Fields

Writing the code

1. In your components or patterns directory in your project, create a new folder called `card`

2. Inside the Card folder create two new files
          -  card.html
          -  card.css (we're using CSS to keep things simple.  Feel free to use Sass if you'd like).

3. In your card.html we'll start with the basic structure of the card

<article class="card">...</article>

So we've created an article tag as the card's container.  Why <article>  and not <div>?  Well, since the card is intended to contain an event's info, if we place a bunch of cards together it makes sense that each card is an individual event article.

4. Next we are going to create wrappers for the two types of data the card will hold.  The two types of data as we have seen from the table above are: Image/media and text or content.  Let's modify our code so it looks like this:

<article class="card">
 <div class="card__media">...</div>
 <div class="card__content">...</div>
</article>

The reason for splitting the image and the rest of the content is that this allows us to move things around independently of each other to create different variations of the card.  More on this later.

Let's pause to review how content will be laid out

If we look at the card images above, we see that some of the fields are either on the image side and others are grouped together separate from the image.  Although we could potentially place fields in the image or content wrappers, it makes sense to place them in the wrapper where they visually appear.

For example, the date and label fields (Photos), look like they belong in the same group as the image.  The rest of the fields will go in the Content wrapper.

5. Let's start with the image wrapper:

<article class="card">
 <div class="card__media">
   <img src="http://placehold.it/300x300" alt="Card image" />
   <div class="card__date">
     <span class="date--day">27</span>
     <span class="date--month">Mar</span>
   </div>
   <span class="card__category">Photos</span>
 </div>

 <div class="card__content">...</div>
</article>

So let's focus in the fields inside card__media. We see we have our image, which in this case is rendering a placeholder image.  Then we have a wrapper to hold the date fields (day and month).  Again, wrapping these two together makes it easy to manipulate them as a single item rather than two separate fields.  Lastly, we have the category for this content (Photos).  Since all these fields seem to belong together, it makes sense to place them the way we have.  Later on, we will use CSS to place each of the fields in their right position.

6. Now let's place the remaining fields inside the .card__content wrapper.  We will temporarily hide the fields in the .card__media wrapper to focus on the other fields.  Modify your markup to look like this:

<article class="card">
 <div class="card__media">...</div>

 <div class="card__content">
   <header class="card__header">
     <h2 class="card__title">City Lights in New York</h2>
     <div class="card__subtitle">The city that never sleeps</div>
   </header>
   <p class="card__excerpt">New York, the largest city in the U.S., is an architectural marvel with plenty of historic monuments, magnificent buildings and countless dazzling skyscrapers.</p>

   <footer class="card__meta" role="contentinfo">
     <span class="card__post-date">6 min ago</span>
     <span class="card__comments">39 comments</span>
   </footer>
 </div>
</article>

So the first thing we did was add a `<header>` tag to wrap the title and subtitle fields.  The header tag is a great way to indicate the role content plays in our component.  In addition, using semantically correct markup makes this component SEO friendly as well as accessible.  Next we have the teaser content wrapped in a <p> tag and finally, we add another semantic tag which is `footer` to wrap the publish date and comments fields.

Why this markup?

I'd like to bring up a couple of things to your attention regarding how I arrived at the markup above.  First, we are using BEM for naming CSS classes (card__title, card__comments, etc.).  BEM is great for creating associations on your component fields.  By looking at the markup you know where each field belongs.  This makes it easier to identify where you would find the styles or other assets for the component within your project when you have tons and tons of components.  The class card and all the other field classes are unique not only to this component but in the entire project.  This gives us the peace of mind that our styles will not inadvertently affect other areas of the website.

Notice I created two containers within the card (`card__media` and `card__content`). This allows me to split the card content into groups I can manipulate individually and independently of each other.  This will come in handy when we need to create a long or wide card.  In addition, by grouping multiple fields into a single container it is easier to manipulate the fields with CSS as a group rather than individually.

Atomic Design

If you are familiar with Atomic Design, you know the recommended way for building components is to break things down into the smallest pieces possible.  For example, in the card structure above, each of the fields that make up the card can actually be its own individual component.  Then we would combine them all into a whole new component (card).  In the interest of time/work, I am not breaking the card component into atoms. However, if I were building the card for a project I would definitely do that as this allows for components to be reused and save time/work in the long road.

Putting the entire card together

Now that we have built each piece of the card, your **card.thml** file should look like this:

<article class="card">
 <div class="card__media">
   <img src="http://placehold.it/300x300" alt="Card image" />
   <div class="card__date">
     <span class="date--day">27</span>
     <span class="date--month">Mar</span>
   </div>
   <span class="card__category">Photos</span>
 </div>

 <div class="card__content">
   <header class="card__header">
     <h2 class="card__title">City Lights in New York</h2>
     <div class="card__subtitle">The city that never sleeps</div>
   </header>
   <p class="card__excerpt">New York, the largest city in the U.S., is an architectural marvel with plenty of historic monuments, magnificent buildings and countless dazzling skyscrapers.</p>

   <footer class="card__meta" role="contentinfo">
     <span class="card__post-date">6 min ago</span>
     <span class="card__comments">39 comments</span>
   </footer>
 </div>
</article>

Card Styles

Now that we have the markup ready for the card component, we can begin writing our Sass/CSS to style it.  I am not going to go into detail about the styles as I have commented the parts that may need some explanation and should be easy to understand.  The main take away from writing styles for components with unique names is that there is little to no CSS nesting.  This makes overriding styles an easy task if there is ever a need to do so.  In addition, styles written for a component like this, don't run into the risk of leaking into other areas of the website.

That's a lot of CSS but it's all necessary to achieve the look and feel of the card.  It is important to know that your markup file (card.html), needs to reference your styles file (card.css) for things to work.  This may be obvious but if you are following along that's an extra step that needs to be done.
Creating a card variation

If  you would like to see the card displayed wide or horizontally, modify your card wrapper to look like this:

<article class="card card--wide">...</article>
 

Component Example 2

Notice that by passing the CSS class of `card--wide` to the original card component we are able to change the orientation of the card from long to wide giving us an alternative variation to use without having to rebuild the card from scratch.  These variations are pretty powerful and present many advantages.

If you look at the styles, you will notice there is a block of CSS in which the card--wide is changed to move the card's content to the right of the image.  This is a great way to provide alternative views of a component without having to recreate the markup or styles for a component.

In closing

Building components is one of my favorite things to do as a developer and there are many advantages to this style of theming.  It's important to think through how components will be used so you can plan ahead how to best build a component that can be reused.  Rushing through building components without having a full understanding of where and how a component may be used can lead to duplicating code or redoing your work to accommodate new project requirements.

Sep 06 2016
Sep 06

Base themes in Drupal are incredibly useful but often add bloat to the finished sub-theme when care isn’t taken to remove unnecessary css files, or files that are 5% used and 95% overridden. When porting aGov to Drupal 8 we took the opportunity to improve how it’s theme inheritance is managed, making it easier to create trim, lightweight sub-themes.

Drupal 7 inheritance

In Drupal 7 you could remove a stylesheet by referencing it in your sub-themes .info file - regardless of if it came from core, another module or a base theme.

For example adding the following line to your theme would prevent the base theme from loading that file (let’s just pretend it does have one with this name);

stylesheets[all][] = component.primary-navigation.css

Which is great if you don’t want any of it’s CSS. If you’re adding your own css just give your file the same name and Drupal will load it instead of the base themes one - not in addition to.

The same goes for Javascript files.

Drupal 8 can do the same thing only way better! Drupal 8 themes can have Libraries. So can modules and profiles but we’ll just focus on themes. A library can be a collection of CSS and JS and can even list it’s dependencies. Here’s what a library might look like:

primary-navigation:
 version: 1.x
 css:
   component:
     css/components/primary-navigation/primary-navigation.css: {}
 js:
   sass/components/primary-navigation/primary-navigation.js: {}
 dependencies:
   - core/jquery

This bundles everything required for the primary navigation block into one easy to manage chunk. Those curly brackets can contain extra options, like { media: print }, or if it’s an external file like your Google font:

//fonts.googleapis.com/css?family=Open-sans: { type: external, minified: true }

But why bother breaking all your CSS components out like this?

If you’re like me, you use a CSS preprocessor like Sass and compile all your components, base styles and layouts into one CSS file. Which you can still do in your sub-theme if you like, but if you divvy up your base theme into discrete Libraries it’s super easy to toggle them on/off in your sub-theme!

Say your sub-theme has an entirely different vertical/offscreen/multi-level/hamburger navigation, and the base theme only gives you a simple horizontal nav? You don’t want any of the primary-navigation CSS, Javascript or dependencies from the base theme because you need to start from scratch.

Just override it in your theme’s .info.yml file:

libraries-override:
 base-theme-name/primary-navigation: false

You can remove a module, profile or core library the same way. Just want to override a library? Say you’re theme requires a more extended version of modernizr than comes with core:

libraries-override:
 core/modernizr:
  js:
    assets/vendor/modernizr/modernizr.min.js: js/modernizr.min.js

Note the last line references the original file and is followed by the new file we’re including in our theme.

Drupal still has the same option to remove individual CSS files (or JS files), which also goes in the .info.yml file and looks like the following:

stylesheets-remove:
- '@base-theme-name/css/base/normalize.css'

That @ symbol is a shortcut to that themes name so you don’t have to worry about the path to the theme, just it’s name - so @classy or @stable works just the same.

The 8.x branch of aGov has taken this approach for the most part, though it could be extended. The base theme is monochromatic but does have a few styles included to make it easy for people to get started and not be distracted by its blueness.

They’ve been broken up into the following Libraries:

  • Base (normalize styles and basic typography)
  • Base Components (components that don’t change very often like system messages, breadcrumbs etc)
  • aGov Components (ones that do change often and are more likely to be overridden)
  • Layout (basically the grid system)

You can see the full breakdown on github.

Then the Starterkit theme lists all the libraries and individual stylesheets (though commented out) in their respective ‘libraries-override’ and ‘stylesheets-remove’ sections to make it super easy to disable them and create your own. Check out it’s .info.yml file on github.

Stable in Drupal 8 core has a LOT of library overrides so worth a look at it’s examples. Classy is also worth a look, particularly at using the weights option.

Zen (https://www.drupal.org/project/zen) takes the Libraries approach in its Starterkit and is a great example of using components.

Omega 5 (https://www.drupal.org/project/omega) has quite a complex Libraries list so is handy to see just what’s possible.

aGov Theming Drupal 8
Oct 23 2015
FEM
Oct 23

One reason WordPress has been gaining exponentially on Drupal over the past few years has partly been because of the massive amount of premium themes and plugins available. Slick themes with easy admin UIs and plenty of options, they are mobile responsive and have slick JQuery/Ajax integration using some of the best plugins. Drupal simply does not have this industry that has grown up around WordPress theming. Though Drupal is catching up and there are plenty of themes available for now at least WordPress has won the hearts and minds of the majority, particularly those without much technical expertise and it has proved the clear winner for small businesses and those who really do not want to get their hands dirty.   Drupal 8 has done a lot to cater more to the end user but we will have to see how that plays out.

The dark of all these theming and plugin options  is separating the wheat from the chaff so to speak. This is also the case with the myriad of plugins available. While drupal.org, has a peer reviewal system similar to those of scientific journals which vets every piece of code before it makes it onto Drupal.org, WordPress does not have this, and finding trusted code is about as easy as navigating the wild west. There are plenty of good resources out there but it is easy to get lost in sea of for profit plugins and themes available out there, recently I have been helping out at Themeshift.com a different way to think about the theming marketplace. Rather than display every single theme that has ever been made and make the user sort through endless options, Themeshift has a few carefully selected and curated premium themes chosen by expert WordPress developers. I have been in the position where I was waiting on clients to choose a theme, and they spend hours wading through Google, when they eventually do settle on one they like they end up purchasing one or too more until they find something they actually want to use. Themeshift takes a different view with a “curated” approach. Here the developers behind the site have taken the time to develop and choose themes that are AAA and that fit a wide variety of needs. A developer curated theming website which provides exceptional support and it is easy to reach actual humans if you have questions. It is in effect a premium segment of the “premium WordPress theme” demographic. For those that want the best and don’t want to be dealing with agents who often experience communication or cultural issues. With teams based out of both NYC and Germany Themeshift caters to a high end cleintele of developers and end users who want to buy themes from individuals they know are available and are up to date with the latest technology and design trends. Check it out and let me know what you think of my new venture, all feedback is taken into consideration!

Aug 28 2015
Aug 28

In my previous post I outlined how to build a Sass directory within a custom Drupal theme including Bourbon and Neat.

At this point, we’re ready to write some SCSS within the base, components, and layouts directories. In this post I’ll demonstrate how Savas Labs applies SMACSS principles to organize our custom SCSS. As a reminder, I’ll be linking to our Drupal 8 mapping site as an example throughout, but none of this is Drupal-8-specific.

Drupal-flavored SMACSS

When we left off, our sass directory looked like this:

# Inside the custom theme directory
sass
├── _init.scss
├── base
├── components
├── layouts
├── lib
│   ├── bourbon
│   ├── font-awesome
│   └── neat
└── styles.scss

At this point we’re ready to start styling. Let’s take a look at the three folders that will hold our custom .scss files, which are loosely based on SMACSS. Acquia has a nice writeup of how SMACSS principles can be applied to Drupal, but I like to simplify it even further.

Base

I personally only have three files in the sass/base directory. Don’t forget that we already imported these three partials in styles.scss.

For full examples of each of these files, check out our base directory.

_normalize.scss

This is simply normalize.css renamed as _normalize.scss - remember that CSS is valid SCSS. Thoughtbot recommends using normalize.css as your CSS reset along with Neat. Regardless of which reset you use, include it in base.

_base.scss

This is for HTML element styles only. No layout, no classes, nothing else. In here I’ll apply font styles to the body and headings, link styles to the anchor element, and possibly a few other site-wide styles.

_variables.scss

This is where I house all of my Sass variables and custom mixins. I typically have sections for colors, fonts, other useful stuff like a standard border radius or spacing between elements, variables for any Refills I’m using, and custom mixins.

I’d definitely recommend including _normalize.scss in base if you’re using Neat, but other than that do what works for you! If you’re following my method, your sass folder should be looking like this:

# Inside the custom theme directory
sass
├── _init.scss
├── base
│   ├── _base.scss
│   ├── _normalize.scss
│   └── _variables.scss
├── components
├── layouts
├── lib
│   ├── bourbon
│   ├── font-awesome
│   └── neat
└── styles.scss

Layouts

This directory holds page-wide layout styles, which means we’ll be making heavy use of the Neat grid here. This is flexible, but I recommend a single .scss partial for each unique template file that represents an entire page. Think about what works best for your site. For the sake of our example, let’s say we’re creating _front-page.scss and _node-page.scss. I like to also create _base.scss for layout styles that apply to all pages.

Remember that these styles only apply to the page’s layout! I occasionally find myself moving styles from the layouts directory to base or components when I realize they don’t only define layout. In these partials, you should be doing a lot of grid work and spacing. This is the entirety of my sass/layouts/_base.scss file on our mapping site:

/**
 * @file
 *
 * Site-wide layout styles.
 */

body {
  @include outer-container();

  main {
    @include span-columns(10);
    @include shift(1);
    @include clearfix;

    h1 {
      margin-top: em($navigation-height) + $general-spacing;
    }
  }
}

We’re almost there:

# Inside the custom theme directory
sass
├── _init.scss
├── base
│   ├── _base.scss
│   ├── _normalize.scss
│   └── _variables.scss
├── components
├── layouts
│   ├── _base.scss
│   ├── _front-page.scss
│   └── _node-page.scss
├── lib
│   ├── bourbon
│   ├── font-awesome
│   └── neat
└── styles.scss

Components

In SMACSS this is called “modules,” but that gets a little confusing in Drupal Land. This is for applying layout and theme styles to smaller chunks of your site, which in Drupal typically means regions. Create a separate partial for each region, or if you have several distinct components within a region, consider a separate partial for each of them.

Let’s say we created partials for the header, footer, and sidebar regions, plus one for non-layout node page styles. At this point, our sass directory is looking like this:

# Inside the custom theme directory
sass
├── _init.scss
├── base
│   ├── _base.scss
│   ├── _normalize.scss
│   └── _variables.scss
├── components
│   ├── _node-page.scss
│   └── regions
│       ├── _footer.scss
│       ├── _header.scss
│       └── _sidebar.scss
├── layouts
│   ├── _base.scss
│   ├── _front-page.scss
│   └── _node-page.scss
├── lib
│   ├── bourbon
│   ├── font-awesome
│   └── neat
└── styles.scss

Now we’ve got a nicely organized, easy to navigate Sass directory, ready to hold your styles and compile them into one beautiful CSS file!

But how do we ensure that our one CSS file really is beautiful? Check out my final post about best practices for writing Sass that you can easily maintain or pass off to another developer.

Aug 27 2015
Aug 27

In my previous post I outlined how to build a Sass directory within a custom Drupal theme including Bourbon and Neat.

At this point, we’re ready to write some SCSS within the base, components, and layouts directories. In this post I’ll demonstrate how Savas applies SMACSS principles to organize our custom SCSS. As a reminder, I’ll be linking to our Drupal 8 mapping site as an example throughout, but none of this is Drupal-8-specific.

Drupal-flavored SMACSS

When we left off, our sass directory looked like this:

# Inside the custom theme directory
sass
??? _init.scss
??? base
??? components
??? layouts
??? lib
?   ??? bourbon
?   ??? font-awesome
?   ??? neat
??? styles.scss

At this point we’re ready to start styling. Let’s take a look at the three folders that will hold our custom .scss files, which are loosely based on SMACSS. Acquia has a nice writeup of how SMACSS principles can be applied to Drupal, but I like to simplify it even further.

Base

I personally only have three files in the sass/base directory. Don’t forget that we already imported these three partials in styles.scss.

For full examples of each of these files, check out our base directory.

_normalize.scss

This is simply normalize.css renamed as _normalize.scss - remember that CSS is valid SCSS. Thoughtbot recommends using normalize.css as your CSS reset along with Neat. Regardless of which reset you use, include it in base.

_base.scss

This is for HTML element styles only. No layout, no classes, nothing else. In here I’ll apply font styles to the body and headings, link styles to the anchor element, and possibly a few other site-wide styles.

_variables.scss

This is where I house all of my Sass variables and custom mixins. I typically have sections for colors, fonts, other useful stuff like a standard border radius or spacing between elements, variables for any Refills I’m using, and custom mixins.

I’d definitely recommend including _normalize.scss in base if you’re using Neat, but other than that do what works for you! If you’re following my method, your sass folder should be looking like this:

# Inside the custom theme directory
sass
??? _init.scss
??? base
?   ??? _base.scss
?   ??? _normalize.scss
?   ??? _variables.scss
??? components
??? layouts
??? lib
?   ??? bourbon
?   ??? font-awesome
?   ??? neat
??? styles.scss

Layouts

This directory holds page-wide layout styles, which means we’ll be making heavy use of the Neat grid here. This is flexible, but I recommend a single .scss partial for each unique template file that represents an entire page. Think about what works best for your site. For the sake of our example, let’s say we’re creating _front-page.scss and _node-page.scss. I like to also create _base.scss for layout styles that apply to all pages.

Remember that these styles only apply to the page’s layout! I occasionally find myself moving styles from the layouts directory to base or components when I realize they don’t only define layout. In these partials, you should be doing a lot of grid work and spacing. This is the entirety of my sass/layouts/_base.scss file on our mapping site:

/**
 * @file
 *
 * Site-wide layout styles.
 */

body {
  @include outer-container();

  main {
    @include span-columns(10);
    @include shift(1);
    @include clearfix;

    h1 {
      margin-top: em($navigation-height) + $general-spacing;
    }
  }
}

We’re almost there:

# Inside the custom theme directory
sass
??? _init.scss
??? base
?   ??? _base.scss
?   ??? _normalize.scss
?   ??? _variables.scss
??? components
??? layouts
?   ??? _base.scss
?   ??? _front-page.scss
?   ??? _node-page.scss
??? lib
?   ??? bourbon
?   ??? font-awesome
?   ??? neat
??? styles.scss

Components

In SMACSS this is called “modules,” but that gets a little confusing in Drupal Land. This is for applying layout and theme styles to smaller chunks of your site, which in Drupal typically means regions. Create a separate partial for each region, or if you have several distinct components within a region, consider a separate partial for each of them.

Let’s say we created partials for the header, footer, and sidebar regions, plus one for non-layout node page styles. At this point, our sass directory is looking like this:

# Inside the custom theme directory
sass
??? _init.scss
??? base
?   ??? _base.scss
?   ??? _normalize.scss
?   ??? _variables.scss
??? components
?   ??? _node-page.scss
?   ??? regions
?       ??? _footer.scss
?       ??? _header.scss
?       ??? _sidebar.scss
??? layouts
?   ??? _base.scss
?   ??? _front-page.scss
?   ??? _node-page.scss
??? lib
?   ??? bourbon
?   ??? font-awesome
?   ??? neat
??? styles.scss

Now we’ve got a nicely organized, easy to navigate Sass directory, ready to hold your styles and compile them into one beautiful CSS file!

But how do we ensure that our one CSS file really is beautiful? Check in next week when I talk about best practices for writing Sass that you can easily maintain or pass off to another developer.

About the author

Anne Tomasevich

Recent posts by Savas

Drupalcamp Asheville - an all around success!

A step-by-step tutorial on setting up Bourbon and Neat and compiling it all with Compass.

We’re giving two presentations at Drupalcamp Asheville!

Aug 21 2015
Aug 21

Recently Savas Labs built a custom Drupal 8 theme using Bourbon for mixins and Neat as our grid framework, applying our favorite parts of SMACSS principles and focusing on creating organized, maintainable code. The result? Fast, easy coding and a relatively lightweight theme.

In this three-part series I’ll detail:

I’ll be pulling some examples from our Drupal 8 theme, but none of this is Drupal-8-specific and really, it’s not entirely Drupal-specific. These principles can be applied to any site. Much of the material in these posts is also largely a matter of opinion, so if you disagree or if something else works better for you, sound off about it in the comments!

Definitions

Let’s talk vocab.

Sass

A preprocessor for CSS. Sass offers functionalities not yet available in CSS like variables, rule nesting, and much more.

SCSS

“Sassy CSS.” Early Sass, with the file extension .sass, used a syntax quite different from the CSS syntax we’re already familiar with. Version 3 of Sass brought SCSS, returning to the same syntax as CSS and proving easier to use for most developers. Importantly, this means that valid CSS is also valid SCSS. Files ending with the .scss extension are written in SCSS. I still call them “Sass files”; please don’t be mad at me.

If you found that last paragraph terribly interesting, you should read this.

Partial

An SCSS file that is not directly compiled into a CSS file, but is instead imported into another SCSS file. A partial is denoted by the underscore that begins its filename (e.g. _base.scss).

Bourbon

A Sass mixin library by thoughtbot, inc. Bourbon makes Sass easier and more powerful by providing extremely useful mixins, meaning you don’t have to write them yourself. I particularly enjoy using Bourbon for CSS3 mixins, which allow me to use modern CSS3 modules without having to worry about vendor prefixes.

Neat

A lightweight grid framework written for Sass, also by thoughtbot. The best part of Neat, in my opinion, is the separation of content from layout that comes from defining layout in Sass files rather than template files. This makes your grid system easier to define, update and maintain and keeps your template files cleaner.

Now that we’re all dying to use these awesome things with Drupal, let’s set it up!

Create a Gemfile

We need to install Bourbon and Neat, which are both Ruby gems. We could do a quick gem install bourbon then bourbon install to create a folder of the entire Bourbon library, but this isn’t ideal if we’re ever going to be sharing this code since each developer (and deployment environment) will need to have these gems installed on their machine. Enter Bundler, a package manager for Ruby gems. Per the documentation, we only need to do a few things:

1. Install Bundler, which is a Ruby gem itself

$ gem install bundler

2. Create a Gemfile in our theme directory

$ cd my-custom-theme
$ touch Gemfile

…and list out all the gems our theme requires.

# Gemfile
source "https://rubygems.org"

gem 'compass'
gem 'sass'
gem 'bourbon'        # Bourbon mixin library.
gem 'neat'           # Bourbon Neat grid framework.

See Bundler’s documentation to read about specifying versions within your Gemfile.

3. Install all your dependencies.

$ bundle install

4. Commit the Gemfile and Gemfile.lock to ensure that everyone is using the same libraries.

$ git add .
$ git commit -m "Add Gemfile and Gemfile.lock"

Create a Sass directory

Within the theme directory, create a directory called sass. In here, create the following directories:

# Inside the custom theme directory
sass
├── base
├── components
├── layouts
└── lib

Install libraries

Now we can actually install the Bourbon and Neat libraries within our project.

$ cd sass/lib
$ bourbon install
$ neat install
$ git add .
$ git commit -m "Add Bourbon and Neat libraries"

Here’s what we’ve got now:

# Inside the custom theme directory
sass
├── base
├── components
├── layouts
└── lib
    ├── bourbon
    └── neat

Now that we’ve got our libraries set up, we need to actually import them so that they’re compiled into CSS.

Set up styles.scss

Create styles.scss in the scss directory. Inside styles.scss, we’ll import all our SCSS partials. View a working example of this here. I generally organize the imports in this manner:

/**
 * @file
 * Styles are organized using the SMACSS technique. @see http://smacss.com/book/
 */

/* Import Sass mixins, variables, Compass modules, Bourbon and Neat, etc. */
@import "init";
@import "base/variables";

/* HTML element (SMACSS base) rules */
@import "base/normalize";
@import "base/base";

/* Layout rules */
// Import all layout files.

/* Component rules (called 'modules' in SMACSS) */
// Import all component files.

We haven’t created any of these partials yet, but we will.

Some people may want to use Sass globbing here for brevity’s sake. I prefer not to as I find the file to be more readable without it.

Set up _init.scss

Within the sass directory, create a file called _init.scss.

In _init.scss we will (in this order):

  1. Import Bourbon (the mixin library) and Neat Helpers (Neat’s settings and functions)
  2. Set some overrides
  3. Import Neat itself
  4. Import fonts

You can view an example of a full _init.scss file here, but I’ll go through some of the highlights.

1. Import bourbon.scss and neat-helpers.scss

First we import all of Bourbon and Neat’s settings and functions, which are included in neat-helpers.scss.

// Import variables and mixins to be used (Bourbon).
@import "lib/bourbon/bourbon";
@import "lib/neat/neat-helpers";

2. Create overrides

Now we’ll override some of Neat’s settings and create our breakpoints.

// Turn on Neat's visual grid for development.
$visual-grid:       true;
$visual-grid-color: #EEEEEE;

// Set to false if you'd like to remove the responsiveness.
$responsive:    true;

// Set total number of columns in the grid.
$grid-columns:  12;

// Set the max width of the page using the px to em function in Bourbon.
// The first value is the pixel value of the width and the second is the base font size of your theme.
$font-size:     16px;
$max-width-px:  2000px;
$max-width:     em($max-width-px, $font-size);

// Define breakpoints.
// The last argument is the number of columns the grid will have for that screen size.
// We've kept them all equal here.
$mobile:   new-breakpoint(min-width em(320px, $font-size) $grid-columns);
$narrow:   new-breakpoint(min-width em(560px, $font-size) $grid-columns);
$wide:     new-breakpoint(min-width em(851px, $font-size) $grid-columns);
$horizontal-bar-mode: new-breakpoint(min-width em(950px, $font-size) $grid-columns);

3. Import Neat

Now that we’ve completed our settings, we’ll import the entire Neat library and our overrides will apply and cause the grid to function the way we want it to.

// Import grid to be used (Bourbon Neat) now that we've set our overrides.
@import "lib/neat/neat";

4. Import fonts

I like to include my fonts in this file to be consistent about how I’m importing my libraries (e.g. the Font Awesome library, which I’ve included in sass/lib). Some people might move this into a _typography.scss file or something similar, perhaps residing in the base directory. Do what feels right!

// Fonts -----------------------------------------------------------------------

// Noto Serif (headings)
@import url(http://fonts.googleapis.com/css?family=Noto+Serif:400,700);

// Open Sans (copytext)
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400);

// Font Awesome (icons)
@import 'lib/font-awesome/font-awesome';

Compile!

We haven’t written any custom styles yet, but at this point we can compile our SCSS into CSS using Compass (which we included in the Gemfile earlier).

First we need to generate a Compass configuration file using compass config.

$ cd my-custom-theme
$ bundle exec compass config

Why did we use bundle exec? Running a Compass command as a Bundler executable runs the command using the Compass gem defined in our Gemfile. This way, if we decided to define a specific version of Compass within the Gemfile that potentially differs from another version installed on our local machines, we ensure we’re using that specific version every time we run a Compass command.

Now we can compile our Sass. Run this command from the root of your theme directory:

$ bundle exec compass compile

Running this command for the first time does two things:

  1. Creates a stylesheets directory containing styles.css, the compiled version of styles.scss.
  2. Creates a .sass-cache directory

Once we start writing our own Sass, we can have Compass watch for changes and regenerate styles.css as we code:

$ bundle exec compass watch

I usually open a new tab in my terminal and leave this command running as I’m styling.

At this point our Sass directory is looking like this:

# Inside the custom theme directory
sass
├── _init.scss
├── base
├── components
├── layouts
├── lib
│   ├── bourbon
│   ├── font-awesome
│   └── neat
└── styles.scss

Where do we go from here? In my next post, I tackle the base, components, and layouts SMACSS-based directories and the custom scss files they will hold. In a future post I’ll go through some of Savas Labs best practices for writing Sass that can be easily shared amongst team members and maintained in the long run.

Jun 29 2015
Jun 29

drupalgovcon logoWe’re excited for Drupal GovCon hosted in the DC area July 22nd through the 24th! We can’t wait to spend time with the Drupal4Gov community and meet fellow Drupalers from all over! Forum One will be presenting sessions in all four tracks: Site Building, Business and Strategy, Code & DevOps, and Front-end, User Experience and Design! Check out our sessions to learn more about Drupal 8 and other topics!

Here our are sessions at a glance…

Nervous about providing support for a new Drupal site? A comprehensive audit will prepare you to take on Drupal sites that weren’t built by you. Join this session and learn from Forum One’s John Brandenburg as he reviews the audit checklist the our team uses before we take over support work for any Drupal site.

Drupal 8’s getting close to launching – do you feel like you need a crash course in what this means? Join Forum One’s Chaz Chumley as he demystifies Drupal 8 for you and teaches you all that you need to know about the world of developers.

If you’re wondering how to prepare your organization for upgrading your sites to Drupal 8, join WETA’s Jess Snyder, along with Forum One’s Andrew Cohen and Chaz Chumley as they answer questions about the available talent, budgets, goals, and more in regards to Drupal 8.

The building blocks of Drupal have changed and now’s the unique time to rethink how to build themes in Drupal 8. Join Chaz Chumley as he dissects a theme and exposes the best practices that we should all be adopting for Drupal 8.

Drupal 8’s first class REST interface opens up a world of opportunities to build interactive applications. Come learn how to connect a Node application to Drupal to create dynamic updates from Forum One’s William Hurley as he demonstrates the capabilities of both JavaScript and Node.js using Drupal, AngularJS, and Sails.js!

Are you excited to launch your new website, but getting held down by all the steps it takes for your code to make it online? On top of that, each change requires the same long process all over again… what a nail biting experience! Join William Hurley as he demonstrates the power of Jenkins and Capistrano for managing continuous integration and deployment using your git repository.

If you’re a beginner who has found the Views module confusing, come check out this session and learn important features of this popular module from Leanne Duca and Forum One’s Onaje Johnston. They’ll also highlight some additional modules that extend the power of Views.

Have you ever felt that Panels, Panelizer and Panopoly were a bit overwhelming? Well, come to our session from Forum One’s Keenan Holloway. He will go over the best features of each one and how they are invaluable tools. Keenan will also give out a handy cheat sheet to remember it all, so make sure to stop by!

Data visualization is the go to right now! Maps, charts, interactive presentations – what tools do you use to build your visual data story? We feel that D3.js is the best tool, so come listen to Keenan Holloway explain why you should be using D3, how to use D3’s visualization techniques, and more.

Implementing modular design early on in any Drupal project will improve your team’s workflow and efficiency! Attend our session to learn from our very own Daniel Ferro on how to use styleguide/prototyping tools like Pattern Lab to increase collaboration between designers, themers, developers, and your organization on Drupal projects.

Are you hoping to mentor new contributors? Check out this session where Forum One’s Kalpana Goel and Cathy Theys from BlackMesh will talk about how to integrate mentoring into all the layers of an open source project and how to develop mentoring into a habit. They’ll be using the Drupal community as an example!

If you’re a beginner looking to set up an image gallery, attend this session! Leanne Duca and Onaje Johnston will guide you in how to set up a gallery in Drupal 8 and how to overcome any challenges you may encounter!

Attend this session and learn how to design and theme Drupal sites using Atomic Design and the Drupal 8 CSS architecture guidelines from our very own Dan Mouyard! He’ll go over our Gesso theme and our version of Pattern Lab and how they allow us to quickly design and prototype reusable design components, layouts, and pages.

Can’t make it to all of the sessions? Don’t worry, you’ll be able to catch us outside of our scheduled sessions! If you want to connect, stop by our table or check us out on Twitter (@ForumOne). We can’t wait to see you at DrupalGovCon!

Previous Post

Programmatically Restricting Access to Drupal Content

Next Post

Announcing Selectability.js: Style-able, Accessible Select Fields

Jun 10 2015
Jun 10

Theming in Drupal 8 means a lot of changes for current Drupalers and a lot of awesome stuff for everyone. In this post I’ll cover:

  • What’s changing
  • The positives and negatives of these changes
  • How to create a custom theme in D8
  • Twig basics
  • Twig debugging

What’s new?

Too much to list here, but here are some highlights:

  • Twig, a template engine by SensioLabs, is used inside template files in lieu of PHP
  • Responsive design elements are included by default
  • Breakpoints can be set and used across modules and themes
  • Support for IE8 and below is dropped meaning the use of jQuery 2.0, HTML5, and CSS3 (including pseudo selectors) are now supported
  • Classy, a new base theme, is introduced
  • CSS: far fewer IDs are used, default classes are no longer in core but are moved to Classy, CSS file structure now uses SMACSS and class names follow the BEM format
  • CSS and JS files are attached to pages differently
  • template.php becomes the slightly better-named [theme-name].theme. Maybe we’ll finally get theme.php in Drupal 9?

Check out Drupal’s change log for a comprehensive list of changes.

Why all the changes?

Though the theming layer in Drupal 8 is quite different from Drupal 7 and will require some relearning, these changes come with great improvements, including:

  • Fewer Drupal-specific conventions and more popular, well-documented frameworks (such as Twig), meaning non-Drupalers can jump in much more quickly. Let’s face it - Drupal 7 theming has a major learning curve, which can keep developers and designers from using Drupal at all.
  • Template files are more secure since they no longer contain PHP code (thanks to Twig). In his D8 theming guide, Sander Tirez offers this nice/scary example of PHP code that could be executed in a Drupal 7 template file:
// This really shouldn’t be allowed to work, and it won’t in D8.
  <?php db_query('DROP TABLE {users}'); ?>

  • Even more security: text is automatically escaped in Twig, meaning a lower chance of XSS attacks.
  • D8 themers don’t need to know PHP to whip up a theme.
  • Separation of logic from appearance, leading to more modular (reusable) code.
  • Speaking of more modular code, Twig introduces template inheritance
  • Lack of browser support for IE8 and below means we get to use HTML5, CSS3, and modern jQuery libraries
  • More semantic CSS class names means leaner CSS and a more readable DOM
  • A general trend towards more extendable, modular, well-organized, better-performing code

Okay, are there any disadvantages?

At the time of writing this post, the toughest things about theming in Drupal 8 for me were:

  • Contributed themes and modules not having their 8.x branches ready. So far I haven’t seen any contributed themes that are truly usable with Drupal 8. This will surely change soon, and it’s good motivation to submit patches in the meantime.
  • Lack of documentation online. When building my first D8 site, documentation often didn’t exist for the problem I was having, it existed but was marked as out of date, or it was out of date but NOT marked as such. This was definitely a challenge! I’d recommend taking anything you read with a grain of salt (including this).

Fortunately both of these problems will resolve as Drupal 8 gets closer to release.

Creating a custom theme in Drupal 8

So, now that we’ve covered some reasons that D8 theming will be awesome and we’re feeling motivated to submit some patches and write some documentation, let’s create a custom theme using Classy as a base.

The first thing to note is the different file structure. The core folder now holds all the the modules and themes that ship with Drupal, and contributed and custom modules and themes are now found respectively in the modules and themes folders in the Drupal document root (mine is called docroot).

Let’s create a folder for our new theme. Savas Labs is working on a Drupal 8 mapping project, so I’ll use that as an example. Our theme is called “Mappy,” so we’ve created a folder for our theme within themes/custom.

Screenshot of D8 file structure.

The first file we’ll want to create is [theme-name].info.yml, which replaces D7’s [theme-name].info file. I’ve created mappy.info.yml, shown below. If you’re new to YAML, Symfony has a nice writeup on syntax. Pay close attention to the whitespace - for example, a space is required after the colon in key-value pairs.

# mappy.info.yml
name: Mappy
type: theme
description: 'D8 Theme for a basic leaflet site.'
core: 8.x
base theme: classy
libraries:
 - mappy/global-styling
 - mappy/leaflet
regions:
  navbar: 'Top Navigation Bar'
  content: Content
  sidebar: 'Sidebar'
  footer: 'Footer'

Let’s knock out the easy ones:

name: Mappy
type: theme
description: 'D8 Theme for a basic leaflet site.'
core: 8.x

This information tells Drupal that we’re dealing with a Drupal 8 theme and gives Drupal a name and description to display in the admin UI. Note that all of these items are required for your theme to be installable.

regions:
  navbar: 'Top Navigation Bar'
  content: Content # required!
  sidebar: 'Sidebar'
  footer: 'Footer'

This hasn’t changed much from Drupal 7. Don’t forget that the Content region is required. You can also forego declaring regions if you want to use Drupal’s default regions.

Classy, the new base theme

base theme: classy

Classy is a brand new base theme that ships with Drupal core. All CSS classes were moved out of core template files and into Classy’s as a way to a) contain, minimize, and organize default classes and b) give developers the option of not using Drupal’s default classes without having to undo core. One can simply choose not to use Classy as a base theme.

Additionally, Classy’s classes follow the BEM convention, making them less generic and more meaningful. Check out this article for a great introduction to BEM.

Libraries

libraries:
 - mappy/global-styling
 - mappy/leaflet

In Drupal 8, assets can be added to pages in a few different ways: globally, per-template, and per-page. We’ve chosen to add our CSS and JS globally since this is a small site and the same relatively lightweight assets are used on almost every page.

In the mappy.info.yml file, I’ve listed two libraries. These correspond to items in my mappy.libraries.yml file, which lives in the root of my theme directory. No matter how you’re including CSS or JS files on a page, you’ll need to define them in your [theme-name].libraries.yml file.

# mappy.libraries.yml
global-styling:
  css:
    theme:
      css/styles.css: {}

leaflet:
  css:
    theme:
      css/leaflet.css: {}
  js:
    js/leaflet.js: {}
    js/map.js: {}
  dependencies:
    - core/jquery

As you may have guessed, global-styling is a library that applies site-wide styles. leaflet is the leaflet library, which consists of leaflet.css and leaflet.js, plus our custom file map.js. jQuery is no longer loaded on every page in Drupal 8, so we have to explicitly include it when it’s required.

By listing these two libraries in mappy.info.yml we ensure that these assets will be included on every page of our site. However, this is typically not the best practice for larger sites since these files can seriously affect performance. This page on Drupal.org details how to attach assets to pages via hooks so that CSS and JS files are only loaded where they’re needed.

Breakpoints

Another new YAML file, [theme-name].breakpoints.yml, allows developers to create standard breakpoints to be used by modules and themes across the site. You can set custom breakpoints by defining them in this file. Below is our breakpoints file, which also resides in the root of our theme. Note that we simply adapted the breakpoints file from the Bartik theme.

# mappy.breakpoints.yml
mappy.mobile:
  label: mobile
  mediaQuery: '(min-width: 0px)'
  weight: 2
  multipliers:
    - 1x
mappy.narrow:
  label: narrow
  mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
  weight: 1
  multipliers:
    - 1x
mappy.wide:
  label: wide
  mediaQuery: 'all and (min-width: 851px)'
  weight: 0
  multipliers:
    - 1x

Important tip: Once you add a breakpoints file, you’ll need to uninstall and reinstall your theme to expose these breakpoints in the admin UI.

With these files set up, you now have a working custom theme!

Creating template files with Twig

In our custom theme’s current state, we’re using Classy’s template files as-is. If we want to customize any of these templates, we need to override them with Twig files located in our custom theme’s templates directory.

Twig is a template engine with syntax similar to Django, Jinja, and Liquid. It simplifies template creation with clean syntax and useful build-in filters, functions, and tags. In a Drupal template file (now with the extention .html.twig), anything between {{ ... }} or {% ... %} or {# ... #} is Twig.

  • {{ These }} are for printing content, either explicitly or via functions
  • {% These %} are for executing statements
  • {# These #} are for comments

Printing variables and regions

In Drupal 7 we render content like so:

<?php print render($page['sidebar']); ?>

Printing variables using Twig in D8 is as easy as including them in the double curly brace delimiter.

// In page--front.html.twig
// Print the sidebar region.

{{ page.sidebar }}


…unless there are special characters in the variable name. If that’s the case and you see an error when using the syntax above, you can use Twig’s subscript syntax, which should look pretty familiar to Drupalers:

// In page--front.html.twig
// Print the page type.

{{ page['#type'] }}


This will be more useful when debugging. The Drupal core base themes include lists of available variables and regions in the DocBlock of their template files, or you can print variables to the page via Twig’s debug mode (more on that below) to see what’s available to you.

Filters and functions

Twig comes with many built-in filters that variables are passed to via the pipe character. These filters do many of the things that PHP functions would have in previous Drupal versions. One example is the date filter:

// Format the post date.

{{ post.published|date("Y-m-d") }}


There are also Drupal-specific Twig filters, such as t which runs the string through the t() function.

// Run an ARIA label through t()

<nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">


By the way, ARIA labels are new in Drupal 8 too!

In addition to filters, Twig provides a range of functions that are also used within the double curly brace delimiters.

Tags

Control flow and other tags are also supported in Twig. One of my favorite things about templating languages is how easy it is to execute if statements and for loops. Savas Labs uses Jekyll for our company website and the Liquid templating language makes it easy to loop through a list of data points, blog posts, projects, etc. and print them to a page rather than writing out all of the HTML. In Drupal, we’ll use the if statement quite often.

// From Bartik's page.html.twig
// If there are tabs, output them.

{% if tabs %}
  <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
    {{ tabs }}
  </nav>
{% endif %}


Another useful tag is set, which allows you to set and use variables throughout the template. In the following example, the variable heading_id is set and then used as the aria-labelledby attribute. Note that the Twig concatenation character ~ is used, and the string ‘-menu’ is passed through the clean_id filter.

// From Classy's block--system-menu-block.html.twig

{% set heading_id = attributes.id ~ '-menu'|clean_id %}
<nav{{ attributes.addClass(classes) }} role="navigation" aria-labelledby="{{ heading_id }}">


Coding standards

Since this is new to some Drupalers, take a moment to check out the coding standards for Twig.

Debugging with Twig

Twig comes with a highly useful debug feature that outputs helpful HTML comments and allows you to code without having to clear the cache constantly, but it doesn’t work out of the box. We’re going to turn on that feature and disable the several layers of caching that require developers to clear the cache every time they make a change in a template file.

To enable debug mode and turn off caching, we need to do 3 things:

  1. Turn on Twig’s debug mode
  2. Turn on Twig auto reload, meaning that Twig templates are automatically recompiled when the source code is changed
  3. Disable Drupal’s render cache

Note that one thing we do NOT need to do, surprisingly, is turn off Twig caching - turning on auto reload is enough.

If you open default.services.yml located in sites/default, you’ll see some twig.config options where you can enable Twig debugging auto reload. I’m going to use this syntax but in a different file because I’m using a local settings file.

I created settings.local.php by making copy of example.settings.local.php in sites, moving it to sites/default and renaming it. I then opened up settings.local.php and customized the $databases['default']['default'] array.

To get Drupal to recognize my local settings file, I opened settings.php and uncommented the last 3 lines:

<?php
if (file_exists(__DIR__ . '/settings.local.php')) {
  include __DIR__ . '/settings.local.php';
}

In settings.local.php we’ll see:

<?php
/**
 * Enable local development services.
 */
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';

This means we need to head over to sites and edit development.services.yml to change our local development services. I added these lines to this file to enlable debug mode and auto reload:

parameters:
  twig.config:
    debug: true
    auto-reload: true

Great, we’ve completed steps 1 and 2. Fun fact: step 3 is already complete too! In settings.local.php:

<?php
/**
 * Disable the render cache (this includes the page cache).
 *
 * This setting disables the render cache by using the Null cache back-end
 * defined by the development.services.yml file above.
 *
 * Do not use this setting until after the site is installed.
 */
$settings['cache']['bins']['render'] = 'cache.backend.null';

So by using the local settings file we’ve already disabled the render cache.

Now, reload your site and you should see HTML comments in your browser’s code inspector with lots of helpful info: which theme hook is being implemented, theme hook suggestions (i.e. how to override the current theme hook), and which template file is being output. You can also make changes to your source code and simply refresh the page to see your changes rather than constantly clearing the cache.

Where my variables at?

One useful function that comes with Twig is dump(). This function works once you’ve enabled Twig’s debug mode and can be entered into any template file.

// Print out all variables on the page.

{{ dump() }}


// Print the page's base path.

{{ dump(base_path) }}


dump() is great, but it outputs a rather unwieldy array.

Screenshot of dump function output.

Enter the beloved Devel module and the new Devel Kint module. Kint is to Drupal 8 what krumo was to Drupal 7. Once Devel and Devel Kint are installed, you can use kint() in place of dump() for a nice expandable array.

// In page--front.html.twig
// Print out all variables on the page.

{{ kint() }}


Screenshot of kint function output.

Ahh, much better!

Further reading:

  • Start with Drupal.org’s theming guide
  • Drupalize Me’s post about debugging Twig has some detailed information about dump(), devel and kint. Be aware that some of the information in that post on configuring Twig is out of date.
Apr 27 2015
Apr 27

Over the past year or so here, we’ve tried to make front-end development less painful by creating living style guides in our Drupal themes that we can use internally as a valuable resource during development, as well as externally as a client deliverable. They allow us to write consistent, reusable and efficient code that is easy to maintain over the lifespan of a project. In addition, they show our design standards and prototypes that we can play with in a browser, at different sizes and in mobile devices, before things are truly functional and placed on an actual page of the site.

Though it takes more work at the beginning to set up, it definitely pays off in the long run. Ready to make an automated, living style guide work within your Drupal theme? Here’s how:

 waynes_world_conveyor

Using KSS and Grunt together to build a living style guide

Knyle Style Sheets (KSS) allows us to add special code comments to our Sass/CSS to specify the site’s repeated patterns, branding, color palette, typography, components and Drupal blocks/panel panes. When the Sass is saved and compiled it gets generated into a nice and clean style guide via kss-node (the NodeJS implementation of KSS), immediately viewable in your web browser. If you don’t like how the default style guide looks, you can customize things with KSS Node Template or just customize the default, vanilla style guide template. (However, recent improvements in kss-node – like being able to specify markup or a template file for everything that gets compiled into the style guide – have made KSS Node Template less useful for us.)

Grunt tasks have been great for us, helping automate some of the stuff we regularly do manually.  For example, updating the style guide files the moment that there’s a saved change to the Sass files we’re working on:

watch: {
 css: {
  // Here we'll config grunt-contrib-watch to keep an eye on any .scss file, in any directory in the theme.
  files: ['**/*.scss'],
  // When one is changed and saved, let's run the sass task to compile CSS.
  tasks: ['sass:dev']
 }
},

things get turned into CSS

sass: {
 dev: {
  options: {
   // Since we're compiling a "dev" version of the CSS here, let's make it expanded output style so we get all the little helpful references to where the CSS originates from in the Sass.
   outputStyle: 'expanded',
  },
  files: {
   // Advomatic standard practice is to have one single manifest file (styles.scss) where we import various partial Sass files in the order we want them compiled. We'll specify Sass to compile CSS exactly where we want it, in this case... css/styles.css.
   'css/styles.css': 'sass/styles.scss'
  },
 },
},

and then the style guide gets regenerated on the fly.

kss: {
 options: {
  // Link to previously compiled CSS.
  css: '/sites/all/themes/custom/mythemename/css/styles.css',
  // Link to theme JS.
  js: '/sites/all/themes/custom/mythemename/js/script.js',
  // Set our custom template to build styleguide from.
  template: 'mythemename-styleguide-template'
 },
 dist: {
  files: {
   // "styleguide" is the destination directory, the source directory is "sass"
   'styleguide': ['sass']
   }
  }
}

With this setup in the Gruntfile.js in your theme directory, you can view your style guide directly in your browser by viewing http://mydomainname.com/sites/all/themes/custom/mythemename/styleguide. That’s kind of a long URL, but we can make it more digestible by setting up a redirect to point that long path to a shorter path, like http://mydomainname.com/styleguide.

Drupal markup examples

You know them, you love them! Drupal has a bunch of “pieces” that you usually have to style on every site you work on; tabs, error messages, pagers – that kind of thing.  A great way to see all the different stuff that could appear in your Drupal site is to download and install the styleguide module (check out this demo site to see it in action).  You might not want all of that stuff in your KSS style guide, so just pick and choose the stuff you do want to use.  For adding more standard, non-Drupal-specific HTML elements and design patterns to your style guide, Brett Jankford’s Style Guide Boilerplate is an excellent source of markup chunks.

Let’s say you want to add the Drupal pager to your style guide.  

The latest version of kss-node allows you to specify a file containing a markup example template file (either .html or .hbs) for each section of your style guide.  You can then copy the default pager markup that gets rendered from the styleguide module’s page for your theme at at http://mydomainname.com/admin/appearance/styleguide, and stick it into a pager.html file in your theme and tell KSS where to find it via the KSS comments in your Sass, like so:

// Pager
//
// Markup: pager.html
//
// Styleguide: pager

After you compile your style guide, you will find a “Pager” section that has a prototype (non-functional) pager example using the markup in the pager.html file you added.  You can then style that example as you wish.  Note: the filename should be relative to the .scss file you’re specifying it from.

Pager example

Pager example within the KSS styleguide, as well as a background grid (via Susy)

 

In conclusion

This is just a brief overview of how to make an automated KSS/Grunt living style guide work within your Drupal theme, and there are even more ways to make your it more organized and comprehensive.  We have definitely found that a little work setting up a living style guide during your initial theme setup goes a long way during the project. The result is a constantly updated library of default styles, patterns and prototypes (with markup examples) that serves as a valuable team and client resource.

For an excellent overview on the resources for building (as well as the benefits of) living style guides, you must read my fellow Advomatic front-ender Amanda Luker‘s excellent recent post.

You should also check out:

Mar 31 2015
Mar 31

Heading into Chicago’s Midcamp, my coworker Andy and I were excited to talk to other front end developers about using style guides with Drupal. We decided to put the word out and organize a BOF (birds of a feather talk) to find our kindred front end spirits. Indeed, we found a small group of folks who have started using them and had a great conversation: tools, workflow and pain points galore! So if you have already been using them or if you are brand new to the idea, read on.

Andy on a Divvy bike.

We looked pretty cool riding Chicago’s Divvy bikes to and from the conference!

So what is a style guide?

It can mean different things in different contexts, but for front end development, it means a fully-realized library of elements and components, using clean HTML/CSS/Javascript. I’ve heard them described as “tiny Bootstraps for every client” (Dave Rupert) — a client with a style guide has all the classes and/or markup they need to properly add new elements and components. A living style guide asserts that the style guide is maintained throughout the life cycle of a project.

At Advomatic, we’ve been integrating style guides into our workflow for about a year. We’ve had a few discussions about when it makes sense to have one, and when not. In the past, I’ve even argued against them, in the case of small projects. But at this point, we’ve come to the conclusion that it ALWAYS makes sense to use one. Smaller sites might have smaller styleguides — perhaps just with the the baseline elements included — but with a boilerplate style guide and a compiler in place, the style guide will, in fact, build itself.

So what can you use to build a style guide?

I heard many static markup generators and/or prototyping software mentioned at Midcamp: Jekyll, Pattern Lab, Prontotype, and Sculpin.

At Advomatic, we’ve been using KSS (Knyle Style Sheets), which is more specific to just generating style guides. It uses a Grunt task to compile a style guide from markup (commented out in your Sass files) and the corresponding CSS. This section documents setting up KSS to auto-generate your style guide using KSS. We use the NodeJS implementation of KSS, which, coincidentally, JohnAlbin (the brains behind Zen base theme and Drupal theming in general) has taken the reins on.

If you still haven’t found one you like, here’s a handy list of styleguide generators!

Scared? I hear you. It SOUNDS like an extra layer of work.

Here were my fears moving to style guides:

  • It might add another layer of complexity and chance to break things.
  • If the markup differs significantly in the style guide and Drupal, we’d have to do the work twice.
  • The style guide is not within Drupal, so you cannot write javascript with the Drupal.behaviors convention.
  • If your style guide includes components that are layout-dependent, you’ll need to set up your grid system within KSS.
  • If the style guide rots on the vine or gets out of sync, it could be a pain to fix.

But let’s look at the pros:

  • Clients love to see the style guide, it can be an early, easy win.
  • Keeps the front-end decision-making at the beginning of the process, and agnostic of the back end.
  • Front end work can happen alongside back end work.
  • A HTML/CSS style guide can be a fully responsive document, unlike a PDF.
  • A style guide can be a stand-alone deliverable, if the client needs to pause or implement it themselves.
  • The modularity of a style guide helps clients think about the site as a system rather than individual pages. The result is flexible when the client wants to add more pages down the line.
  • A style guide helps onboard new people coming onto a project or keep consistency among more than one front end dev. A FED can see if a similar component has already been built or if certain styles can be reused or expanded on.
  • Helpful for QA testers — something that they can refer back to if something “in the wild” doesn’t look quite right.
  • Having the markup embedded in the style guide helps multiple developers produce consistent markup for the front end.

We have found that components that we chose to not prototype in a style guide often ended up taking more time than expected. When the back end devs could see what our preferred markup was, they built our components very closely to what we prototyped. In the end, the pros outweigh the cons.

So what is the holy grail style guide workflow?

We’re still looking for it, but here’s some tips:

  • Automate your workflow — style guides should compile every time you make a change to the site. We use Grunt for this.
  • Use a boilerplate style guide — you won’t forget to theme anything that way.
  • Use Drupal-specific markup in your boilerplate to make the transition easier. Use the Drupal style guide module for boilerplate markup.
  • Try not to put too many components on the same page to reduce endless scrolling, ease testing for accessibility by tabbing through components, reduce the amount of javascript and images loading on the page.
  • I haven’t yet, but I’d love to incorporate something like Ish to make each component responsive without having to resize the whole browser window when testing responsiveness.

What else would you suggest? Any pain points that you are feeling when using style guides with Drupal?

Or if you are just dipping your toes in, check out these resources for more good information:

Website Style Guides Resources
http://styleguides.io/

Style Guide podcast, Anna Debenham and Brad Frost
http://styleguides.io/podcast/

Front End Styleguides by Anna Debenham
http://24ways.org/2011/front-end-style-guides/

Design Components presentation from JohnAlbin:
http://www.slideshare.net/JohnAlbin/managing-design

Example style guides
http://ux.mailchimp.com/patterns
http://rizzo.lonelyplanet.com/styleguide
http://www.starbucks.com/static/reference/styleguide
http://www.bbc.co.uk/gel
http://primercss.io (Github’s style documentation)

Style guide comparison chart (google doc)

Responsive Deliverables
http://daverupert.com/2013/04/responsive-deliverables

Modularity and Style Guides
http://dbushell.com/2012/04/23/modularity-and-style-guides

You should also check out:

Nov 18 2014
Nov 18

As many of us know, Drupal 8 beta was released at the beginning of October which has given us a great preview of the goodies to come. One of those goodies is a new theme engine, Twig, which replaces PHPTemplate. Twig gives us a lot of extra power over our templates and allows us to clean up a lot of the extra cruft that PHPTemplate forced us to add.

So you may be asking, how will our brand new Drupal 8 templates look? Well they are going to be a lot leaner. The extra cruft of php tags, functions, and other miscellaneous bits are no longer needed – in fact, they don’t even work in Twig templates. Arguably, it will be easier to read at a glance what is happening in the Twig versions of Drupal templates. For a great example of how the new templates will look, we can crack open the Views module and compare the templates in the Views module 7.x version to the ones in the Views 8.x version. So let’s compare the views-view.tpl.php file from Views 7.x to views-view.html.twig file in Views 8.x.

Views-compare-part-oneViews-compare-part-two

Twig Comments

Starting from the top, lets work our way down to see what has changed. In the documentation section we can see that for the large block of comments, as well as single line comments, the {# #} syntax is used.

In the list of variables variables that are available to use, you may notice a few other changes. For example, Twig is not raw PHP, so the ‘$’ is not used at the beginning of variable names. Another change is that is that the $classes_array has been replaced by the attributes variable.

Rendering Variables

 Views-compare_example_one

Moving down to line #40 we can see the first instance of a variables rendered using Twig. The double curly bracket syntax, {{ my_variable }}, tells Twig that this is a variable and it needs to be rendered out. A variation of this syntax uses dot-notation to render variables contained in an array/object. This syntax looks like {{ my_variable.property_or_element }}, which makes it extremely easy to use. Dot notation is not used in this particular Twig template.

Twig Filters

Another powerful feature of Twig is template filters. Filters allow us to do simple manipulations of variables. The syntax for using a filter is similar to the syntax for rendering a variable. The difference is that after the variable name, you insert a | (pipe), followed by the name of the filter. For an example to make a string from a variable all lowercase you would do {{ variable_name|lower }} which transform all of the characters to lowercase. If you have used templating systems from other frameworks, such as Angular.js, this syntax may look familiar to you. This particular Views template does not use filters, but you can see examples of different filters on the Twig documentation site. If none of the predefined filters satisfy your requirements, you can extend Twig to create your own filter. The Twig documentation site provides details about creating your own custom filters..

Twig Logic

Views-compare_example_two

Jumping to line #42, we can see the {% %} (curly-bracket and percentage symbol) syntax, which is used for template logic, such as if statements. This syntax tells Twig that we are not rendering something, but rather that we need to process some logic, such as a control structure or loop, in our template.

The Takeaway

This blog post is a high level overview of how Twig templates in Drupal 8 will look.  With Twig, we can choose to use the out-of-the box tools it provides, or we can dive in and extend it with additional features such as new filters. For more information I would highly recommend reading through the Twig documentation for designers and for developers.

Aug 28 2014
Aug 28

Gesso theme on drupal.org For the past year Forum One has been using a Drupal starter theme created in-house to make theming more flexible, consistent, and easier to maintain. This theme is now available on drupal.org! Gesso (pronounced JEH-so) is an art term for the white paint mixture used to prepare a canvas or sculpture for painting. Likewise, the Gesso theme prepares Drupal’s markup and styles to give us a clean starting point.

Gesso is a responsive, Sass-based theme developed with accessible, standards-compliant HTML5 markup. It follows a mobile-first, future-friendly approach to coding responsive websites. Gesso also removes much of the cruft that we previously tended to override on each project and standardizes common components.

A word of caution: this theme is geared towards advanced themers. If you want to be able to manipulate the theme’s design, markup, or layout via a nice GUI, Gesso is not the theme for you. We built this theme to make it easy to customize within the Drupal theming layer, without getting in your way.

Gesso is not a stand-alone product. It depends on several Drupal modules and Sass tools: Magic, HTML5 Tools, Compass, Breakpoint, and Singularity.gs. It also integrates well with optional Drupal modules such as Display Suite, Panels, Blockify, Clean Markup, and Modernizr.

To be clear, Gesso wasn’t created in a vacuum. We got a ton of great ideas by diving deep into the code of other Drupal themes, such as:

If you want to develop a deeper understanding of Drupal theming, I encourage you to check out the code within these themes.

The biggest differentiator between Gesso and other themes is the altered Drupal markup, which makes it easier to follow the Drupal 8 CSS architecture guidelines. This theme leverages SMACSS with a modified BEM naming convention to organize styles. This encourages a component-based approach to theming through the creation of discrete, reusable UI elements.

In follow-up articles we’ll cover Gesso in more depth, including Sass organization, site building, and theme settings. Please join us in the issue queue if you have questions or ideas on how to improve it.

Previous Post

Customizing SearchApiQuery Filters

Next Post

Making a Big Splash at World Water Week

Developer? Designer?

Join the Forum One team.

Apply now
Feb 04 2014
Feb 04

What flavor is Kalatheme?

Create a Kalatheme sub-theme project right on Pantheon

Pull it down to your laptop on Kalabox

Work on it in Eclipse IDE, for example

What flavor is Kalatheme?

Kalatheme is a very convenient theme to use, and should be the default theme for Panopoly, with all due respect. Peruse its Drupal project page.  Panopoly + Bootstrap 3 + Bootstrap themes + browser based sub-theme generator (Bootswatch, etc., etc.!) + views grids + reusable custom CSS classes that can be registered as optional in any panels pane + advanced stuff for the folks that, inline with Kalatheme philosophy, don't like to admit they use it:Sass and Compass Tools.

I watched an interesting video given by Mike Pirog of Kalamuna, which gives you a really good feel for Kalatheme's philosophy, objectives and look and feel, despite being a few months old. Then take a gander at the Kalatheme docs on d.o. 

Some cool concepts are:

  • Twitter bootstrap
    • Drupal Libraries API for themes!
    • Straightforward upgrade path for any library
    • Responsive classes
  • One region: content (that's it). Then, panels layouts and panes. Page manager, Panelizer, Panopoly goodness.
    • No more blocks! No more regions!
    • Way, way fewer files!
  • Panopoly layouts + Kalatheme layouts + custom layouts

Create a Kalatheme sub-theme project right on Pantheon

  • Sign up and/or login to your pantheon dashboard.
  • Add a new site
  • Select the Panopoly distribution
  • SFTP mode is required, and it will be (should be) by default
  • Visit the site to complete the installation of Panopoly. Initially, just use any old theme. I installed the Panopoly News demo too, just to see some stuff.
  • Once the install process is complete, visit your new site as admin.
  • From the Appearances page click on "Install a new theme" and paste in a link the latest stable archive of Kalatheme. I entered http://ftp.drupal.org/files/projects/kalatheme-7.x-3.0-rc1.tar.gz in Install from a URL field and clicked Install (it works since we are in SFTP mode and the necessary permissions are automatically set up).
  • Initially enable Kalatheme and set it to the default and admin theme. You can safely disregard the error message "You do not have a Bootstrap library installed but that is ok! To get equipped either check out our Start Up Guide or run our Setup Wizard."
  • Now to create your sub-theme based on your favorite Bootswatch theme.
    • Did you remember to clear cache after setting a new theme :)  ?
    • Go back to your Admin > Appearances page.
    • At the top is the Setup Kalatheme link, click on it.
    • Complete the setup webform, with name, bootswatch theme (with preview! I chose Simplex; you can also choose third-party Bootstrap themes, for example there are paid themes at https://wrapbootstrap.com/ ), whether or not you want awesome font included (you do!), then click on Dress me up.
    • Lo and behold it becometh the default theme everywhere! REJOICE, as the instructions say.
  • Important Pantheonic note: Commit your changes on your site dashboard! Then you can switch to Git mode and do a backup or clone the project with Git. This will be important if you want to download a backup to your local laptop or workstation, say using Kalabox.

Pull it down to your laptop on Kalabox

"Kalabox is more than just a local development environment. It's an easy to use, site building and deployment toolkit for the masses. Advanced webtools now belong to the people." Built on kalastack using Vagrant and VirtualBox, integrated with Pantheon, I'm interested!

I shot them an email at [email protected] to apply for a keycode since kalabox is in private beta. Mike Pirog shot me a nifty code, and I entered it together with my name and address in order to get "boxed". I downloaded the kalabox-1.0-beta4.dmg file for my Mac.

From the Readme.md (please read in its entirety) included in the install package:

Requirements

  • Kalabox has been tested mostly on Mac OS X 10.8 and partially tested on 10.7 and 10.6. It may work on 10.6 or lower. If you try it out on an older OS X version, please share your experience.
  • For now, Kalabox supports 64-bit operating systems only. So if you're on a 32-bit machine, just hang tight, as support is coming soon!
  • Vagrant 1.3.5 and VirtualBox 4.2.18
  • 1GB+ of RAM Kalabox dynamically allocates memory to itself based on your available RAM. It needs at least 1GB available to run. 

Installation

  1. Double click on the installer.
  2. Agree to the terms of service
  3. Rejoice. NOTE: Apple may warn you...

Connecting with Pantheon

All you need is an account and a site on Pantheon. Go to the configure tab, enter your username and password, click back to My Sites and start developing! If you're interested in interacting with your Pantheon sites directly from the command line, you can use some of the handy Drush commands that come packaged with the Terminatur. https://github.com/kalamuna/terminatur

More? https://kalamuna.atlassian.net/wiki/display/kalabox/Kalabox+Home

After installing in the usual Mac way, I executed it. It asked me for permissions and downloaded some extra stuff... After a while (quite a while, actually, something like 15 minutes with a pretty decent internet connection), I had my Kalabox up and running. Edit: Actually, this is a very short time if you take into consideration that a full Linux server is being downloaded and setup!

I clicked on the Configure tab and entered my Pantheon credentials and logged in.

Then I clicked on My Sites and all my sites were to be found. I clicked on one, I thought I checked Download my files also, and chose the nifty option Create a new Pantheon backup and download it, and hit Submit.

The site was downloaded and I was greated with the Boomshakalaka! message that my site was good to go right here on my laptop. I clicked Great in answer to the offer Give it a try. There was my site right in my local browser!

I had forgotten to click on the Download my files also, so the images weren't present. So from the My Sites tab, I clicked on the gear just below the front page thumbnail of my site, and selected Refresh, then selected the Files checkbox only, and clicked Refresh. My images appeared on my site :)

I then clicked on the Home tab, and then selected SSH. Local Terminal opened at /home/vagrant. I cd'd to /var/www and then to my site and did a drush status

Cool.

Work on it in Eclipse IDE, for example

From https://github.com/kalamuna/kalastack:

"Kalastack uses NFS file sharing. You can access your server webroot at ~/kalabox/www on your host machine. This way you can use your local IDE to edit files on your server."

Well, that was easy!

In a later article, we'll deal with Pantheon integrated workflow using Kalabox. Can't wait!

Bookmark/Search this post with

Dec 01 2013
Dec 01

I’ve been leading Drupal web projects for some years now and yet have never heard a frontend developer say: “This design is meant for Drupal. It is so easy to implement it, the designer totally gets how Drupal works. I’m totally having coffee with this guy later today, we’re pals.” Instead, it’s often about how the designers only goal in life must be to think of ways how to drive the devs into insanity and ultimate extinction. What seems to be the problem?

Where to start from, would the themer say, putting down his half-smoked pipe and jQuery cheatsheet. Lets start from the beginning. The moment when you see Dropbox icon in update mode, and with a shaky cursor, open the design folder for the very first time. What will it be, Photoshop, Fireworks, or God save us all, an Illustrator file? Or is it just a bunch of .jpg’s with no means to separate backgrounds from text and shadows?

Whatever it is, the themer is usually left to discover his own way around the new landscape. Because the designer is off to a vacation, or too busy with his next project, or generally not involved, because his job is done, right? And it’s easy to understand that he is fed up with it. Because, yet again, the client puts him into a position where he not only has to make it look pretty, but also work out the UX process and half of the functionality while at it.

And grid. The grid is those cyan lines that help you align stuff in Photoshop. And Omega is a watch company. Keep the number of columns consistent through different responsive states, you say? Your stupid math has no place in my creative process, I say!

Finally you get throught the main laoyouts and move on to theme more specific functionality. The comment thread. The pager. The inputs. Is there design for those? No. And when you ask for it, the designer frustratedly spends his Saturday evening catching up and creates a pixel perfect design, that has no common ground with Drupal’s default layouts whatsoever, requiring thousands of characters of JS to make it work.

Lets breathe in

Its fun to rant, but all jokes aside, there’s some pretty simple stuff that would save a ton of time and money for everyone:

  • make nice layered source files, where all elements can be extracted separately. Please don’t send .jpg’s.
  • a Drupal project should be a team effort from the start. There is no independent graphic design phase. It does not make sense that the web designer is also the one who single handedly draws up the layouts and UX.
  • use consistent grid when doing responsive layouts.
  • when drawing up standard Drupal elements, look at the examples, get a basic knowledge of how the code works. Features are cheap, details expensive.
Sep 23 2013
Sep 23

This post is another step in the theming Drupal 7 wit Bootstrap 3, you can read my previous article about “Drupal 7 and bootstrap 3 theming the login form“.

Now the purpose here is to change the default Drupal messages display system :

default drupal messages

to this a nice modal message using Bootstrap 3 :

Drupal messages with bootrap 3

Okay let’s start :

1) Fist you need to rewrite the theme_status_messages() in your theme.php file like this :

function [your_theme_name]_status_messages($variables) {
  $display = $variables['display'];
  $output = '';

  $status_heading = array(
    'status' => t('Status message'),
    'error' => t('Error message'),
    'warning' => t('Warning message'),
  );
  foreach (drupal_get_messages($display) as $type => $messages) {
    // ! important : adding html needed for the modal.
    $output = '

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    

<div class="modal-dialog ">
      

<div class="modal-content">
        

<div class="modal-body">
';

    $output .= "

<div class=\"_messages $type\">
\n";
    if (!empty($status_heading[$type])) {
      $output .= '

<h2 class="element-invisible">' . $status_heading[$type] . "</h2>


\n";
    }
    if (count($messages) > 1) {
      $output .= " 

<ul>\n";
      foreach ($messages as $message) {
        $output .= '  

<li>' . $message . "</li>


\n";
      }
      $output .= " </ul>


\n";
    }
    else {
      $output .= $messages[0];
    }
    $output .= "</div>


\n";

    $output .= '</div>


        

<div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>


      </div>


<!-- /.modal-content -->
    </div>


<!-- /.modal-dialog -->
    </div>


<!-- /.modal -->';
  }
  return $output;
}

2) Now into your script.js file add :

// modals.
$('#myModal').modal();

3) Flush your theme registry cache and Voilà ! now every time the messages will be displayed within the modal dialog box.

Try a new sport with Pickleball, this  is a paddle sport that combines elements of badminton, tennis, and table tennis which you can find the Westop pickleball paddles of the best quality and price.

Hope you enjoyed !

Sep 17 2013
Sep 17

Bootstrap 3 is out with responsiveness, simplified code, new components etc .. so how to integrate this new features on a Drupal theme ? in this tutorial we’ll try to change the default Drupal login form from this :

startTo this :

final_result

1) First of all we’ll need to create a new theme ( in this tutorial we’ll be using Zen theme to create a subtheme) and download the bootstrap source.

2) Second we’ll need to create a custom module to alter the form and remove some of the uneeded html elements.

Okay no more talk let’s start !

– We begin by including the bootstrap css minified file into the subtheme :

yourtheme.info content :

stylesheets[all][] = bootstrap/css/bootstrap.min.css

Notice no important change appears that’s because we need to add bootstrap classes ..

Now we set what we need for the templates :

// set custom tpl for the login page.
function [your_theme_name]_theme() {

  $items = array();

  $items['user_login'] = array(
    'render element' => 'form',
    'path' => drupal_get_path('theme', '[your_theme_name]') . '/templates',
    'template' => 'user-login',
  );
  return $items;
}

//add class to buttons
function [your_theme_name]_button($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'submit';
  element_set_attributes($element, array('id', 'name', 'value'));

  $element['#attributes']['class'][] = 'form-' . $element['#button_type'];
  $element['#attributes']['class'][] = 'btn';
  // adding bootstrap classes.
  if($element['#button_type'] == 'submit'){
    $element['#attributes']['class'][] = 'btn-primary';
    $element['#attributes']['class'][] = 'btn-lg';
  }
  if (!empty($element['#attributes']['disabled'])) {
    $element['#attributes']['class'][] = 'form-button-disabled';
  }

  return '<input' . drupal_attributes($element['#attributes']) . ' />';
}

/**** theme form textfields. ***/
function [your_theme_name]_textfield($variables) {

  $element = $variables['element'];
  $output = '';
  // login form adding glyphicon.
  if($element['#name'] == 'name') {
    $output = '<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>';
  }

  // force type.
  $element['#attributes']['type'] = 'text';
  // set placeholder.
  if(isset($variables['element']['#description'])){
    $element['#attributes']['placeholder'] = $variables['element']['#description'];
  }

  element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength'));
  // adding bootstrap classes.
  _form_set_class($element, array('form-text', 'form-control', 'input-lg-3'));

  $extra = '';
  if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
    drupal_add_library('system', 'drupal.autocomplete');
    $element['#attributes']['class'][] = 'form-autocomplete';

    $attributes = array();
    $attributes['type'] = 'hidden';
    $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
    $attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
    $attributes['disabled'] = 'disabled';
    $attributes['class'][] = 'autocomplete';
    $extra = '<input' . drupal_attributes($attributes) . ' />';
  }

  $output .= '<input' . drupal_attributes($element['#attributes']) . ' />';

  return $output . $extra;
}

/*** theme password field ***/
function [your_theme_name]_password($variables) {
  $element = $variables['element'];
  $element['#attributes']['type'] = 'password';
  element_set_attributes($element, array('id', 'name', 'size', 'maxlength'));
  _form_set_class($element, array('form-text', 'form-control'));

  $output = '';
  // login form adding glyphicon.
  if($element['#name'] == 'pass') {
    $output = '<span class="input-group-addon"><span class="glyphicon glyphicon-eye-close"></span></span>';
  }

  return $output . '<input' . drupal_attributes($element['#attributes']) . ' />';
}

/** Theme form element **/
function [your_theme_name]_form_element($variables) {
  $element = &$variables['element'];

  // This function is invoked as theme wrapper, but the rendered form element
  // may not necessarily have been processed by form_builder().
  $element += array(
    '#title_display' => 'before',
  );

  // Add element #id for #type 'item'.
  if (isset($element['#markup']) && !empty($element['#id'])) {
    $attributes['id'] = $element['#id'];
  }
  // Add element's #type and #name as class to aid with JS/CSS selectors.
  $attributes['class'] = array('form-item');
  if (!empty($element['#type'])) {
    $attributes['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
  }
  if (!empty($element['#name'])) {
    $attributes['class'][] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
  }
  // Add a class for disabled elements to facilitate cross-browser styling.
  if (!empty($element['#attributes']['disabled'])) {
    $attributes['class'][] = 'form-disabled';
  }
  if (isset($element['#parents']) && form_get_error($element)) {
    $attributes['class'][] = 'has-error';
  }

  if($element['#type'] != 'radio'){
    $attributes['class'][] = 'input-group';
  }

  $output = '<div' . drupal_attributes($attributes) . '>
' . "\n";

  // If #title is not set, we don't display any label or required marker.
  if (!isset($element['#title'])) {
    $element['#title_display'] = 'none';
  }
  $prefix = isset($element['#field_prefix']) ? '<span class="field-prefix">' . $element['#field_prefix'] . '</span> ' : '';
  $suffix = isset($element['#field_suffix']) ? ' <span class="field-suffix">' . $element['#field_suffix'] . '</span>' : '';

  switch ($element['#title_display']) {
    case 'before':
    case 'invisible':
      $output .= ' ' . theme('form_element_label', $variables);
      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
      break;

    case 'after':
      $output .= ' ' . $prefix . $element['#children'] . $suffix;
      $output .= ' ' . theme('form_element_label', $variables) . "\n";
      break;

    case 'none':
    case 'attribute':
      // Output no label and no required marker, only the children.
      $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
      break;
  }
  // remove description we'll use placeholder.
  if (!empty($element['#description'])) {
    //$output .= '
<div class="description">' . $element['#description'] . "</div>

\n";
  }

  $output .= "</div>

\n";

  return $output;
}

Okay now the user-login-template.tpl.php :

<div class="col-md-5 col-md-offset-3 panel">

<div class="panel-heading">
<h2><?php print t('Login'); ?></h2>
</div>

    
<div class="panel-body">
    <?php print drupal_render_children($form) ?>

    </div>

</div>

at this point and if everything is ok you should see something like this :

intermediaire

We need to remove the label to get a nice version, in the custom module :

/** Hook_form_alter **/
function [your_module]_form_alter(&$form, &$form_state, $form_id) {
    // user login
    if($form_id == 'user_login'){
        $form['name']['#title_display'] = 'invisible';
        $form['pass']['#title_display'] = 'invisible';
    }
}

Ps : you’ll need to rebuild the theme registry to see the changes !

Et voilà ! hope you enjoyed. Please if you have any idea about how to do this in a more simple way feel free to comment.

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.

Panels

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.

Omega

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 21 2013
May 21
Backlit spaghetti (as in code)

This is an intervention.

CSS is pretty simple. Classes, IDs, elements and pseudo-elements, with style definitions attached to each. Calling it a "language" is a bit of a stretch (though preprocessors like Sass fit the bill).

But let's be honest, for years our stylesheets cascaded right on out to infinity.

Huge files with table-of-contents comments to try to make some sense of it — until a quick fix got pasted down at the bottom. Brittle style definitions relying on tight coupling with HTML structure. Pieces of styles being replicated here and there for different components with similar features, without any way to tell they were related in the CSS.

My stylesheets were like that too, because strategies for writing CSS had barely altered since the days when it was used to change the colors of the scroll bars in Internet Explorer. Luckily, in the past couple of years both CSS architecture and CSS preprocessors came into their own.

Jonathan SnookSMACSS, or Scalable and Modular Architecture for CSS, was developed by Jonathan Snook, a featured speaker at Drupalcon Portland. I'm really excited to get the opportunity to have Jonathan speak, not only because of my personally well-dog-eared copy of SMACSS, but because Drupal itself is adopting a SMACSS approach to its CSS.

I spoke with Jonathan about sustainable stylesheets and the future of SMACSS. For an even more detailed look, please join me at Jonathan Snook's featured Drupalcon Portland this afternon, Tuesday, May 21 at 4:30 PM.

IB: What's the biggest mistake you see people making when writing CSS?

JS: I think the biggest mistake is thinking of everything in the context of a single page. We're no longer just building sites with a design for a home page and an inside page. We're developing complex systems that need to work in a variety of contexts and we need a development approach that complements that.

SMACSSIB: What's the biggest "win" you see in using the SMACSS approach? Why should frontend developers change their approach to CSS?

JS: The biggest win is maintainability. The SMACSS methodology makes it easier to build larger projects by breaking things down into smaller components. Like the move from spaghetti code to MVC frameworks on the server side, this separation of concerns on the CSS side improves the process of putting a site or web app together.

IB: In the last part of your book, you talk about how the SMACSS approach fits in to work using a preprocessor like Sass. There have been a lot of developments in Sass in the past year — have they had any positive effects on your use of the SMACSS approach?

JS: With Sass, the introduction of placeholders was a positive step forward. Overall, Sass (and other preprocessors) are a great way to augment — but not replace — the way people write CSS.

IB: What are your thoughts on BEM? Do you see it as compatible with SMACSS?

JS: I see BEM as very compatible. BEM really enforces naming convention, which is a very important concept in SMACSS. They both take a modular approach to site development.

IB: What are you tacking next when it comes to CSS and frontend development? Will there be a "SMACSS Part Two"? Or something else entirely?

JS: I'd love to augment SMACSS with case studies and expand on some of the ideas in the book based on things that come up in the workshops I do. I'd also like to work on a prototyping/site development tool that uses the SMACSS concepts. We had built something like this when I was at Yahoo! that I think many people in the industry would find really useful. Hopefully I can find the time to work on it!

Image credit Flickr user stevensnodgrass. It's spaghetti! (As in code.)

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

May 17 2013
May 17
Breakpoint: Snap!

Media queries are a key part of responsive web design, because they control at what width (among other things) different CSS rules kick in.

"Breakpoint makes writing media queries in Sass super simple," say Mason Wendell and Sam Richard, creators of the extension to Compass, and they're right. It's not surprising that we'd want them to present at Drupalcon, since design in Drupal, like web design everywhere, has been embracing responsive web design as a fundamental principle. (Side note: This website is in the midst of a responsive web design overhaul. Cobbler's children and all that.)

I spoke to Mason and Sam about how Breakpoint makes responsive web design even easier. Don't miss their Drupalcon Portland frontend session, “Managing Responsive Web Design with Sass and Breakpoint,” on Thursday at 10:45 AM.

IB: What motivated you to create Breakpoint? How has it changed your own workflow?

MW: Before Sass 3.2 came out I had written an article for The Sass Way that previewed some of it's new features, including the ability to use variables in media queries. I created an example that baked in some names for breakpoints into a kind of "master mixin" for media queries. On my next responsive project I put the theories I'd written for that post into practice, and found that I could refine that approach. If I assigned a variable to each media query first the approach would be very flexible. Then when noticed that I wrote min-width queries way more often than any other type I set up defaults that made creating media queries very fast.

MW: There was a side effect that I think is more useful though. By assigning names to each of my media queries I'm able to keep them in context in a much more effective way. If I some media queries to deal with the width of a nav element, and then later I add an item to that nav, I can change the value of that variable and all the associated queries are adjusted. This is even more effective when handing code back and forth within a team.

SR: Breakpoint was created with the motivation to ease many of the pain points of working with media queries in CSS. The biggest pain point that Breakpoint solves is providing meaningful semantics to your media queries. When building content based responsive sites, early in your design process two unrelated items may happen to break at the same points, but as your project grows, those points may change and a simple find and replace will have unintended consequences. This is probably the biggest workflow win to using Breakpoint, all of your media queries now have proper semantics.

SR: The other big win for my workflow is Breakpoint's no-query fallback, allowing me to very easily add in fallback code for any of the media queries I write.

IB: What can Breakpoint do that just assigning variable names to specific min-widths can't?

SR: For starters, Breakpoint handles much more than min-width queries. It is designed to be future friendly and currently supports all CSS level 3 and level 4 media queries. Additionally, it's syntax is easy to use to create complex media queries, including both and and or media queries. It has native handling for all of the different media query requirement for resolution (of which you need to write at least four different queries for currently) while just writing the standard. The no-query fallbacks are a huge win as well.

MW: The main benefit is that you can assign names and manage your media queries with variables. This helps you avoid having them scattered around your SCSS, and makes is easy to understand how they're related and affect each other.

MW: While Breakpoint is optimized for min-width because they're used most often it doesn't stop there. There are a number of shortcuts built in, for fencing min- and max- values, converting pixels to ems, and even vendor prefixed queries like resolution.

MW: We even created a way to Breakpoint to report back to you what queries are in a particular context. Singularity GS uses this feature to kind of magically create responsive grid systems.

SR: Of all of Breakpoint's features, probably the least used, but most powerful is Breakpoint Context. This allows you to call a function anywhere and get the current media query context allowing for amazingly intelligent mixins and functions to be written in Sass, something unique to Breakpoint that you simply don't have with interpolating variables.

IB: Are there any responsive web design aspects specific to Drupal theming/frontend development that Breakpoint helps with?

SR: There is nothing Drupal specific that Breakpoint helps with. Breakpoint, like Sass, was built to be backend independent. This means that if you are building any site, regardless of if it's a Drupal site or a Node site or a static site, Breakpoint is able to do its job handily without being caught up in being tied to a specific backend technology.

MW: One of the things I love about working with Sass is that it's not Drupal-specific, and it's meant to be used anywhere on the web. Breakpoint follows that example.

IB: Is Breakpoint a successor to Respond-To, or will that continue to get developed?

SR: In a way, yes and no. Respond-To was written before Breakpoint, but upon Breakpoint's release, it was decided that our efforts should be focused on a unified Media Query engine, with Respond-To as a wrapper syntax for Breakpoint. This is how the current Respond-To project exists. As of Breakpoint 2.0, the Respond-To mixin has been incorporated into Breakpoint core, so you now can use Respond-To without needing an additional Compass extension!

IB: Do you use Breakpoints module (in Drupal 8 core)? Or do you just do all of that through Sass?

SR: I personally truly dislike the Breakpoint module. Every use case I've heard for it seems to be based on the thinking that sites have three or four breakpoints and that everything can be boiled down into an easy to use admin interface. There are no standard breakpoints, period, and good, reasonably complex responsive sites will usually have 20 or more breakpoints. Responsive cannot be done from the backend, and the Breakpoint module encourages you to do so (as does the Spark layout initiative).

IB: Do you think any aspects of Breakpoint might get rolled directly into Sass in the future?

MW: It's possible, but we probably won't move the obvious parts to the Sass language. There are some helper functions that we've written in Ruby that would be very useful in Sass core. Once that's in we'll be able to offer Breakpoint without Compass.

SR: I do not believe Breakpoint will be rolled directly into Sass, nor would I want it to be, as it is out of scope of Sass core. As much as I like them, I even think the color functions in Sass are out of scope for it. Sass core should simply be the language and the bare minimum function base for it to be useable. Sass doesn't ship with any mixins, and I think it should probably stay that way. That being said, Breakpoint is fairly stable; our 1.3 release stood stable for six or so months without needing any changes until we rewrote the whole thing for our 2.x release, so maybe being merged into Compass isn't out of the question, but I do not see a need for that.

IB: I hear in addition to Breakpoint, Sam went and created some kind of magic box of Sass called Toolkit. Want to say more about that?

SR: Toolkit started life as RWD Kickstart, a project Mason and I kind of made up on the spot a year ago at one of the first New York Sass meetups. Its original goal was simply to be a collection of Compass templates to make pulling in media query and grid solutions together easily. Since then, it's evolved to be more of a collection of Progressive Enhancement, Design in Browser, and Modern Web Development tools, a toolkit if you'll let me, of useful tools. I'd say the four biggest thing that Toolkit has are a modern Clearfix mixin, progressive enhancement replace text mixins, a triangle generation mixin, and an intrinsic ratio mixin to make using intrinsic ratios super easy. It also adds *, *:before, *:after { box-sizing: border-box} and img, video { max-width: 100%; height: auto; } to your stylesheets, which are the first two things I do for any responsive project.

SR: Toolkit's templates have also evolved, Where originally there were five some odd different templates to choose from, now there are just two, a basic one to set up a basic partial structure, and a responsive web design one that pulls in Breakpoint 2.x for media queries and Singularity 1.x for grids.

IB: You sure know those late twentieth-century presidents.

MW: With a name like Breakpoint, how could I not revisit the cinema classic Point Break. Bodhi and his gang of thrill-seeking bank-robbing surfers evaded the FBI for years until the newly minted Special Agent Johnny Utah was on the case. I think we can all agree that there's a poignant metaphor for web designer there. And some pretty sweet gifs.

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

May 17 2013
May 17
The power of the Twig templating engine

A new theming engine, Twig, is coming along with Drupal 8's adoption of the Symfony framework. And it's downright magical.

Instead of having theme functions that have to be overridden, everything becomes an (easy to read, easy to modify) template. Instead of having to figure out render arrays, themers can use consistent template variables. And instead of having insecure output, Twig sanitizes everything by default.

If you've ever worked on a WordPress or Tumblr theme, the approach will feel pretty similar. Here's what it looks like:

Example of Twig template in Drupal

And oh by the way, it's well-documented — no small point in the Drupal community!

Sound too good to be true? Well, it almost might be, because a lot has to happen in order to get this into Drupal 8. There's a Twig-focused sprint happening right after Drupalcon, so if you think this is great, come pitch in! Because if things don't get done, Twig will be held until Drupal 9. No Drupal themer, veteran or newbie, kitten or human, wants that to happen.

I spoke to Jen Lampton (with a contribution from Fabian Franz) about how Twig will result in happier veteran Drupal themers, happier new Drupal themers, and happier Drupal kittens. Be sure to show up for their featured Drupalcon session (along with Drupal CSS innovator John Albin Wilkins), “Using Twig: The new template engine in Drupal 8,” on Wednesday at 3:45 PM.

IB: What's one thing you're most excited about with Twig?

JL: Replacing the template engine with something completely different means that we get to take a good hard look at absolutely everything in the current theme system, so we can do a clean sweep.

FF: What I love the most about Twig is the syntax, and how it cleverly makes it possible to lazy-render things. The possibilities of having an interpreted language are endless.

IB: Can theme developers start converting/creating their themes now?

JL: No! If you have the time to start converting your own themes, then please, please, please use the time to help us make the theme system what you want it to be — instead. There will be time to convert your themes later, but Drupal itself can only be monumentally improved right now.

IB: Will frontend developers and themers coming from other CMSes — like WordPress — find Twig easier to use?

JL: Yes. Front end developers coming from everywhere will find Twig easier to use. For starters, Twig looks a lot more like HTML, so if you don't know PHP you'll still be right at home. For people who do know PHP and don't know Twig, there will be a learning curve, but it's far far FAR less steep than learning about what Drupal had done to PHPTemplate.

IB: Twig sounds great! What can people do to help make sure it happens for Drupal 8?

JL: There are four main areas where we need help right now, as outlined in our Twig TODO wiki.

1. Help us test all the patches.
2. Help us fix issues with the patches.
3. Help us improve the markup in core (after being converted to Twig).
4. Help us clean up the rest of the theme system.

If people are interested in any one of these four areas, they can come to the sprint immediately following DrupalCon and get some hands-on help making Drupal better. We need all the hands we can get since we are up against some major deadlines, so please please please come help us!

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

May 15 2013
May 15

Ah, base themes.

If there's an analogue to the Windows/Mac/Linux battle in Drupal land, it's probably Zen vs. Omega vs. AdaptiveTheme.

Garrett Dawson and John Ferris have a way out of that eternal struggle: Custom base themes. As they put it in their Drupalcon Portland session description:

"By necessity, base themes make assumptions about how teams and individuals work. By rolling your own, you’ll become much more comfortable and informed about the Drupal theming layer, and have a better launchpad for your front-end projects."

Here in Portland we take home gardening and permaculture seriously, so what better place to talk about "growing your own" custom base theme!

I spoke with John and Garrett about how creating your own base theme can make work for you and your team easier. Take a gander at their session, “Dapper Drupal: Custom Tailored Themes,” on Thursday at 2:15 PM for the full story!

IB: Base themes that are out there make some assumptions about how you want to theme. What's the advantage to rolling your own base theme rather than finding the theme that already makes the assumptions you do?

JF and GD: If you can find a base theme in contrib that fits perfectly into your workflow, by all means, use it. There's a lot of solid tools out there. We don't want to deter people from using and contributing to them. With that said, we feel it's unlikely a contributed base theme will be ticking all the boxes and making all the right assumptions about your workflow.

There's no one-size-fits-all approach. Your front-end process is heavily influenced by team dynamics, contrib module choices and a whole host of other considerations. The majority of base themes cannot account for those variables like you can. We want front-end developers to take a critical look at their tools to see where they can make improvements. That may mean creating a custom base theme; a custom starter theme for use with an existing base theme; or even a set of helper modules.

All the popular base themes started because someone wasn't happy with what was available at the time. The ultimate goal is increasing efficiency while improving the quality of the final HTML, CSS and JS.

IB: Do you recommend custom base themes for big shops? Small distributed teams? Freelancers? Everyone?

JF/GD: Yes, all of the above. At least consider it as an option. If you find yourself doing any kind of repetitive work, there's an opportunity for improvement. The only people who should steer clear of custom base themes are those new to Drupal. You need to be familiar with the tools that are available before setting out to create your own.

IB: Besides your the custom base themes you developed yourselves (Center and Prototype) what other custom base themes have you seen in the wild?

JF/GD: Yes! We've learned a lot working with and iterating on Center and Prototype. They work well for the structure of our team and the type of work we do at Aten. However, we realize every team is unique. We were really interested in seeing how other organizations were approaching the front-end problem space. We chatted with a range of teams of varying sizes working across different industries. Everyone has their own unique set of tools based on their own strengths and constraints. We're excited to share those with you, but you'll just have to come and see for yourself!

Images: National Archives and Flickr user McBeth.

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

May 15 2013
May 15
Screenshot from Dale's presentation: When designers change colors on CSS

It's fair to say that in the last year, adopting the CSS preprocessor SASS has completely changed frontend development for me. That's a sentiment I've heard others express when they started using it — and I was pretty late to the party.

I got attracted to it initially through variables. We've all been there when a client or a designer wants to change a color and suddenly we have to change dozens or hundreds of values across CSS.

Dale Sande captures that kind of revolution in efficiency that SASS brings, as seen in a screenshot from his upcoming presentation at Drupalcon Portland.

But Dale, who's spoken plenty on SASS and organizes the Seattle SASS meetup, is taking us way past the SASS basics like variables, and that's why I'm excited to see his presentation next week.

Around the same time SASS came onto the scene, some thoughtful people were exploring more maintainable frontend development and CSS architecture through ideas/acronyms like OOCSS, SMACSS and BEM, and folks like Nicole Sullivan, Jonathan Snook (a Drupalcon featured speaker!), Nicolas Gallagher, and Harry Roberts.

I spoke with Dale about SASS, object-oriented CSS and some the things he'll be covering at Drupalcon. Be sure to join me at his session, "Sass: OO'S'CSS w/Extends and Silent Placeholders," on Wednesday at 2:15 PM!

IB: Some people argue SASS creates bloated code — do you see placeholders addressing that concern effectively?

DS: Sass doesn’t create bad code. Bad coders do.

The whole concept of placeholder selectors was designed to fight code bloat and be a more pragmatic solution to OOCSS. In my presentation, I illustrate how using the various techniques generate code.

The real "ah-ha" moment comes when we see how using placeholder selectors makes it easier to manage and literally re-use code — thus reducing dreaded CSS bloat.

IB: What's the advantage to using silent placeholders over mixins for a set of rules?

DS: Simply put, being able to re-use code without duplicating code. The use of mixins was the first part of being DRY with our code. Looking at the Sass it felt AWESOME! But when we looked at the output CSS, this is when we realized that we were all living a lie.

Our CSS rules were being duplicated tens, if not hundreds of times. We weren't being DRY, we simply put the onus of duplication on the machine.

Placeholder selectors embrace the one of the oldest concepts of CSS and that is to extend the CSS selector for reuse. But with traditional CSS this was difficult to do, especially when you were dealing with thousands of lines of code. Sass' @extend directive allows developers to create name-spaced reusable chunks of code that is portable, re-usable and extendable without duplicating anything.

Fighting tight coupling in CSS by keeping code separation in SASSIB: Do you see placeholders as helping to reduce the amount of tight coupling — scattering pieces of styles in multiple places?

DS: While Placeholder Selectors are a tool that can help with scattered code, it is not the only solution. Having a file/folder structure that embraces the different types of code, e.g. CSS selectors, placeholder selectors, mixins and functions, can assist in creating reusable modulare code and maintain a process of control over the many parts.

Images: Screenshot from Dale Sande's presentation.

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

May 13 2013
May 13
Drupalcon Portland: May 20-24, 2013

The big news at Drupalcon Portland is that, for the first time at a Drupalcon, we're having separate frontend and user experience (UX) tracks. That means we were able to offer even more sessions targeted directly at frontend developers, and as the local track chair for frontend, I'm really excited about what we've ended up with!

Groundbreaking frontend featured speakers

Jonathan SnookFirst and foremost, of course, we have Jonathan Snook presenting on his concept (and book) Scalable and Modular Architecture for CSS.

MortenDK at Drupalcon SydneySMACSS has had a big impact on a lot of frontend developers and themers — and in fact it's had a huge impact on Drupal itself. The Zen base theme, the most-downloaded Drupal theme out there, has adopted a SMACSS approach.

And Drupal itself is moving toward SMACSS with a re-organization of its CSS in the upcoming Drupal 8 release.

Join Jonathan Snook at Drupalcon Portland on Tuesday, May 21 at 4:30 PM.

Drupal 8 and Twig

Oh yeah, so there's this new version of Drupal coming out pretty soon.

Among the many, many awesome things happening with Drupal 8, one of the most relevant to frontend developers is the adoption (with a little luck) of the Twig templating engine.

Twig, a component of Symfony — a framework being adopted by Drupal 8 — will enable themers to write much cleaner (and safer!) code, and enable module developers to simplify the theming components of their modules.

No joke, at the BADCamp 2012 Twig session, there were literally gasps in the audience as we all saw how cool it was. If you're a themer or a frontend developer, don't miss this!

Join Jen Lampton, Fabian Franz and John Albin Wilkins presenting Twig on Wednesday, May 22 at 3:45 PM.

And so much more!

I've just touched on two of the featured sessions at Drupalcon Portland. In the coming week I'll be posting more about some of the other sessions, but you can browse the frontend sessions right now and start planning to attend your favorites! (Don't forget the User Experience sessions too.)

And if you don't yet have your ticket to Drupalcon Portland, there's still time! Grab your ticket by this Friday and save $50 off the on-site ticket price.

I can't wait to see everyone here in Portland!

Join Rootwork on Twitter, Facebook and SlideShare.

Learn about Rootwork's services for nonprofits and social change.

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.

Conclusion

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?

Nov 07 2012
Nov 07

If you have ever worked with views and columns in Drupal, you may have had the unfortunate and rather difficult task of getting the columns to render out just the way you really want them to. After some research, I believe I've found a workable approach.

The most common approach is probably cutting the row widths in half and then floating them left. This gives the "illusion" that they are actually in "columns". This works great, if you want the view's row results to read left to right. However, I recently came upon the need to have the view rows to stack on top of each other and then overflow into the second column.

Many of you might be thinking, "Why didn't he just use a Grid style plugin in Views? That is, after all, what it's there for!"

Answer: Responsiveness!

Grids render in table markup. Anyone that has ever tried theming a table to be responsive knows it's a lot of work to override default table positioning behaviors.

There had to be a better approach in getting these columns to actually function the way I needed them. After doing a quick Google search, I came across the the Views Column Class module. Great! This looked very promising! I started to mess around with it and quickly realized that it added classes in a custom view style. Yes, this could work. However, it's still the same technique that we use for creating left to right "faux columns" - relying on classes to float left or right. What I really needed was to actually alter the markup that was generated. I needed to separate the rows into columns that have their own

markup. This would allow for easier manipulation and styling of the actual columns. I started searching some more.

I finally came across this wonderful blog by Amanda Luker: Flowing a list view into two columns. Granted it's a little over a year old, but it definitely got me on the right path! The technique is rather solid, but I'm not really a fan of using preg_replace(). For performance reasons, it's better to generate the correct markup in the first place. No need to generate markup only to replace it later. This is Drupal after all!

Not only that, I also needed to accomplish the following:

  1. Easier way to manage which views get processed and converted into columns
  2. Standardized view classing for the columns (including zebra striping and first/last classes). This is very useful for theming purposes.
  3. Dynamic Columns. Have the ability to produce any number of columns, more than just two.

In the end, I felt just doing some rewriting was in order. In the end, this approach helps with all the previously mentioned tasks at hand. Below are the source code files (in Gist) needed to start preprocessing Views Columns:

  1. template.php - Contains the preprocess hook needed for your theme. I figured preprocessing an unformatted list would probably be the easiest.
  2. views-view-unformatted.tpl.php - The template file needed for your theme.
  3. views-columns.less & views-columns.css - These are supplemental and are really just base styling for creating evenly width 2 and 3 columns for tablet sizes and up.

I have tried to document these files fairly well, however if you find that additional documentation is needed please feel free to comment below or fork the Gists!

Nov 01 2012
Nov 01

This week, to to keep things moving, we have three more videos on using Omega 3.x. We will cover creating a sub-theme, debugging options, and take a look at Omeg's grid and responsive settings.

Next week, we'll start configuring Omega and taking a look at some of the other options it offers in its UI.

Oct 24 2012
Oct 24

Learn about this powerful responsive base theme

We're happy to kick off our new series, Introduction to Omega 3.x. The Omega theme is the second most installed Drupal theme, and is used by over 40,000 sites. It is a very popular responsive base theme, with a lot of configuration options to help you get up and running. In the series we will be covering all of the pieces of your first Omega sub-theme, from an explanation of how a base theme works, all the way to making your own customizations to theme templates and functions from the Omega base.

The first two videos in the series are free, so you can get a sense of what will be covered and get an overview of Omega, helper modules often used with it, the terminology it uses, and finding documentation.

Omega Overview and Terminology

A Brief Explanation of the Omega 3.x series

Oct 24 2012
Oct 24
Lullabot logo

Lullabot has trained thousands of Drupal developers & guided the development of some of the largest Drupal websites.

Oct 24 2012
Oct 24

In this lesson we're going to take a look at the Omega theme, cover some basic terminology around it, and discuss the advantages and challenges of using it. Specifically this lesson will cover:

  • Omega features
  • Helper modules
  • Where to find documentation
  • Omega terminology
Jul 27 2012
Jul 27

If you receive our newsletter, you may have noticed that you recently got a HUGE list of posts we've written recently. Well, except that they weren't all really that recent — some of those we two months old, and every week in between. Our regular newsletter is sent out automatically based on our RSS feed, and it turns out that our RSS feed was broken. Once we tracked it all down and got it fixed, all of the posts that had never gotten queued up for the newsletter shot out in one big go. Sorry about that. Aside from the crazy long newsletter though, I thought I'd share how I got this sorted out, because this is the kind of problem that can happen to anyone, and it is really annoying to track down.

When we finally realized there was a problem, we didn't know what was causing the problem, or therefor how to fix it. The error that Drupal.org was showing when trying to update the feed was "The feed from Drupalize.Me seems to be broken, because of error "Reserved XML Name" on line 1." That wasn't really helpful, but a little bit of Googling pointed us in the direction of having a space in the feed. Lo and behold when we went back and looked at the feed itself, you could see that there was a blank space right at the beginning of the first line. Hm, where did that come from?

We hadn't made any changes to our view for the feed, and we didn't have any custom theming going on for it, but we checked those things out anyway. Nothing proved helpful. Trying to review all of the code on our site for an extra space was massively daunting. Then it struck me that I could narrow my search very easily because we use version control. We knew the feeds worked fine originally, so we just need to check the changes between it working correctly and not. I tracked down the rough date of when the feeds started to fail, and then I found the point in time in our code where it worked correctly. We use tags for our production code, so on my local I checked out a tag that worked right (3.3.0). I rolled forward on the tags until I saw when the feed broke (3.3.2). Now since this was a hot fix release, the changes in it were pretty small and in only a few files. A quick look at the diff on the files and I saw the mistake right away: a space was accidentally added to the top of our template.php file, right before the opening PHP tag. That added a space to the beginning of ALL pages on the site.

Now, if this hadn't been so quick to find with my basic method here, the next thing to do would have been to use a really handy Git command called bisect. If you've never used bisect before, it lets you take two endpoints in your code, and then goes halfway between those two points. You can then test if the bug is still there. You can keep bisecting the commits until you zero in on the commit that introduced the bug.

So, luckily, once I remembered that version control is my friend in so many ways, I quickly found the bug, fixed it and rolled out the new hot fix. Our feeds are now working properly and we can share with the world again.

Jul 17 2012
rmo
Jul 17

Hello, Shadow is here!

Posted on: Tuesday, July 17th 2012 by Richard Mo

Have you ever felt that doing front-end web development for mobile web devices (i.e. Android, iOS) is a real pain, especially when you can’t do any inspections quickly? Designers or Themers would totally agree with me on this. Web developers, in general, would feel the same way but not as much as designers/themers do. And how about QA in general – manually pressing links or refreshing pages? It’s a lengthy process… Now, may I suggest to you that it is possible to shadow your actions across multiple devices?

I’ve recently been introduced to Adobe Shadow which addresses all the pain I mentioned earlier. A quote from Adobe Labs:

“Adobe® Shadow is a new inspection and preview tool that allows front-end web developers and designers to work faster and more efficiently by streamlining the preview process, making it easier to customize websites for mobile devices.”

Basically, it allows you to sync all URL changes to every shadowed device and inspect HTML and CSS on each and every one of them.

Here are some features Adobe® Shadow provides:

  • Synchronized Browsing and Refreshing (Device Pairing) — Wirelessly pair multiple iOS and Android devices to your computer.
  • Remote Inspection —Target a device for remote inspection and using familiar development tools, make changes to your HTML, CSS and JavaScript and see your device update instantly.
  • URL Monitoring — Shadow monitors the Address Bar in Chrome, and sends updates to Shadow devices as they happen.

Setting the system up isn’t hard at all; there are, however, 3 things you must download to get things up and running:

  1. You need to download the Adobe® Shadow service which installs onto your desktop. It acts as a server then communicates with all your devices.
  2. Download and install the Chrome browser extension which you would use to control your Shadow devices.
  3. Finally, each device (Android or iOS) must install their respective Shadow app.

Combining all 3 pieces of the puzzle, hook them up, and there you go!

Adobe® Shadow is excellent for traditional websites, where every page is uniquely named (i.e. each page has a unique URL), because Shadow devices follow URL paths sent by the host and interact with the native browser. Most AJAX elements on the page, however, will not be compatible with Shadow for that reason. Web applications built purely using JavaScript, Sproutcore per se, will not work.

Then, what would Adobe® Shadow be used for? Drupal! Shadow is excellent for Drupal front-end development! It really speeds things up for designers and themers. The built-in HTML CSS inspector will let you see what’s going on with each device and you can take screenshots for all of them at once!

For further information, please visit Adobe Shadow.

Apr 11 2012
Apr 11

Ah, Drupalcon. Three days of panels and BOFs, one Advomatic code sprint, and some very late nights with the Advoteam. Now I'm thrust back into the land of overflowing diaper pails and spaghetti bits everywhere that is work-from-home motherhood. But I promised myself I'd put my DrupalCon notes into a fancy blog post in the hope that others will find them useful (and so I can find them later). Two weeks later, here goes.

This year's DrupalCon was particularly fruitful for us theme developers. In years past, there hasn't been much new and shiny for us beyond CSS3 goodies we couldn't touch because of legacy browsers. But technology is changing, as it is wont to do. We're seeing a revolution in how we plan, design, theme and QA our sites, thanks mostly to responsive design (and SASS/Compass, but I'll save that for a later blog post.)

If you need any convincing that the mobile revolution is mandating a change in the way we design and build sites, check out Luke Wroblewski's super engaging keynote. LukeW coined the term (and wrote the book) "Mobile First" to redirect planning sites for handheld devices first -- then for computers -- because of the clear trend in how people are accessing sites. A collateral benefit is that by designing mobile first you are forced to prioritize your site's content -- maybe the main thing people need when they go to your organization's website is how they can help the cause, not a letter from the Board. There were a few "future is now" moments in there too, for better or worse. Do check out his Future Friendly manifesto.

At Advomatic, responsive sites are rapidly becoming the norm, and we're figuring out best practices as we go. So these DrupalCon sessions were a top priority:

There was a bit of buzz around the idea of doing "design in browser" versus in a design program like Fireworks or Photoshop, which inevitably mean a fixed width conceptualization of a site (even if the designer creates versions for a variety of browser widths.) SASS and Compass would give you a leg up to design something quickly directly from your browser, and I hope to address that in future blog posts. However, I tend to camp with those that say that starting from the browser will inevitably stunt a designer's creativity:

The browser was intended as a delivery mechanism with HTML and CSS a means of describing content rather than defining it (a subtle distinction I know, but an important one). As such the browser lacks even the most rudimentary tools, such as the ability to draw lines or irregular objects through direct manipulation. Instead this process is heavily abstracted through code. As the best design tools are the ones that put the smallest barrier between the creator and their creation (the pencil is a good example of this) designing in the browser adds an unnecessary level of craft to the process. - Andy Budd, Clearleft

I'm not sure whether Photoshop and Fireworks will soon have built-in flexibility, or if browsers will have built-in design tools, but currently neither is a perfect tool for responsive design.

Another interesting approach to the the problem of graphic design for responsive environments is Style Tiles, which was mentioned in at least four of the sessions I saw. It's a method for designing for a client without creating full comps, somewhere between a "mood board" and a comp. I like that it allows for some flexibility, and look forward to an opportunity to try it out. Another suggestion was designing a few comps for different breakpoints in Photoshop/Fireworks and a style guide -- and then move to designing in the browser.

One Drupal module that would help with in-browser design (and makes testing for different displays easier) is the Style Guide module, which generates a page where you can test all common HTML elements for a site, so you don't miss anything.

There is still a lot of debate on how to handle images in responsive design. While the img {max-width: 100%;} goes a long way, it still means you are potentially downloading a unnecessarily large image on your phone. And unlike CSS background images, img tags have a single, immutable source. The Adaptive Image module for Drupal is suggested, as is Borealis Responsive Images, for creating smaller images on the fly depending on the browser size. It's a complex issue, and you can dive deeper here and here. For video FitVids was suggested (and FitText for flexible font sizes.)

What about content? While there is this mantra of "mobile first" -- designing the site around the smallest of devices first, keeping content super streamlined -- there's another thread that content available to larger screens shouldn't necessarily be hidden on smaller screens. Mobile users may in fact be looking for a more rich experience, not just the bare bones. So think twice before plunking in a display:none on an entire region. However, I imagine that will probably be a site-by-site decision.

Responsive Design Testing

So testing for all these various devices inevitably will be tedious. I collected a little list of some tools to help.

  • Responsive Design Testing Tool - See how your site will look in four different device widths together on a single page.
  • Adobe Shadow - plug in devices to a desktop, pull up your site on one, and view it in all devices (no need to surf to it on all devices.)
  • The Browser Stack, a cross browser testing tool, just added mobile support

And, finally, here's a collection of fun responsive examples to check out for inspiration.

There you have it. Hopefully something in my extended brain dump will be of use to you!

Watch all Drupalcon sessions here, and fill me in on anything I missed below.

Feb 01 2012
Feb 01

Right now everyone wants a good mobile experience for their site and that is sparking discussions about what theme you can and should use to make your site accessible to the mobile world. At Zivtech, we feel that we have outgrown starter themes because we spend more time overriding than using them (especially in D7 since a lot of the great Zen stuff is baked right in). The other day I got to thinking, just what would it take to build a responsive theme for Drupal from scratch. Is it so complicated that we need systems upon systems to handle it?

You probably guessed, my answer is no. It turns out it takes less than fifty lines of code to build a basic working responsive theme complete with media query powered break points. If a completely custom and highly flexible layout can be made in less code than zen’s opening page.tpl.php comment, why use a base theme for responsiveness? Of course, I cheated a little by using an amazing framework that a coworker and zealot turned me onto awhile back called Susy.

Susy

Grid systems have been around for quite a few years now but the advent of Sass makes them a whole new ball game. Until CSS preprocessors, working with a grid system (like blueprint or 960.gs) meant you included some boilerplate CSS files that gave you a bunch of nice default grid behaviors. Then you just had to take their selectors and add them to your markup. This works well and it is very cool, the one problem is it is not semantic. You are changing your doc to change your presentation, yeah it’s necessary but really not cool and what that ol’ zen garden was all about avoiding. Enter Sass.

Sass is all about making CSS as terse as humanly possible, so a major feature is having simple functions that you can pass variables to (called mixins) for generating all of your CSS quickly and easily. This means you can leave your markup alone (especially in Drupal where everything and its mother is a div with 10 classes) and you can generate tailored grid CSS to match. No presentation leaking into our DOM (at least until we start hitting edge cases).

Introducing Tony

Following the Drupal 7 core’s own Stark theme for guidance, I created nothing more than an .info file and a layout.css, giving me an installable theme called Tony (named for my favorite Stark (sorry, that one was for the nerds)). My goal with Tony was to create a bare bones Drupal 7 theme with a fully functional responsive layout built with media query based break points to keep the layout friendly to displays of all sizes (including mobile). Experimenting with Tony requires that you have Compass and Susy installed on your machine.

You can always find Tony in my sandbox if you want to toy around with it, though I really don’t intend to turn it into a real base theme. Remember, we have a lot of choices there and it’s what I’m trying to avoid.

Step by step

Now lets take a tour of the code:

@import "susy"

This line just imports compass and Susy.

$total-cols: 8
$col-width: 50px
$gutter: 8px
$gutter-width: $gutter
$side-gutter-width: $gutter-width

Here’s where the magic begins. Here we set the stage by establishing the number of columns in our grid, the width of each one, the space between each element (the gutter) and how much room we should have on the far left and right sides. These global variables will be used by Susy everywhere else to determine what CSS it should generate. Note that we are free to enter our dimensions in pixels but Susy will do all the hard math to convert these into % ratios so that our layout can respond proportionally to the size of the screen.

@mixin full-width
  +columns($total-cols)
  +alpha

If you’re not familiar with Sass’s syntax you’re in for a treat and I highly recommend you read up. You’ll thank me. What this does is define a mixin that can be used throughout my css to reapply a few lines of code. This one sets the width of an element by proscribing it the appropriate number of columns (in this case all of them) and then applies the alpha styles (as opposed to omega) telling Susy we want this to go to the left. The first element in a row should always be an alpha and the last one an omega.

#page-wrapper
  +container
  +susy-grid-background()
  width: auto
  margin: 6em
#header, #navigation
  @include full-width
#sidebar-second
  +columns(2)
  +omega
#sidebar-first
  +columns(2)
  +alpha
#content
  +columns(6)

Here we set the stage. Again, borrowing from Stark, this theme uses Drupal 7’s stock markup without any tweaks. We apply one of Susy’s mixins with +container to turn the #page-wrapper div into a container, applying the global Sass variables we created before by calling Susy’s +container mixin. We then turn on a visible grid to show our grid as a reference (obviously just for the design/development phase). Next, we set the width to auto so that the page will grow to fill any screen size and set all margins to 6em to give it a bit of breathing room and space for a background. We also set widths for the sidebars by calling the Susy mixin (again, like a function for generating CSS) and passing in an argument of the number of columns this div should take up. Note we set whether the sidebars should appear first and last by calling +alpha and +omega Susy mixins as well. You can read more about how this works here. Finally we set the main content region’s width at 6 columns (the default appropriate to both left sidebar only and right sidebar only).

body.one-sidebar.sidebar-first #content
  +omega
body.one-sidebar.sidebar-second #content
  +alpha

These four lines set #content to float right or left based on which side bar is currently visible.

body.two-sidebars
  #content
    +columns(4)
  #sidebar-first
    +alpha
  #sidebar-second
    +omega

Here we set the content to float in between the sidebars and adjust it’s width to accommodate having an extra sidebar. The grid system makes the math easy, 8 columns - (2x 2 sidebars) = 4 columns. That’s it, now we have a fluid grid based layout that can accommodate all of our side bar variations. A great start, but I did promise to make this responsive, so now the real fun begins:

Media Queries

Media queries allow you style sheets to apply specific styles depending on the current size of the browser. Normally these need to go a the root of your CSS document but thankfully Sass has a media bubbling behavior that will ensure they find their way to where they belong and you are free to define them in a place that makes sense to you, even nesting them inside other selectors.

@media screen and (max-width: 1000px)
  #page-wrapper
    margin: 1em
      top: 0

Here we specify that if the browser width ever dips below 1,000 pixels, we should remove the top margin, drop the rest of the margins from 5em to 1 and stop using up so much real estate for borders. This helps on smaller screens and netbooks, but to be able to work well all the way down to mobile, we probably want to kill our margins completely and pop the sidebars above or below our main content.

@media screen and (max-width: 500px)
  #page-wrapper
    margin: 0
  body.one-sidebar.sidebar-first, body.one-sidebar.sidebar-second, body.two-sidebars
    #content, #sidebar-second, #sidebar-first
      @include full-width

And that’s it! We covered all the big ticket items in less than fifty lines of code (at least, before compiling). So if the responsive grid system and media query break points can be achieved reliably and easily without tedious calculations, tweaking or templating… Why use a base theme at all? A good mobile experience needs to be hand tweaked, that’s easier to do if you have a full control and understanding of what’s going on. We all need to change how we think about presentation and I don't think any theme out of the box will be a good mobile experience for your content.

Now all you have to do is make it look good, but that’s really a whole other post.

Oct 13 2011
Oct 13

Theming forms is always a little bit of a handful; designers like to create slick looking forms with rounded corners, drop shadows and custom looking form elements. Unfortunately it's not always an easy task to bring the design to life, but with a bit of css and jquery it is very easy to get your drupal forms looking a little less Drupal-ey.

Overview

We have previously gone over theming the markup of your Drupal forms for easier theming, now let's look at what tools are out there to add a bit of pizzaz to those boring select list and checkboxes. Select lists and checkboxes are incredibly annoying to deal with because unlike text fields you just can do much with css. Without any theming you end up with a very disjointed looking form. I this case we have to look to jquery to save the day. We are going to be using two lightweight jquery scripts to transform those stubborn form element into slick custom checkboxes and select lists.

Preparations

We are going to need these two scripts.

The select box script comes with a .css file as well, you can drop that in your theme's css folder and we will load it like any other css file.

and lastly you will need an empty file to supply the jquery to the theme, I usualy go with the incredibly creative scripts.js.

How-to

First things first you'll want to create a folder in the root of your theme called "scripts" if there isn't one already. Once you have that done you can toss those three files in there. Then we want to load those files through the theme. The way we do that is declare them in your themes .info file like this.

stylesheets[all][] = css/jquery.selectBox.css scripts[] = scripts/jquery.selectBox.js scripts[] = scripts/jquery.checkbox.js scripts[] = scripts/scripts.js

Save your file and give your site's cache a clear at admin/config/development/performance or if you use Administration menu you can flush it through the link they have. Your theme should now be loading your scripts so we should probably start applying them to something.

First we can apply the select box script to all select boxes on the site with this

(function ($) { $(document).ready(function(){ $(function() { /** * Fancy select boxes */ $("SELECT").selectBox(['default']); }); }); })(jQuery);

If you would like something a little more targeted just throw in the css selector you'd like it to apply to.

Under that you will add a similar line for your checkboxes again if you want to target specific ones just add a css selector.

(function ($) { $(document).ready(function(){ $(function() { /** * Fancy select boxes */ $("SELECT").selectBox(['default']); /** * Fancy checkboxes */ $('input:checkbox:not([safari])').checkbox(); }); }); })(jQuery);

What you will get is some nice markup to theme away.

For select boxes you will get this.

<a class="selectBox selectBox-dropdown"> <span class="selectBox-label">Item 15</span> </a>

The ul with all your options will ouput at the bottom of your page and be absolutely positioned below the selectbox.

For checkboxes you will get this.

<label><input style="position: absolute; z-index: -1; visibility: hidden; " type="radio" /> <span class="jquery-checkbox"> <span class="mark"> <img src="empty.png" /> </span> </span> 1st radio button </label>

With these 2 scripts you should be able to get your form looking quite unique and a lot less drupal-ey. I will offer a little disclaimer, it is very easy to get carried away with adding jquery to forms. Having used full jquery form suites in the past I urge you to steer clear of them. I've only created more headaches with them and prefer to bring jquery in to help with only the most stubborn of form elements.

Oct 04 2011
Oct 04

We've been hearing a lot about responsive design and the future of the web recently. At DrupalCamp Montreal this September, Jen Simmons and Jake Strawn talked about why responsive design is taking hold. I was inspired to try out some of the techniques they talked about, and decided to convert evolvingweb.ca to be more responsive.

Unlike creating an iPhone app for your website or throwing together a mobile theme, applying responsive design to your existing site requires you to change the design of your website. What I thought would be a few small adjustments to the theme turned into a larger project to make our design and theme more flexible and robust.

What is Responsive Design?

Rather than designing a site that works for one screen size, or designing separate themes that work for different devices, the goal of responsive design is to build a website that adapts to the width of the user's screen and works for both large and small screens. This involves creating a flexible-width layout that will adapt as the screen size changes, and writing some CSS specific to screens with a particular size so that you can trim down or hide certain elements at smaller widths and restrict the width of the page at large screen widths.

Media Queries

Currently, the main technique for implementing responsive design is to use media queries. Media queries allow you to include CSS files based on the size of the user's screen or device. At different screen widths (or device widths), you can load different CSS files which change the layout and styling of the page. You can do this either by targeting screens with a particular minimum width, maximum width, or both.

CSS for Larger Screens

To include CSS files for screens larger than a certain width, you can use the following in your mytheme.info file:

stylesheets[screen and (min-width: 760px)][] = css/screen-760.css
stylesheets[screen and (min-width: 960px)][] = css/screen-960.css

The screen-760.css file is loaded for browsers the width of 760px, but also larger screens. It allows for a total page width of 760px and also defines a layout for the columns to fit in that width.

The screen-960.css file is loaded for any a screen width of 960px or larger. It restricts the width of the page to 960px and allows for normal-sized column widths (i.e. 640px for the main content and 320px for the sidebar). If you're converting an existing theme to be responsive, this will contain a lot of what used to be in your layout CSS file.

CSS for Smaller Screens

Include the following in your .info file to include CSS for screens smaller than a certain width:

stylesheets[screen and (max-width: 320px)][] = css/screen-320.css
stylesheets[screen and (max-width: 480px)][] = css/screen-480.css

The screen-320.css file would only be loaded for screens 320px wide or narrower. The screen-480.css file would be loaded for screens 480px or narrower. Notice that since a device that is 480px wide will load both files, it makes sense to load the screen-480.css file second so it overrides the styles in the 320px stylesheet.

CSS for a Range of Screen Sizes

You can also effectively set a range of screen sizes that your CSS will target by combining a min-width and min-width in your media query.

stylesheets[screen and (min-width: 480px) and (max-width: 760px)][] = css/screen-480-760.css

Inline Media Queries

Depending on your design, you might end up with a lot of screen-size-specific CSS files. Sometimes it's more appropriate to use several media queries within a CSS file, using the @media rule.

@media screen and (max-width: 480px) {
  #page {
      width: 480px;
  }
}

Device Width vs. Browser Width

I should clarify that using min-width means that the CSS file will be loaded based on the browser width, so this will apply to users of large monitors who resize their browser. This is really useful for testing your responsive design, since you don't need to switch devices to see your design change, just change the width of your browser. If you only want to detect the device width only, use min-device-width or max-device-width.

It's Not Working on Android!

In addition to adding these media queries, Android devices need a 'viewport' meta tag to being able to detect their own screen width. Adding the media queries above won't have any effect on Android devices until you add this meta tag to your site. You can add it from your mytheme_preprocess_html() function using drupal_add_html_head() like this:

<?php
  $meta_viewport 
= array(
    
'#type' => 'html_tag',
    
'#tag' => 'meta',
    
'#attributes' => array(
      
'name' => 'viewport',
      
'content' => 'width=device-width'
    
)
  );
  
drupal_add_html_head($meta_viewport'viewport');
?>

What to do about Internet Explorer?

Internet Explorer versions 6-8 don't implement media queries. For these versions of IE, you can either implement some kind of responsive solution with javascript, or you can decide not provide the responsive layout for IE users, which the approach I took. In this case, you still need to provide CSS targeting IE so that users viewing your website on a larger device with IE will not see a full-width design. To implement this approach, the CSS you'll want to add for IE will likely be the same as what you added for screens that have a min-width of 960px (or whatever your widest page layout is). Drupal doesn't allow you to add a CSS file more than once, so you'll have to create a duplicate CSS file. My solution was to create a separate screen-960-ie.css file and use @import to include in it all the CSS from the screen-960.css file.

You can add a CSS file for IE only using the Conditional Stylesheets module. You can also add the file from your template.php file using drupal_add_css() and setting the browsers parameter.

Designing for Mobile

The instructions above will get you started adding media queries to your Drupal theme, but I think there's a lot to be said about how to actually create a 'mobile first' design. As themers, we're not used to designing and writing flexible-width themes for tiny devices. Even though you might like the idea of 'mobile first', your client probably expects you to design for standard-sized monitors and adapt the design for smaller devices afterwards.

Adapting a design to be responsive after it's fleshed out for a fixed-width screen is not an easy task. You can stack columns on top of each other at smaller widths, make certain elements smaller, and remove others altogether, but some elements are going to be hard to adapt. If you resize your browser to a smaller width, you'll notice a lot of awkward layouts (i.e. an image that takes up almost the full width of a column, with just a couple words wrapping to the right of it).

The best approach is to start thinking about how to make your theme responsive as you're designing and building it, and testing it at various screen widths as you go. This is going to be a challenge when the designer and themer are different people, especially if the designer is working exclusively in Illustrator or Photoshop.

Writing CSS for Responsive Design

Here are some tips to get you started writing CSS for responsive design.

  • Watch out for elements that are positioned absolutely. Will they overlap with other items at smaller screen widths?
  • Make sure your horizontal menus items wrap gracefully. Try centering them on smaller screens and using the CSS3 white-space: nowrap property.
  • Check the line-height on text that wraps at smaller screen widths.
  • Set a max-width for images of 100%, as well as for the HTML tag that wraps each image.
  • Set a max-width of 100% for form elements as well.
  • Watch out for elements with a fixed height or width. Try setting a min or max width or height instead.
  • Watch out for elements that are altered with javascript, including slideshows and text replacement tools.
  • Watch out for text that floats next to images. Do you need to change this behaviour for smaller width screens?

What do do with Tables and Panels

I found dealing with tables and Panels to be a huge challenge. Columns could be removed at smaller widths, or stacked on top of each other rather than sitting next to each other.

  • Panels layouts with more than one or two columns will not work well on smaller screens. Try writing CSS to remove columns or float columns differently at smaller widths.
  • If you're using grid-style Views to display non-tabular data, consider another display technique.
  • If you need to display data in a table, consider using advanced CSS techniques as described in this article.
  • Some of your mobile users will have an app for displaying spreadsheets on their device, so consider generating a CSV for users to download if you have a lot of tabular data to display.

Resources

Beyond Responsive Design

For some use cases when mobile performance is a priority, you'll probably want to go beyond responsive design and actually change the markup of the page for different devices. To get started doing this in Drupal, try the Mobile Tools or Context User Agent. However, mobile detection doesn't replace responsive design, and using device detection is probably out-of-scope for most Drupal projects.

Responsive design is really exciting and a great challenge for both designers and themers. While using a base theme that provides a responsive layout is great, it doesn't mean that you don't have to think about responsive design. We need to understand how different screen sizes effect our designs and how to meet the challenge of responsive design by creating more robust and more flexible themes.

Sep 19 2011
Sep 19

Columns. While it may seem like a good idea to a graphic designer, the idea of newspaper-style columns strikes fear in the hearts of themers everywhere. In particular, you may run into an instance where you need a list view to be A-L in the first column, then M-Z in the second column. I'll walk you through a method for doing just that, using a little PHP. Note that this is for Drupal 7, but is easily adaptable for Drupal 6.

I will note first that there are a couple other quickie options that might work for your situation.

1. There are several javascript solutions available, which finds a midpoint in the text and wraps the chunks in divs. This works, but if a user has a plugin like NoScript enabled, this solution does not degrade gracefully.

2. There IS a CSS3 multicolumn solution, but it is largely unsupported. Currently it is only supported by Firefox 1.5+ and Safari 3.

So, eventually, there will be a simple CSS solution, but, for the time being, the cleanest option is server-side, using PHP.

In my example here, we'll look at theming a list view to have multiple columns.

Say you have a view with a some items that we want to display in two columns. Views generates HTML that looks something like this:

<div class="view-columns">
  <div class="view-content">
    <div class="views-row views-row-1 views-row-odd views-row-first"> ... </div>
    <div class="views-row views-row-2 views-row-even"> ... </div>
    <div class="views-row views-row-3 views-row-odd"> ... </div>
    <div class="views-row views-row-4 views-row-even views-row-last"> ... </div>
  </div>
</div>

Here's what that looks like just floating each row to the left. Looks like columns, but they are not in the order we want.

floated rows

Instead, we want something that looks like this:

newspaper style columns

To make this themable with CSS, we need the markup to look like this instead:

<div class="view-columns">
  <div class="view-content" id="leftcol">
    <div class="views-row views-row-1 views-row-odd views-row-first"> ... </div>
    <div class="views-row views-row-2 views-row-even"> ... </div>
  </div>
  <div class="view-content" id="rightcol">
    <div class="views-row views-row-3 views-row-odd"> ... </div>
    <div class="views-row views-row-4 views-row-even views-row-last"> ... </div>
  </div>
</div>

The solution to building this markup is with PHP in a views template. The next trick is to choose the right one! Editing your view, click on the Advanced tab, then on Theme: Information. We want to use the Display output template. So, for example, mine is called: views-view--columns--page.tpl.php.

First, we'll make a preprocess function in our template.php file specific to that views template file that finds the number of view results and the halfway point.

This first function here is a helper function for Drupal 7 so you can add preprocess functions to specific views on the fly:

<?php
 
function THEME_preprocess_views_view(&$vars) {
    if (isset(
$vars['view']->name)) {
     
$function = 'THEME_preprocess_views_view__'.$vars['view']->name;
      if (
function_exists($function)) {
      
$function($vars);
      }
    }
  }
?>

And here's the preprocess function:

<?php
 
function THEME_preprocess_views_view__columns(&$variables) {
   
$view = $variables['view'];
   
// Create a variable that divides number of results in half and add one.
   
$variables['half'] = ceil((count($view->result) / 2) + 1);
  }
?>

Once you have determined the $half variable, which is row number that starts the second column.

So let's add the markup to the views tpl file.

Replace the lines:

<div class="view-content">
  <?php print $rows; ?>
</div>

with:

<?php
 
// remove white space in html
 
$rows = preg_replace('~>\s+<~', '><', $rows);
 
// add the </div><div> in at the halfway point to separate the columns
 
$search = '<div class="views-row views-row-' . $half;
 
$replace = '</div><div id="rightcol" class="view-content"><div class="views-row views-row-' . $half;
 
$rows = str_replace($search, $replace, $rows); //
?>

<div class="view-content" id="leftcol">
  <?php print $rows; ?>
</div>

This will wrap the first half of your results in a leftcol div and the second half in a rightcol div. From there, float your columns and add the necessary padding. Enjoy!

Aug 09 2011
Aug 09

My first ever Fuse blog post will focus on the Context module developed by the DC based Development Seed. With 29577 reported installs of the module, Context is quickly climbing the module ranks. It's already part of our base install for all sites we work on here at Fuse. 

Simply put, Context lets you determine specific reactions on a set of conditions. On every page load, it checks to see if any active contexts have conditions that have been fulfilled, and if so, it performs the reaction. To show you how it works I will give you an example of what can be achieved with Context.  In this example we want to create an active menu trail for content tagged with a specific taxonomy term. That taxonomy term will be your condition and the reaction is the desired active menu trail.  Here are the steps to take to make this work: 

1. Install Context:

As of today, the latest version of context is 7.x-3.x, which is not that different from the version 6.x-3.0. I will be working with Drupal 7 version since we're using D7 for all our new builds at Fuse. Install Context the usual way just don't forget CTools, as it is a dependent module. In Drupal 6.x environment you will also need the jQuery UI module which provides you with an admin interface for some extra features. (D7 has the jQuery included within core)

2. Add a new context:

Under Structure > Context you’ll get a list of all the contexts you've created and a search bar. You should be looking at an empty list after installing the module.

On top you can +Add or +import. Lets add a new context for now (we’ll get to importing a bit later.) Adding a new context will prompt you for Name, Tag a description. The "Tag" field will be used to group contexts on the context listing page.

3. Set your conditions:

This is where you will set the various conditions for your context. As mentioned above, conditions are checked on page load, and if the condition is met, the configured reactions are performed. Context comes built in with quite a few default conditions that will probably, for the most part, fulfill your needs. However Context is fully extendible and there are already modules out there that provide new and exciting conditions and reactions. This extendibility is discussed further at the end of this post. For now, we'll just go over the default conditions:

Context: The condition is met, if another context's conditions are met. Perfect for recycling your already set context, if there are currently active contexts that you would like to base your new context on, the context option would be perfect for it. I hardly ever duplicate the exact same condition set between two or more contexts, but there is the odd time when I like to use a context I have already set and fine tune it (ie. create another condition on top of it).
Menu: Allows you to select any number of menu items. The condition is met when any of the selected menu items belong to the current active menu trail.

Node Type: Select from a list of node types. The condition is met when viewing a node page (or using the add/edit form -- optional) of one of the selected content types. 

Taxonomy: Your condition is met if the current node being viewed is referring to a particular taxonomy term. Don't confuse this condition withTaxonomy term.

Path: Allows you to supply a list of paths. The condition is met when any of one or more paths match the supplied paths.

Site-wide Context: The condition is met at all times.

Taxonomy term: Will set the context when viewing the taxonomy term's page (not a node that is referring to that taxonomy term).

User Role: The condition is met if the current user has one of the selected role(s).

User Page: Lets you choose from a list of 'User' pages. (i.e. User profile, User account form, Registration form). Condition is met when viewing the selected pages.

Views: This option will list all active views and their specific generated pages. This allows you to trigger your context for any pages that a particular view is active on.

4. Set your reaction:

Once your conditions are set, it's time to set up your reactions. Once again, we'll just go over a few of the reactions that comes with Context built-in:

Blocks: The blocks reaction is probably my most used reaction of all. It allows you to place any block in any region when the condition is met. This provides a much more flexible way to add blocks to the page than the blocks administration page (admin/structure/block) since you can use more than just the path as the criteria for when a block should be visible or not.
 

Note: 

There is one tricky thing when using Context to place your blocks and that is the ordering of the blocks within a particular region. Within a context, it's easy to reorder the blocks within a region using the standard drupal drag and drop interface. However, If you have two

different

contexts adding blocks to the same region you will need to order them manually. Under the "+add" in the region header, click the 

 icon and the weight field will appear. Here you can assign a specific weight number to your block. The weight will be respected accross all contexts so you just need to make sure the blocks you want to appear first have lower weights than ones you want to appear after.


By drag and drop sort method vs. weight select sort method:

 

Breadcrumb: Set the breadcrumb trail to a particular menu item.

Menu: Set the Menu Active class

Theme Page: Override the section title and the section subtitle of the page. This will also override your $section_title and $section_subtitle variables within your page.tpl.php.

Theme html: Add an additional html body class to the page

5. Import / Export:

You can easily export an Context by clicking on "Export" (under Operations) on the Context listing page.

The result will be a block of text that can be copied and then imported back to another site. Just select "+Import" from the top (next to the "+Add" button) and paste the exported text. Hit save and you will have an exact copy of the context.

6. Context Editor:
 

Having the Admin menu module installed, there is the handy context editor window for testing and editing contexts. Active contexts are easily detected and can be modified on the fly by adding conditions, blocks (drag and drop) and theme variables.

7. Book keeping:
 

Usually on substantial projects the Context overview list gets messy and a bit confusing. When there are a lot of contexts it can be hard to find the one that is outputting a certain block on a certain page. To avoid this confusion I recommend a few things:
 

  • Write Descriptive Descriptions! It sounds redundant, but the better your description is, the easier it will be to figure out which context is outputting "that block" in "that region" on "that page".
  • Use Tags Wisely! Tagging can be very useful since the contexts on the context listing page get grouped by tag. If you group your contexts intuitively using tags, you'll spend less time finding your contexts and more time trying to figure out if we're ever going to get multigroups back.
     

8. Extending Context using the API

As mentioned above, Context comes with an API to extend it's functionality by adding custom conditions and reactions. An example of one of these modules is Background Images (built by Fuse's own Chris Eastwood). It provides a new reaction that can change the background image of any css-selectable element on the page. While this tutorial will not delve into how to use the API to extend context (perhaps in another tutorial down the road?), I thought it was worth mentioning in case you need a condition or reaction that isn't built-in. You know how it often goes with Drupal, if it's not built-in, there may just be a module for that! 

Jun 07 2011
Jun 07
Notable changes to theming in Drupal 7

There are 50+ changes to the theme system in the move to Drupal 7 - that's a lot to consider when upgrading your theme from Drupal 6 to Drupal 7. As expected, some of the changes make theming more complex... but those changes can also free things up for you to do complex things in a simpler way. Some things have been broken down into smaller pieces so you can do more with them, and some tasks you did repetitively across different themes are now automated.

Node Jenga

So far, you've come to grips with two common ways of getting fields to print in the node template (in the order you want):

  1. Drag and drop fields into the order you want them via the "Manage Fields" page for a given content type in that content type's Manage Fields page.
    This is only a global solution for your site, and you don't really have a way to sort fields in different contexts. Your node template gives you $content which prints out all the fields associated with that node. While this works just fine for simple sites, what happens when you want the fields to display in different orders when seen in different situations? In Drupal 6, if you want your node to display its fields in a certain order for the "full" node version, but in a different order for its teaser version, then you're out of luck (without writing custom code or perhaps using a contrib module for that functionality).
  2. Print fields out directly.
    If you want to print out certain fields, you've been able to search the $node object for the particular field you want and print it directly, getting around having to use $content altogether. An example of that would be <?php print $node->content['field_myfieldname']['#value']; ?>

In Drupal 7, you can sort fields for both the "default" and "teaser" formats, among others, from the content type's "Manage Display" page. However, be aware that if you rearrange your fields in the manner, it also affects the order of the fields shown on your node's "edit" form (a tip of the hat to commenter Matthias for making this point). If you want to order your fields in a way that the "Manage Display" page won't allow you to... or if you don't want your node edit form mangled, you can take your node's $content and print things however you want (or conversely, NOT print things) from within the template, so you never have to mess with the content's "Manage Display" page, or break apart $node. For this approach, we have two new functions available to us:

  • hide()
    Now you can use, for example, <?php hide($content['links']); ?> at any point before the content gets printed and those parts of the $content will not be rendered with everything else.
  • render()
    So you've decided which fields/parts of $content you don't want in the big old chunk of $content, and now you use <?php print render($content); ?> to print the rest. Everything that wasn't first hidden with hide() will now be printed out. You can then use <?php print render($content['links']); ?> to print what you originally hid in $content.

Of course, if you can sort your fields the way you want them using the admin pages for your content type, you should probably do that before adding unnecessary code to your node templates or preprocess functions.

Say goodbye to .clear-block

The Drupally way of clearing floats within container elements was the .clear-block class. In Drupal 7, this class has been renamed to .clearfix. This seems to be a little more descriptive of the point of the fix in the first place, and does less to confuse beginners with Drupal's "block" system which is unrelated.

Hiding stuff

Special standard classes to identify elements as hidden have been added to core CSS:

.element-hidden is for hiding things on page load, and it can be used in junction with jQuery's .show() and .hide() to toggle something as hidden or not. An example of usage of this class attribute would be to put it on a dropdown menu (<div> or <ul>, or whatever floats your boat) that only displays when its parent main menu item has been hovered on.

.element-invisible is for elements you want permanently hidden (but still viewed on screen readers for accessibility reasons). If you ever do any image/text replacement work, you can probably see how this will be useful.

Form overrides

When I first got started with Drupal, I found it particularly difficult as a themer with beginner's PHP skills trying to figure out how to take a form and make modifications: re-order fields, change labels, remove fields, add markup... that kind of thing. Eventually you learn that form overrides can be done in a custom module using hook_form_alter(), or by using hook_theme() in template.php to establish a form override function and do your magic there. As a themer, in most cases, your form changes don't fundamentally change how the form's functionality works, and you usually do your form override in template.php.

Well, now hook_form_alter() is available for use in the theme layer. This means you don't have to go through hook_theme() anymore and you can just jump in and modify whatever for you want using the $form_id that comes in as an argument via hook_form_alter() and hook_form_FORM_ID_alter():

For example, to add a new "search-field" class to your search block's text field, you would simply drop the following into your theme's template.php:

function yourtheme_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'search_block_form') {
      $form['search_block_form']['#attributes']['class'][] = 'search-field';
  }
}

As you can see, we're checking for $form_id to do these overrides on a case-by-case basis. You can add more IF statements to this function to other overrides for different forms. Alternatively, you can use hook_form_FORM_ID_alter() to break your forms into separate functions, like this:

function yourtheme_form_search_block_form_alter(&$form, &$form_state, $form_id) {
      $form['search_block_form']['#attributes']['class'][] = 'search-field';
}

So, form overrides are a little bit easier and simpler in Drupal 7.

In related news, fellow Advomatic developer Aaron Winborn discovered today that ALL _alter functions are now available to the theme layer in D7 (currently happening in the middle of drupal_alter() if you're curious). This allows for things like hook_js_alter() or hook_css_alter() in themes, which some of you may find useful.

Thanks for reading, and stay tuned for part two.

Feb 20 2011
Feb 20

A lot has changed since March 2010.

how to get started
The presentation is for people who are new to Drupal theming, as well as those who want to get a better sense of what's new in Drupal 7 theming.

I expanded on the previous presentation, clarified some points, and replaced a few slides with better ones.

A video of my slide presentation is available on the DDCLA Blip TV site. The slides are kind of fuzzy because the recording app captured my presentation notes screen instead of my presentation screen. My sincere gratitude goes out to John Romine for taking care of all the session videos, including the cropping of my session to just the relevant slides.

It was great meeting various folks at Drupal Design Camp LA. Big thanks to Christefano and Lee Vodra for their wonderful hospitality!

Pages

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