Altering Default Views in Code

Recently I had to modify a View shipped with another module. Specifically I had to tailor the Workbench Moderation view to contain additional column(s). Workbench Moderation supplies its own set of Views in the file  workbench_moderation/views/workbench_moderation.views.inc and therefore these Views are not exportable via regular Features as they are owned by a module already (you may be able to use features_override but I haven’t tried — I’m trying to keep the site dependencies rather lean).

This work was to be completed on a development server and pushed into production via a code update.

Modules that wish to define their own (default) Views do so by implementing hook_views_default_views(). For workbench_moderation their implementation of hook_views_default_views() can be seen in their Drupal.org repository workbench.module file.

In version 1.3 of workbench_moderation it looks as follows, it’s merely loading a View that has been exported to a file.

/**
 * Implements hook_views_default_views().
 */
function workbench_moderation_views_default_views() {
  $module = 'workbench_moderation';
  $directory = 'views';
  $extension = 'view.inc';
  $name = 'view';

  // From workbench_load_all_exports().
  $return = array();
  // Find all the files in the directory with the correct extension.
  $files = file_scan_directory(drupal_get_path('module', $module) . "/$directory", "/.$extension/");
  foreach ($files as $path => $file) {
    require $path;
    if (isset($$name)) {
      $return[$$name->name] = $$name;
    }
  }

  return $return;
}

In order to not destroy this code, and be safe(r) to upgrade our modules we want to override the default view, which looks as follows, to include a new custom column:

Default Workbench Moderation view

Default Workbench Moderation view

We do this by implementing our own hook_views_default_views_alter() in a custom module. We have 2 choices:

  1. Completely override the view by simply exporting the full view plus our changes into this code.

  2. Figure out the changes needed to the view and apply only those changes.

Option 1 is easier, but not as safe for module upgrades. Option 2 is harder but is the recommended approach. To find the differences I typically diff the Default view (exported in the workbench_moderation module) and my own exported View to a file — and i Diff them with Meld.

My implementation in code looks like:

/**
 * Implementation of hook_views_default_views_alter().
 */
