Overriding default views in code

Last updated on
1 December 2016

Drupal 7 will no longer be supported after January 5, 2025. Learn more and find resources for Drupal 7 sites

One of Views' most useful features is being able to export a view into code. This has a few benefits:

  • A view in code can be managed with revision control systems (git, svn, etc).
  • A view in code can be included in a module as a "default" view; for example, the Views module includes a replacement for the standard taxonomy term page structure.

Once a view is put into code, you can override it in the Views user interface (add extra fields, add displays, add arguments, etc.). Rather than leaving the modified view stored in the database, and having it be listed on the Views main administration page as "Overridden", it is considered a good practice to save the modified view back into code, rather than leaving the changes in the database only. There are two ways to do that.

Method #1 - Easy

The easy method involves completely replacing the existing view with your modified view. This method has the disadvantage that if the default view from the original module is updated, you wouldn't get the updates. (Of course, that might not be a disadvantage to you).

To do this, first export your modified view into a text buffer. Then, in your own module, add an implementation of hook_views_default_views_alter() that looks like this:

/**
 * Implements hook_views_default_views_alter().
 */
function mymodule_views_default_views_alter(&$views) {
  // Alter only the 'view_name_of_interest' view.
  if (array_key_exists('view_name_of_interest', $views)) {
    $view = new view();
    $view->name = 'view_name_of_interest';
    // The rest of the definition from the exported view goes here.
    // ...

    // Override the existing view with this new definition.
    $views['view_name_of_interest'] = $view;
  }
}

After that's all done, enable your module and clear your site caches to make Views recognize your changes. Then go to the Views administration page, and revert your changes to the view. It should now be your changed version.

Method #2 - Hard

The alternative method involves less code, but a greater awareness of how Views works: rather than replacing the entire view definition, the idea is to specify the few parts of the view that are to be changed. This will mean that if the underlying view from the other module changes, you will get the changes. Achieving this is a several-step process:

  1. As before, create a hook_views_default_views_alter() in your module.
  2. For the first version of the hook, use the dpm() function from the Devel module (or you could use print_r()) to output the existing view from the other module:
    /**
     * Implements hook_views_default_views_alter().
     */
    function mymodule_views_default_views_alter(&$views) {
      // Alter only the 'view_name_of_interest' view.
      if (array_key_exists('view_name_of_interest', $views)) {
        dpm($views['view_name_of_interest']);
      }
    }
    
  3. Export the overridden view, and compare this to the dpm() output, to figure out what has changed.
  4. Put the changes into your hook_views_default_views_alter() function. For example:
    /**
     * Implements hook_views_default_views_alter().
     */
    function mymodule_views_default_views_alter(&$views) {
      // Alter only the 'view_name_of_interest' view.
      if (array_key_exists('view_name_of_interest', $views)) {
        // Change the path of the first page display.
        $views['view_name_of_interest']->display['page']->display_options['path'] = 'new_page_path';
    
      }
    }
    

Workaround: cloning a default view

An alternative approach that's feasible in some cases is to substitute the default view with a version you've cloned and modified.

Note however that this approach depends on where and how the default view you're replacing is referenced elsewhere on the site. If it's a view that provides a single page display, replacing it with a clone should work fine, since the page will continue to work at the same path. However, if your view provides for example a block display, cloning the view would require edits to any code or configuration referencing that block.

To replace a view with a cloned version:

  1. Clone the view of interest, giving it a new name and making any changes you wish to make. If you have already overridden the view, you can clone your overridden version then revert the original view.
  2. Export your cloned view to code. You can do so manually or by using the Features module.
  3. Disable the original view. You can do so through the Views UI or in code. To do so in code, use hook_views_default_views_alter() to change the 'enabled' property of the exported view. Or see #1961734-6: Add support for exporting admin views in Features for an alternate approach.

The Media module's library views can be changed by cloning the media_default view in this fashion.

Help improve this page

Page status: No known problems

You can: