In the course of a day as a Drupal Themer, I need to code a wide variety of functionality into a given site I'm working on. I try to follow Drupal best practices as well and this usually means implementing theme preprocess functions; these become key to a Themer's toolbox. This article is a selection of snippets I've picked up along the way that might help others out. When I first started building with and theming Drupal several years ago, at first I did not see the value of preprocessing but it's turned out to be quite valuable.
Add JS or CSS with a Pattern Match / Wildcard
This method is ideal if you want to add special or custom JS or CSS files to a specific path with a pattern match or wildcard. For example I might have unlimited URLs associated with a Taxonomy with patterns such as:
… but then maybe I want to also add this code to some individual pages not associated with the Taxonomy. I can do something like this with a preprocess HTML function.
As you can see from the above code, we are adding JS to anything under the path or
/portfolio/ but also to a page called
foo-page. Note the
newline character between the two pattern matches as well as the
* which serves as a wildcard. We are also using the Drupal API
path_alias which returns the alias of an internal path. You can imagine the possibilities using this method which could potentially cut back on the number of scripts being aggregated on any given part of your site.
The one caveat using this method is that you'll want to be sure to add a test to your script instantiation. So for example, in my scripts file, if I am instantiating the above script, I want to be sure to add an
if clause, otherwise you run the risk of calling the script when it does not exist on various pages which would in turn throw a nasty error. So you'd want to do something like so:
Weight, Scope and Group
In certain cases, you need to load a script last or set a specific weight to place it at a specific point in relation to other scripts that are loading. This can be achieved by "weighting" and "scoping." Scope has two possible constants,
JS_THEME but there's also two other constants available,
JS_LIBRARY which would commonly be used within a module context. Below is a sample
Note also that
preprocess is set to
TRUE as we want this internal script to be aggregated. However, there's some cases where you'd set this to
FALSE perhaps in the case of an external JS file. The high weight number would most likely make it load last but it's a good idea to test this with aggregation off on your dev site so you can actually see where and how it loads. Play with the number if you don't get the desired result.
You can also weight CSS and it has three group constants available as per the Drupal API page:
- CSS_SYSTEM: Any system-layer CSS.
- CSS_DEFAULT: (default) Any module-layer CSS.
- CSS_THEME: Any theme-layer CSS.
It should be pointed out that the groups themselves have weight so you can really fine tune this using a numbered weight as well as a named group 'weight'.
if you still develop for older versions of Internet Explorer (gasp!), there's a nice
add_css Parameter called
browsers which combines with the
drupal_pre_render_conditional_comments function. This is also a theme
preprocess_html function. For example, if you want to render an IE8 fixes stylesheet conditionally, you could do something like this:
Here we say that we want this to be a conditional stylesheet for less than or equal to IE8 and false for all others and this would render as:
There's plenty of other parameters, options and constants for adding CSS and JS within theme preprocessing functions and I suggest checking out the Drupal API pages, links referenced below. There's your tips from a themer, I'll be back sometime soon with more!
- function drupal_add_js
- function drupal_get_path_alias
- function drupal_add_css
- function drupal_pre_ render_conditional_comments