function mymodule_views_default_views_alter(&$views) {
  if (array_key_exists('workbench_moderation', $views)) {
    $view = $views['workbench_moderation'];
    $handler = $view->display['default']->handler;

    $fields_to_add = array('field_country', 'field_story_country', 'workbench_moderation_history_link', 'name_1','field_survey_country');

    foreach ($fields_to_add as $field_name) {
      $handler->display->display_options['style_options']['columns'][$field_name] = $field_name;
    }

    $handler->display->display_options['style_options']['info']['field_country'] = array(
      'sortable' => 0,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
    );

    $handler->display->display_options['style_options']['info']['field_story_country'] = array(
      'sortable' => 0,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
    );

    $handler->display->display_options['style_options']['info']['workbench_moderation_history_link'] = array(
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
    );

    $handler->display->display_options['style_options']['info']['name_1'] = array(
      'sortable' => 0,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
    );

    $handler->display->display_options['style_options']['info']['field_survey_country'] = array(
      'sortable' => 1,
      'default_sort_order' => 'asc',
      'align' => '',
      'separator' => '',
      'empty_column' => 0,
    );

    /* Relationship: Content: Author */
    $handler->display->display_options['relationships']['uid_1']['id'] = 'uid_1';
    $handler->display->display_options['relationships']['uid_1']['table'] = 'node';
    $handler->display->display_options['relationships']['uid_1']['field'] = 'uid';
    $handler->display->display_options['relationships']['uid_1']['relationship'] = 'nid';
    $handler->display->display_options['relationships']['uid_1']['label'] = 'Original Author';
    /* Field: Content: StudentStory (Country) */
    $handler->display->display_options['fields']['field_story_country_1']['id'] = 'field_story_country_1';
    $handler->display->display_options['fields']['field_story_country_1']['table'] = 'field_data_field_story_country';
    $handler->display->display_options['fields']['field_story_country_1']['field'] = 'field_story_country';
    $handler->display->display_options['fields']['field_story_country_1']['relationship'] = 'nid';
    $handler->display->display_options['fields']['field_story_country_1']['ui_name'] = 'Content: StudentStory (Country)';
    $handler->display->display_options['fields']['field_story_country_1']['label'] = '';
    $handler->display->display_options['fields']['field_story_country_1']['exclude'] = TRUE;
    $handler->display->display_options['fields']['field_story_country_1']['element_label_colon'] = FALSE;
    $handler->display->display_options['fields']['field_story_country_1']['type'] = 'taxonomy_term_reference_plain';
    /* Field: Content: AlumNote (Country) */
    $handler->display->display_options['fields']['field_country']['id'] = 'field_country';
    $handler->display->display_options['fields']['field_country']['table'] = 'field_data_field_country';
    $handler->display->display_options['fields']['field_country']['field'] = 'field_country';
    $handler->display->display_options['fields']['field_country']['relationship'] = 'nid';
    $handler->display->display_options['fields']['field_country']['ui_name'] = 'Content: AlumNote (Country)';
    $handler->display->display_options['fields']['field_country']['label'] = '';
    $handler->display->display_options['fields']['field_country']['exclude'] = TRUE;
    $handler->display->display_options['fields']['field_country']['element_label_colon'] = FALSE;
    $handler->display->display_options['fields']['field_country']['type'] = 'taxonomy_term_reference_plain';

    /* Field: User: Name */
    $handler->display->display_options['fields']['name_1']['id'] = 'name_1';
    $handler->display->display_options['fields']['name_1']['table'] = 'users';
    $handler->display->display_options['fields']['name_1']['field'] = 'name';
    $handler->display->display_options['fields']['name_1']['relationship'] = 'uid_1';
    $handler->display->display_options['fields']['name_1']['label'] = 'Ucsb Student';

    /* Field: Content: Country */
    $handler->display->display_options['fields']['field_survey_country']['id'] = 'field_survey_country';
    $handler->display->display_options['fields']['field_survey_country']['table'] = 'field_data_field_survey_country';
    $handler->display->display_options['fields']['field_survey_country']['field'] = 'field_survey_country';
    $handler->display->display_options['fields']['field_survey_country']['relationship'] = 'nid';
    $handler->display->display_options['fields']['field_survey_country']['alter']['text'] = '11 [field_story_country_1] 22 [field_country] 33 [field_survey_country]';
    $handler->display->display_options['fields']['field_survey_country']['type'] = 'taxonomy_term_reference_plain';

    $fields_that_should_have_empty_value = array(
    'nid','log','state','moderation_actions','title','type','name','changed',);

    foreach ($handler->display->display_options['style_options']['info'] as
        $name => $value) {
      if (in_array($name, $fields_that_should_have_empty_value)) {
        $handler->display->display_options['style_options']['info'][$name]['empty_column'] = 0;
      }
    }
    $views['workbench_moderation'] = $view;
  }
}

This allows my workbench_moderation view to ultimately appears as follows:

Overridden Workbench Moderation View with custom "Country" column.

Overridden Workbench Moderation View with custom “Country” column.

As an aside, this View is showing multiple content types of information. If the special country field is available for the Type of content I include it in the result as 1 column of data. I do this work in hook_views_pre_render():

/*
 * Implements hook_views_pre_render().
 *
 * Country added to the Workbench Moderation listing for Staff use.
 *
 * Added 2 Hidden Fields to the view. They are related to the Node:Content relationship.
 * We examine the resultset and if either Field has a value we substitute it into the
 * field_field_survey_country value as we only want to show 1 Country value on the page.
 * Multiple content types have a country type.
 *
 * I tried to do this without code and just Replacement Patterns, but patterns are applied to
 * Field if that field had a result -- since we have multiple content types sometimes the given
 * field was empty ... but this workaround works because each row is only showing 1 content
 * type.
 */
function mymodule_views_pre_render(&$view) {
  if ($view->name == 'workbench_moderation') {
    #dpm($view);
    for ($i=0,$z=count($view->result); $i<$z; $i++) {
      $r = $view->result[$i];
      // Student Story type Country
      if (count($r->field_field_story_country_1)) {
        $country = $r->field_field_story_country_1[0]['rendered']['#markup'];
        $view->result[$i]->field_field_survey_country = array(array('rendered' => array('#markup' => $country, '#access' => TRUE)));
      }
      // Alumnus Note Type Country
      if (count($r->field_field_country)) {
        $country = $r->field_field_country[0]['rendered']['#markup'];
        $view->result[$i]->field_field_survey_country = array(array('rendered' => array('#markup' => $country, '#access' => TRUE)));
      }
    }
  }
}

I hope you’ve enjoyed this example of overriding another modules views’ safely!

Looking for quality Drupal Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , , , | Posted under Drupal | RSS 2.0

Author Spotlight

David Gurba

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *


3 − 3 =

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>