|Read more about this book|
(For more resources on Drupal, see here.)
Including a CSS file in a theme
This recipe details the steps involved in adding a CSS file to the theme via its .info file. In this case, we will be adding a CSS file to the mytheme sub-theme which we created in the previous article.
Create a CSS file inside the theme’s folder named mytheme.css and add the following example rule to it:
color: #996633 !important;
This rule should override and change the color of all text on the page to a brownish hue.
How to do it…
Adding a CSS ﬁle to a theme is best accomplished via its .info ﬁle. Navigate to the theme’s folder at sites/all/themes/mytheme and open the mytheme.info ﬁle in an editor. Add the following line to this ﬁle to include our CSS:
stylesheets[all] = mytheme.css
If the CSS ﬁle is stored along with other stylesheets in a sub-folder named css, the syntax would include the relative path to the ﬁle as follows: stylesheets[all] = css/mytheme.css.
Once done, save the ﬁle and exit the editor. Since we have modiﬁed the .info ﬁle and introduced a new ﬁle, our changes will not take effect until the theme registry is rebuilt. Therefore, clear the Drupal cache and view the site to conﬁrm that our new stylesheet has been included correctly. The theme should now display all text in brown.
How it works…
Drupal checks the .info ﬁle and notes that we have declared stylesheets using the stylesheets variable. The syntax of this variable is similar to that of an array in PHP. The all index in the syntax represents the media type as used in CSS declarations.
The next screenshot displays a section of the source code of a page which conﬁrms the inclusion of the new stylesheet, mytheme.css. We can also see that our sub-theme is including the stylesheets declared by its base theme—Garland—as well as its own stylesheets.
In the preceding screenshot, we can see that Drupal references each stylesheet along with a query string. For example, mytheme.css is included as mytheme.css?e. This rather quirky sufﬁx is a trick used by Drupal to ensure that browsers do not use stale copies of a cached CSS ﬁle while rendering our site.
We can test this by clearing the Drupal cache and viewing the source code once again. Now, our stylesheets should have a different sufﬁx— perhaps, something like mytheme.css?A—thereby tricking browsers into believing that these are different ﬁles and using them instead of their cached copies.
One of the advantages of using a sub-theme is that we can easily override elements of the base theme. This includes stylesheets as well.
Overriding the base theme’s stylesheet
If the base theme includes a stylesheet named layout.css, adding a stylesheet of the same name in the sub-theme will override the base theme’s stylesheet. In other words, Drupal will include the sub-theme’s stylesheet instead of that of the base theme.
Enabling CSS optimization
CSS optimization in Drupal is accomplished through two steps—aggregation and compression. This optimization provides a signiﬁcant boost to performance both on the server as well as for the user. This recipe details the steps to be performed to enable this feature in Drupal.
CSS optimization is a requirement only when a site is ready to go live. Until such time, it is recommended that it be left switched off as CSS changes during development will not take effect unless the Drupal cache is cleared.
How to do it…
Public File system
As the screenshot states, the optimized CSS ﬁle is cached using Drupal’s ﬁle system which needs to be set to public to ensure that the user’s browser can access and download it. Therefore, it is necessary to set Download method of the Drupal ﬁle system to Public. This can be done via admin/settings/file-system (Home | Administer | Site conﬁguration | File system).
Once done, click on the Save conﬁguration button at the bottom of the page to save our changes.
How it works…
Aggregation involves the collating and joining of multiple CSS ﬁles into a single stylesheet, while compression reduces the resulting ﬁle to a smaller size by trimming out unnecessary elements such as whitespace. The former helps in reducing the number of ﬁles that the server has to load and serve. The latter saves on bandwidth and time.
The previous and following screenshots demonstrate CSS optimization at work. The previous screenshot is a snippet of the HTML source of a Drupal page running on a stock Garland theme. As displayed, this involves the server performing look-ups and serving eight separate CSS ﬁles—seven for all media types and a print stylesheet—for each and every page served. If this is extrapolated to sites of greater complexity, the number of ﬁles and, consequently, the server and bandwidth load, begin to take on signiﬁcant proportions and can seriously impact performance.
The preceding screenshot is of the same page as before with one difference—CSS optimization is now turned on. The number of CSS ﬁles has now been reduced to only two—one for all media types and the other being the print media type. These stylesheets are stored in the files folder and are cached copies. As a result, each page load now only involves the webserver serving two ﬁles instead of the previous eight.
CSS optimization and other performance improvements should be used with care.
When to use it
CSS optimization is only necessary to improve performance on production sites. Enabling it beforehand will only hinder theme development.
Enabling optimization can sometimes be handy when working on sites which are using more than 31 stylesheets—a not too infrequent occurrence on sites using a plethora of modules and an elaborate theme—as this is an upper-bound for Internet Explorer. IE will only load the ﬁrst 31 stylesheets and ignore the rest. Drupal’s CSS optimization feature reduces this number to one, thereby conveniently working around the issue. An alternative is to use modules such as IE CSS Optimizer (http://drupal.org/project/ie_css_optimizer).
Creating the mysite module to hold our tweaks
In the course of developing our site, we will frequently come across situations where various elements of the site need to be tweaked in PHP using Drupal’s APIs. While a lot of theme-speciﬁc cases can be stored in template ﬁles, certain tweaks which are theme-agnostic require that we store them in a module to ensure that they are available to all themes.
This recipe covers the creation of a module to hold all these bits and pieces.
Create a folder inside sites/all named modules. This is where custom and contributed modules are usually housed.
How to do it…
The following list details the procedure involved in creating a module named mysite to hold our theme-agnostic customizations and other odds and ends:
- Create a folder inside sites/all/modules named mysite where mysite refers to the name of our site.
- Create a ﬁle named mysite.info within the mysite folder.
- Edit this ﬁle and add the following code inside:
name = Mysite
description = A module to hold odds and ends for mysite.
core = 6.x
- Save the ﬁle.
- Create another ﬁle named mysite.module which will hold our odds and ends.
- Save and exit the editor.
- Finally, enable the module via the module administration page at admin/build/ modules (Home | Administer | Site building | Modules).
How it works…
Just as with themes, modules require a .info ﬁle which provides information to Drupal on compatibility, dependencies, and so on. Once Drupal ascertains that the module is compatible with the version installed, it loads the .module ﬁle of the same name and processes it accordingly.
We can test if the module is working by adding a snippet such as the following:
* Implementation of hook_init().
// Display a message on every page load.
drupal_set_message("Welcome to MySite!");
As the comment suggests, the preceding snippet will display a welcome message on every page load.
The Drupal community routinely comes up with modules to ease the pain of development.
There’s a module available named Module builder which can be used to generate a skeleton of a general module. This can subsequently be populated as per our requirements. It is available at http://drupal.org/project/module_builder.