Let’s say we found a useful bit of JS or CSS that we’d like to use within our Drupal site. For example, this jQuery ListNav Plugin. An ideal way to accomplish this is by adding it to Drupal’s Library API. Here’s how to do it.
First, make sure you have the Libraries API module installed and enabled.
Next, we’re going to write a custom module that implements hook_libraries_info() to add our custom library to Drupal’s set.
The jquery_listnav.info file:
1 2 3 |
name = jQuery List Navigation description = Adds Eric Steinborn's jquery-listnav plugin to Drupal Libraries core = 7.x |
and the hook_libraries_info() implementation within jquery_listnav.module:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php /** * Implements hook_libraries_info(). */ function jquery_listnav_libraries_info() { $libraries = array(); $libraries['jquery-listnav'] = array( 'name' => 'jQuery ListNav', 'vendor url' => 'http://ericsteinborn.com/jquery-listnav/', 'download url' => 'https://github.com/esteinborn/jquery-listnav/tarball/master', 'version arguments' => array( 'file' => 'jquery-listnav.min.js', 'pattern' => '/v(\d+\.+\d+\.+\d+)/', 'lines' => 1, ), 'files' => array( 'js' => array( 'jquery-listnav.min.js', ), 'css' => array( 'css/listnav.css', ), ), ); return $libraries; } |
First, we create a new $libraries array and then define a key => value pair within $libraries for our new library. The key is the name of our new library within Drupal’s eyes — in our case it’s “jquery-listnav”. The value is another array of information about our new library.
We’ve defined the following bits of info about our library:
- name
- vendor_url
- download_url
- version_arguments (which is itself yet another array)
- files (which is itself yet another set of multi-dimensional arrays)
The former three (name, vendor_url, and download_url) are pretty self-explanatory but let’s dig into the latter two.
The ‘version arguments’ key tells Drupal where it can find information about the library’s version.
The ‘file’ key points Drupal to where the file is located. In this case, since our library is only one file, the version is contained therein. If your library consists of many different JS and/or CSS files, you may have an .info file which contains the version data or it may be in only one of the files.
The ‘pattern’ key is a regex expression that tells Drupal how to find the version of the library (if any exists).
The ‘lines’ (optional) key tells Drupal the maximum number of lines to search for the aforementioned regex. It defaults to 20 so if you know your version is always on line 1 (say, in a minified version of the code in question), you can save some cycles by specifying such here.
Next, the ‘files’ key is the crucial data point as it tells Drupal where to find the files that should be included in this library.
The ‘js’ key is yet another array that contains the file names of JS files to include in this library. We’ve packaged the JS file in the same directory as our module but it could easily be in the theme itself.
The ‘css’ key is the same as the ‘js’ key but for CSS files.
There are quite a few more available keys in the $libraries array definition including declaring dependencies and utilizing external libraries. You can read more about them on the Drupal 7 API Reference page for hook_libraries_info().
Finally, one last thing I’d like to cover is how to load a library and add it to a specific page.
1 2 3 4 5 6 |
function my_theme_views_pre_render(&$view) { if ($view->name=="directory") { libraries_load('jquery-listnav'); drupal_add_js("jQuery(document).ready(function() { jQuery('#directory-list').listnav(); });", 'inline'); } } |
I’d like this library to load on all displays of a specific view named ‘directory’. So in my template.php file in my theme, I implement theme_views_pre_render() and create an if-block for that case.
Then I call:
1 |
libraries_load('jquery-listnav'); |
to load the library we created earlier. Now that that JS is available, I call drupal_add_js() to run the pertinent JS function.
Sometimes we’ll want a library loaded and available on all views, or all pages. In that case, you could employ the same tactic but remove the if-block from the theme_views_pre_render() call. You could even do it in something like hook_init().