Create a 'related content' View.

Last modified: April 19, 2009 - 14:58

Let's continue the previous tutorial at Create a view on a node reference field with a more advanced View. First let's define what we already have and what we need.

We have a Songs content type with a node reference field, that references an Artist content type.
What we now want is that when a user enters a Song node, she will see all the other songs that belong to the Artist.

  1. Have the content types set up.
  2. Create a new view 'Related content' displaying the items of type Node.
  3. In Relationships add content:field_reference_song. Set relationship name 'Content reference'.
  4. The first argument that we want to pass is the existing node. This node shouldn't, obviously, appear in the Related content block. In Arguments add Node:nid and Provide default argument >> Node ID from URL. Enable the 'Exclude the argument' checkbox. Note that this argument does not need any relationship.
  5. Now we want to get all the nodes that are referencing the Artist node. In Argument add a second Node:Nid and set the relationship to 'Content reference'. We need to pass the node ID of the Artist node using some PHP (Provide default argument >> PHP code) . Remember to remove the <?php ?> when pasting the code.
    <?php
    // The referencing field name.
    $field_name = 'field_multi_content_reference'; // <--- Change this to your field name.
    if ($node = menu_get_object()) {
     
    // Pass the first node id on the content reference.
     
    return !empty($node->{$field_name}[0]['nid']) ? $node->{$field_name}[0]['nid'] : NULL;
    }
    ?>
  6. Add relationship to the second argument we added.
  7. Setup the View to use Table and add some fields such as the title (i.e. you will see the title of the song), and create a Block view based on this Default view. Note that since we use menu_get_object() you can't check the View in the Live preview - you will need to check it on the real node view.
  8. In the blocks admin enable the block and navigate to a song node, and enjoy your new Related content block.

Here's an export of a View you can import:

