Skip to main content
Steven Merrill

Speed Up and Version Your Views

This post was originally posted on the Phase2 Blog.

Since getting started with Drupal over two years ago, the sites I’ve built with it have naturally gotten bigger and bigger in scope. As your sites get bigger and bigger, you always look for ways to keep your site running as smoothly as possible, and this usually ends up meaning getting rid of queries wherever you can.

One feature of Views which is often used by module developers is the ability of a module to expose a set of default views. The calendar module, for example, provides a default calendar view in both its Drupal 5 and 6 versions. This is an obvious asset for developers of contributed modules: if your module interfaces with Views, it makes sense to provide a default view that users can modify.

Implementation and Potential Benefits #

The hook used to do this is hook_views_default_views(). Since most modern sites are run off of a number of Views, you can also realize several benefits by building your sites with a custom module that implements hook_views_default_views():

  1. It improves performance. Views implemented via hook_views_default_views() do not require a database query to instantiate. You will realize an even greater performance gain if you also use an opcode caching system such as APC or XCache.
  2. Providing views in code will allow you to override the default view to make changes, and you can then choose to keep the changes in the database, update the module file to reflect the changes, or revert back to the version in your module file.
  3. Because the view (and theoretically, changes to that view) are stored in files, you can put them in version control and see how the views used in your site change over time and revert to an earlier version without having to go to a database backup.

Views2 / Drupal 6 Implementation #

Here’s how to do it in Views2 on Drupal 6. When implementing a site, we at Tree House usually end up with a utility module that will do some of the things that will need to do theming or development tweaks, like the odd hook_form_alter(), or provide a Views handler or two. I’ll be calling this module treehouse_utils. There’s two steps to providing a default view in Drupal 6 and Views2: you need to tell Views2 that you implement the Views2 API, and then you have to create a file that contains the default view(s).

So first, in treehouse_utils.module, it’s time to tells Views2 that we’re implementing Views features with hook_views_api(). The implementation of the hook looks like this in our module:

function treehouse_utils_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'treehouse_utils'),
  );
}

This module just tells Views2 that we’re implementing version 2 of the Views API and that it should look for Views-related files in the directory of the treehouse_utils module. (Some other modules will make a separate directory called includes where its Views-related files will live.)

Putting the Views in Code #

The other task that we need to do is to implement hook_views_default_views() and actually tell Drupal about our Views. It is possible to do this in the main treehouseutils.module file, but the trend in Drupal 6 is towards using more files so that Drupal has less code to load and parse overall on each page request. You can implement hook_views_default_views() (as well as a smattering of other Views-related hooks) in a _MODULENAME.views.inc file. In the case of hook_views_default_views(), you can implement that in its own file, MODULENAME.views_default.inc.

So here’s what treehouse_utils.views_default.inc will look like:

<?php

function treehouse_utils_views_default_views() {

  $views = array();

  // Start copy and paste of Export tab output.

  // End copy and paste of Export tab output.

  // Add view to list of views to provide.
  $views[$view->name] = $view;

  // ...Repeat all of the above for each view the module should provide.

  // At the end, return array of default views.
  return $views;
}

Implementations of hook_views_default_views() are expected to return an array, so for each view that you would like to have provided by a module, go to the Views2 administrative interface, click Export, and copy and paste the PHP code between the two comments, and also be sure to include the $views[$view->name] = $view; line, where the newly-defined view object gets included in the array that will be returned.

Finally, when your module is enabled (or when you next visit the Views2 administration page or otherwise clear Views2’s caches,) you’ll see the following:

Notice that because the view which I put into the module is also in the database, Views tells us that the view is overriden - a default is now provided in PHP code, but our version in the database still supercedes it. If you were to click Revert, the database entry for the view would be deleted, and Drupal would load it from your MODULENAME.views_default.inc file.

Continuing this Workflow #

At this point, you can check your module into version control and have a record of your view at this point in time. Later, you could make some more changes in the Views2 UI, hit Export again, and paste the newer version into the file, check that into version control and continue.

Views2 is amazing, and these techniques let you squeeze a little more performance and a lot more possibilities for revision control while building out your sites.

Also, be sure to vote for Thomas’s DrupalCon session if you’d like to look at concrete techniques of all types to scale your Drupal sites!