Make Views More Flexible/Maintainable

Posted on May 24 2008 in Web Development

Any Drupal developer worth his salt at least knows of the Views module. The shear usefulness and time-saving nature of views has earned the module a place in every Drupal site I've developed. However, because views are stored in the database and their presentation is controlled by the views module itself, managing views between staging/live sites, handling updates, and tracking revisions become difficult issues when dealing with Views. On the other hand, source code is easily managed between copies of a site, updates are a breeze, and revisions are natural -- all of this with revision control, such as Subversion. Also, what if you want to implement complicated access rules for your view?

Views documentation has a section on how to programmatically build and render views. This is great, but building a view programmatically takes a lot more time than using the Views UI because you're constantly trying to figure out the table/field names used by the various modules that provide views integration, let alone filter, field, and argument settings. If your development cycle is anything like mine, taking more time on something is not always a luxury you can afford.

Views module also provides an interesting Import/Export feature that allows you to copy/paste a view definition between sites. This helps with moving a view between two copies of a site and even helps a little dealing with updates. If you're diligent, this could be used to deal with revision control as well, but it's still a little clunky if you're maintaining and building sites all the time.

In my opinion, the sweet spot when dealing with views is combining views exports with embedding views in your own PHP code.

Every Drupal site I've developed as ended up with a "custom" or "glue_code" module that does various minor modifications to the site, such as hook_form_alter, hook_nodeapi, hook_menu, etc. I've also started to use this type of module to render and provide default views using the following process:

  1. First, during development of your site, go ahead and design the view using the Views UI as you normally would. We'll call this view example_view.

  2. Once you have the view's page display the way you like it, keep the page display enabled, but clear the URL so that the view page isn't really accessible anywhere on your site.

  3. Now, export the view and copy the large export array that is provided.

  4. Implement hook_views_default_views() in your custom module. Simply paste the exported views array into this function. Be sure your code makes sense and returns something according to the hook spec.

  5. Delete the view from your site, because your custom module will be providing it now.

  6. In your custom module, add a new hook_menu item that points to a callback that will provide the view. For the purpose of this example, our callback is called 'custom_view_page'.

  7. The custom_view_page() function will then look something like this:

    function custom_view_page() {
      $view = views_get_view('example_view');
      return views_build_view('embed', $view);
    }
    

That will retrieve the view (the default one provided by your implementation of hook_views_default_views OR the overridden version if you've defined a view in the UI by the same name), then render it for output. If you need to send arguments to the view, pass them as elements of an array in the third parameter sent to views_build_view().

Benefits:

  • View definition is no longer in the database.
  • Updates are performed by updating code base. Simply build updated version of view on dev/staging site, export, and update the hook_views_default_views() implementation.
  • Revisions of changes to view are kept in source control.
  • All benefits and flexibility of views is maintained.
  • Finer control over things like access to the URL that provides the view.
  • Possible performance gains (untested).