$view = new view;
$view->name = 'gizra_multi_content_reference';
$view->description = 'Get all the content referenced through the content reference field';
$view->tag = 'gizra';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('relationships', array(
  'field_multi_content_reference_nid' => array(
    'label' => 'Content reference',
    'required' => 1,
    'delta' => '-1',
    'id' => 'field_multi_content_reference_nid',
    'table' => 'node_data_field_multi_content_reference',
    'field' => 'field_multi_content_reference_nid',
    'relationship' => 'none',
  ),
));
$handler->override_option('fields', array(
  'title' => array(
    'label' => 'Title',
    'link_to_node' => 1,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
    'relationship' => 'none',
  ),
));
$handler->override_option('sorts', array(
  'title' => array(
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
  ),
));
$handler->override_option('arguments', array(
  'nid' => array(
    'default_action' => 'not found',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'default_argument_type' => 'php',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 0,
    'id' => 'nid',
    'table' => 'node',
    'field' => 'nid',
    'relationship' => 'field_multi_content_reference_nid',
    'default_options_div_prefix' => '',
    'default_argument_user' => 0,
    'default_argument_fixed' => '',
    'default_argument_php' => '',
    'validate_argument_node_type' => array(
      'product' => 0,
      'book' => 0,
      'cluster' => 0,
      'grading_rule' => 0,
      'group' => 0,
      'image' => 0,
      'marker' => 0,
      'page' => 0,
      'spec' => 0,
      'story' => 0,
      'style' => 0,
      'task' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '3' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_is_member' => 0,
    'validate_argument_php' => 'dpm ($handler->argument);
                                          if ($node = menu_get_object() && $node->type == \'style) {
                                            $handler->argument = $node->nid;
                                          }',
  ),
  'type' => array(
    'default_action' => 'ignore',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'default_argument_type' => 'fixed',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'id' => 'type',
    'table' => 'node',
    'field' => 'type',
    'relationship' => 'none',
    'default_options_div_prefix' => '',
    'default_argument_user' => 0,
    'default_argument_fixed' => '',
    'default_argument_php' => '',
    'validate_argument_node_type' => array(
      'product' => 0,
      'book' => 0,
      'cluster' => 0,
      'grading_rule' => 0,
      'group' => 0,
      'image' => 0,
      'marker' => 0,
      'page' => 0,
      'spec' => 0,
      'story' => 0,
      'style' => 0,
      'task' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '3' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_is_member' => 0,
    'validate_argument_php' => '',
    'override' => array(
      'button' => 'Override',
    ),
  ),
));
$handler->override_option('filters', array(
  'status' => array(
    'operator' => '=',
    'value' => 1,
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'status',
    'table' => 'node',
    'field' => 'status',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
  'role' => array(),
  'perm' => '',
));
$handler->override_option('header', '<?php
       
if ($node = menu_get_object()){
         
// The referencing field name.
         
$field_name = field_multi_content_reference;
         
$ref_node = node_load($node->{$field_name}[0][nid]);
          print
strtr(Other content referencing <a href="@node-ref">@ref</a>., array(@node-ref => url(node/. $ref_node->nid), @ref => check_plain($ref_node->title)));
        }
       
?>
');
$handler->override_option('header_format', '4');
$handler->override_option('header_empty', 0);
$handler->override_option('items_per_page', 0);
$handler->override_option('style_options', NULL);
$handler = $view->new_display('block', 'Related content block', 'block_2');
$handler->override_option('relationships', array(
  'field_multi_content_reference_nid' => array(
    'label' => 'Content reference',
    'required' => 0,
    'delta' => '-1',
    'id' => 'field_multi_content_reference_nid',
    'table' => 'node_data_field_multi_content_reference',
    'field' => 'field_multi_content_reference_nid',
    'relationship' => 'none',
    'override' => array(
      'button' => 'Use default',
    ),
  ),
));
$handler->override_option('fields', array(
  'title' => array(
    'label' => 'Title',
    'link_to_node' => 1,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
    'relationship' => 'none',
    'override' => array(
      'button' => 'Use default',
    ),
  ),
));
$handler->override_option('arguments', array(
  'nid' => array(
    'default_action' => 'default',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'default_argument_type' => 'php',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 1,
    'id' => 'nid',
    'table' => 'node',
    'field' => 'nid',
    'override' => array(
      'button' => 'Use default',
    ),
    'relationship' => 'none',
    'default_options_div_prefix' => '',
    'default_argument_user' => 0,
    'default_argument_fixed' => '',
    'default_argument_php' => '// Pass the argument only if we are on node view page.
                      $item = menu_get_item();
                      return $item[\'path\'] == \'node/%\' ? $item[\'page_arguments\'][0]->nid : NULL;',
    'validate_argument_node_type' => array(
      'product' => 0,
      'forum' => 0,
      'book' => 0,
      'cluster' => 0,
      'grading_rule' => 0,
      'group' => 0,
      'image' => 0,
      'marker' => 0,
      'page' => 0,
      'spec' => 0,
      'story' => 0,
      'style' => 0,
      'task' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '13' => 0,
      '23' => 0,
      '21' => 0,
      '24' => 0,
      '29' => 0,
      '32' => 0,
      '34' => 0,
      '11' => 0,
      '8' => 0,
      '19' => 0,
      '30' => 0,
      '35' => 0,
      '22' => 0,
      '4' => 0,
      '5' => 0,
      '7' => 0,
      '10' => 0,
      '12' => 0,
      '17' => 0,
      '18' => 0,
      '9' => 0,
      '14' => 0,
      '20' => 0,
      '25' => 0,
      '31' => 0,
      '33' => 0,
      '36' => 0,
      '27' => 0,
      '37' => 0,
      '26' => 0,
      '28' => 0,
      '16' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_is_member' => 0,
    'validate_argument_php' => '',
  ),
  'nid_1' => array(
    'default_action' => 'default',
    'style_plugin' => 'default_summary',
    'style_options' => array(),
    'wildcard' => 'all',
    'wildcard_substitution' => 'All',
    'title' => '',
    'default_argument_type' => 'php',
    'default_argument' => '',
    'validate_type' => 'none',
    'validate_fail' => 'not found',
    'break_phrase' => 0,
    'not' => 0,
    'id' => 'nid_1',
    'table' => 'node',
    'field' => 'nid',
    'override' => array(
      'button' => 'Use default',
    ),
    'relationship' => 'field_multi_content_reference_nid',
    'default_options_div_prefix' => '',
    'default_argument_user' => 0,
    'default_argument_fixed' => '',
    'default_argument_php' => '// The referencing field name.
                            $field_name = \'field_multi_content_reference\';
                            if ($node = menu_get_object()) {
                              // Pass the first node id on the content reference.
                              return !empty($node->{$field_name}[0][\'nid\']) ? $node->{$field_name}[0][\'nid\'] : NULL;
                            }',
    'validate_argument_node_type' => array(
      'product' => 0,
      'forum' => 0,
      'book' => 0,
      'cluster' => 0,
      'grading_rule' => 0,
      'group' => 0,
      'image' => 0,
      'marker' => 0,
      'page' => 0,
      'spec' => 0,
      'story' => 0,
      'style' => 0,
      'task' => 0,
    ),
    'validate_argument_node_access' => 0,
    'validate_argument_nid_type' => 'nid',
    'validate_argument_vocabulary' => array(
      '13' => 0,
      '23' => 0,
      '21' => 0,
      '24' => 0,
      '11' => 0,
      '8' => 0,
      '16' => 0,
      '19' => 0,
      '27' => 0,
      '22' => 0,
      '4' => 0,
      '5' => 0,
      '7' => 0,
      '10' => 0,
      '12' => 0,
      '15' => 0,
      '17' => 0,
      '18' => 0,
      '9' => 0,
      '14' => 0,
      '20' => 0,
      '25' => 0,
      '26' => 0,
    ),
    'validate_argument_type' => 'tid',
    'validate_argument_is_member' => 0,
    'validate_argument_php' => '',
  ),
));
$handler->override_option('title', 'Related content');
$handler->override_option('style_plugin', 'table');
$handler->override_option('style_options', array(
  'grouping' => '',
  'override' => 1,
  'sticky' => 1,
  'order' => 'asc',
  'columns' => array(
    'field_icon_image_fid' => 'field_icon_image_fid',
    'title' => 'title',
    'type' => 'type',
  ),
  'info' => array(
    'field_icon_image_fid' => array(
      'separator' => '',
    ),
    'title' => array(
      'sortable' => 1,
      'separator' => '',
    ),
    'type' => array(
      'sortable' => 1,
      'separator' => '',
    ),
  ),
  'default' => 'title',
));
$handler->override_option('block_description', 'Related content');
$handler->override_option('block_caching', -1);

Thanks for this great

hades666evil - November 6, 2009 - 15:36

Thanks for this great tutorial !
I've modified a little bit the PHP argument code like this :

<?php
$field_name
= 'field_multi_content_reference'; // <--- Change this to your field name.
if ($node = node_load($view->args[0])) {
 
$refs = "";
  foreach(
$node->{$field_name} as $ref){
    if(!empty(
$ref['nid'])){
       
$refs .= $ref['nid'].",";
    }
  }
  if(
$refs != ""){
    return
substr($refs,0,-1);
  }
  else{
    return
NULL;
  }
}
?>

I've changed the method to retreive the node from the first argument. Now you can place the block anywhere, and it works in preview mode.
I also add a loop to look at every references. So, now you also have to check the "Allow multiple terms per argument" box in the argument settings.

 
 

Drupal is a registered trademark of Dries Buytaert.