Skip to content Skip to navigation

Adding Default Views and Pages to a Custom Module

Posted by: 
Topics: 
Note: This post is preserved here for legacy purposes only. The Features module makes the process detailed in this post largely obsolete, and it's recommended that you use Features instead.

If your site makes heavy use of Views and Panels, you can speed things up by storing your Views (and Panels) in code, rather than in the database. Views' API allows modules to contain default Views; an example of this is the Calendar module, which includes a default Calendar View.

This article will detail how to do this for both Views and Panel Pages, as well as a technique for organizing the default Views/Panels in a more orderly fashion. The general approach is the same for both Views and Panels, so I will explain the method for Views first, then detail the minor differences with Panels.

Most of the information in this tutorial was taken from the Views Online Help article, "Using Default Views in Your Module".

Advantages of this approach include:

  • Speed: loading PHP code from the web server is faster than loading it from the database
  • Separate Development from Production: You can configure a View in a development environment, then export it for use in production, and never have to use Views UI on the production site
  • Version Control: Furthermore, you can then use your favorite version control system to keep track of changes to Views that are stored in your custom module

Views

Getting Started

We'll assume you have a custom module already built for your site, or at least are familiar with the basics of building a custom Drupal module. There are three basic steps to add default Views to your module:

  1. Tell Views to look for them
  2. Export your Views
  3. Put your exported Views into your module

Here's a bare-bones mymodule.info file, which will work for creating a custom module:

; $Id$
name = Splendiferous Custom Module
description = "Custom module demonstrating default Views"
version = 6.x-1.x-dev
core = 6.x
dependencies[] = views

Or you can download a bare-bones module to use as a template.

Step 1: Tell Views to Look for Your Module's Default Views

In order for the Views module to know about your module's default Views, you need to tell it. All you have to do is put the following lines in your mymodule.module file (Note: Replace "mymodule" with the name of your custom module anywhere it appears here):

<?php
/**
 * Implementation of hook_views_api().
*/
function mymodule_views_api() {
  return array(
    'api' => 2.0,
  );  
}

That's it! Now Views will look for default Views in a file named mymodule.views_default.inc.

Step 2: Export Your Views

Go to admin/build/views and click the "Export" link next to one of your custom Views. This will bring up a text area with many lines of PHP code. Select all of the code in the text area and copy it to your clipboard.

Step 3: Put the Exported View in Your Custom Module

In order to make the exported View available for use, you need to create a file named mymodule.views_default.inc. The contents of that file can start as the following:

<?php
/**
 * Implementation of hook_views_default_views().
 */
function mymodule_views_default_views() {
 
  //PASTE EXPORTED VIEW CODE HERE
 
  $views[$view->name] = $view;
  return $views;
}

Be sure to include the opening <?php tag, but omit the closing tag.

Paste the code of your exported View in where it says "PASTE EXPORTED VIEW CODE HERE". You could paste multiple exported Views in this file, and (once you clear Views' cache), they would all be available as default Views in your site.

However, once you have more than a couple of Views in your mymodule.views_default.inc file, it gets unwieldy, and could be many thousands of lines long.

To avoid that, we'll make each exported View and individual file, but first we must tell hook_views_default_views() to scan a subdirectory for those files and convert them to View objects.

Step 3.5: Tidy It Up

Delete all the code in your mymodule.views_default.inc and replace it with the following:

<?php
/**
 * Implementation of hook_views_default_views().
 */
// Declare all the .view files in the views subdir that end in .view
function mymodule_views_default_views() {
  $files = file_scan_directory(drupal_get_path('module', 'mymodule'). '/views', '.view');
  foreach ($files as $absolute => $file) {
    require $absolute;
    if (isset($view)) {
      $views[$file->name] = $view;
    }   
  }
  return $views;
}

This tells Views to scan a subdirectory named "views" in your module directory, look for files ending in ".view", and create default Views for them based on the name of the .view file.

Create a subdirectory named "views" in your module directory. In the "views" directory, create a file named myview.view. The name of this .view file must be the same as the machine-readable name of your View. Your myview.view file will look like this:

<?php
  //PASTE EXPORTED VIEW CODE HERE

Be sure to include the opening <?php tag, but omit the closing tag.

Paste in the code from your exported View then save the file. Clear Views' cache (at admin/build/views/tools).

screenshot of clearing Views' cache

Your View should now say overridden in the list of Views. Click "Revert" and your View will load from code and not from the database! (Note: It should go without saying that you need to have enabled your custom module in order for this to work.)

screenshot of Views list

Review

  1. Call hook_views_api() in your custom module
  2. Export your View code
  3. Call hook_views_default_views() in mymodule.views_default.inc
  4. Paste your exported View code into mymodule/views/myview.view
  5. Clear Views' cache
  6. Revert your View

Panels

OK, let's do the same thing with Panel Pages.

Call the Hook in Your Custom Module

Add the following code to mymodule.module:

/**
* Implementation of hook_ctools_plugin_api().
*/
function mymodule_ctools_plugin_api($module, $api) {
  if ($module == 'page_manager' && $api == 'pages_default') {
    return array('version' => 1); 
  }
}

Create the Default Pages File

Create a file called mymodule.pages_default.inc in your modules root directory with the following code:

<?php
/**
 * Implementation of hook_default_page_manager_pages().
 */
function mymodule_default_page_manager_pages() {
  $files = file_scan_directory(drupal_get_path('module', 'mymodule'). '/pages', '.inc');
  foreach ($files as $absolute => $file) {
    require $absolute;
    if (isset($page)) {
      $pages[$file->name] = $page;
    }   
  }
  return $pages;
}

Create the Individual Default Page Files

Create a subdirectory named "pages" in your module's directory

Create a file named mypage.inc in the "pages" subdirectory and paste in the code from your exported Panel Page. Be sure to include the opening <?php tag, but omit the closing tag.

Clear your cache and your pages should appear as Overridden at admin/build/pages. On the edit screen for the Page, you can click "Revert" to delete what's stored in the database and load the Page straight from code.

screenshot of reverting a Page at the edit screen