context-sensitive embedded views

If you want to embed a view in a node type, it is quite likely that you will want to make it context sensitive.

For example, I have two node types: project and issue. In each Projectnode I want to display a list (view) of the Issues associated with that particular Project. So our ‘context-node’ is a Project and our ‘listed-node’ is an Issue.

The trick here is really the Argument Handling, but first :

We need a way of associating an Issue with a particular Project.

A simple method is to add a CCK Node-Reference field to issue nodes. In the Node-Reference field configuration:

  • label the field Projects,
  • choose the ‘Select List’ widget, and
  • set the ‘Content types that can be referenced:’ to project.
  • Now would be a good time to create a couple of new Issues and associate them with a Project using the Projects select list.

And we need a View to embed.

  • Create a View named issue_view.
  • In the Page fieldgroup: check ‘Provide Page View’, and select ‘List View’.
  • In the Fields fieldgroup: select ‘Node: Title’.
  • In the Arguments fieldgroup: select ‘Node Reference: Projects (field_projects)’ and set it to ‘Display All Values’.

Embedding the View in the context-node.
In order for the Argument to work as a ‘context filter’ it needs to receive an argument from the node in which it appears. How we send this argument depends on the method for embedding the view in the node.

For this example we want every Project to include a list of associatedIssues, and we don’t want users or editors to change this behaviour; so we will hard-wire it into the theme using the node-project.tpl.php. (There are a couple of drawbacks to this method: [1] it only works with PHPtemplate themes and [2] this is custom theming, so if you use more than one theme on your site, you need to create and modify a node-project.tpl.php in each drupal/theme/$yourtheme folder.)

After creating a node-project.tpl.php in our drupal/theme/$ourtheme folder (by renaming a copy of the node.tpl.php), insert the following code chunk wherever we want it to appear:

<?php
// load the context-node’s ‘metadata’
global $current_view;
// * define the context-node’s NID as the argument
$current_view->args[0]=$node->nid;
// * select the name of the view to embed as $view1
$view1 = views_get_view(‘issue_view’);
// * define this section for CSS
print ‘<div class=”issue_view”>’;
// * display a subtitle for the view section
print ‘<h2>’ . t($node->title . ‘ Issues’) . ‘</h2>’;
// send $args to the View’s Argument Handler and display $view1 in the context-node
print (views_build_view(’embed’, $view1, $current_view->args, false,false));
print ‘</div>’;
?>

Tinkering.
Things you might want to change are marked with a *:

  1. * define the context-node’s NID as the $args:
    $current_view->args[0]=$node->nid;
    Usually $node->nid; does the trick, but I found that a ‘relativity module’ parent, for example, required $parent->nid;.
    Other times, depending on the Argument Handler used in the View (?), you may want to pass, say, the node type by using node->type;.

 

  • * select the name of the view to embed as $view1:
    $view1 = views_get_view(‘issue_view’);
    Pretty straight forward. If your View is not named issue_view you need to substitute it here.
  • * define this section for CSS:
    print ‘<div class=”issue_view”>’;
    If your View is not named issue_view and you want intelligible CSS tags, you need to substitute the CSS class here.
  • * display a subtitle for the view section:
    print ‘<h2>’ . t($node->title . ‘Issues’) . ‘</h2>’;
    This will display the context-node’s title …. eg My First Project Issues – as a title atop the list.
    If you don’t like clutter, just comment out the line.
    If you want it to say just Issues, use the line print ‘<h2>’ . t(‘Issues’) . ‘</h2>’;instead.

How to embed multiple views.
Adding additional views to the node page is very easy, as you can see from this modified node-project.tpl.php code which displays a list of relevantIssues and then a list of related How-to nodes as well:

<?php
// load the context-node’s ‘metadata’
global $current_view;
// * define the context-node’s NID as the argument
$current_view->args[0]=$node->nid;    // * select the name of the view to embed as $view1
$view1 = views_get_view(‘issue_view’);
// * define this section for CSS
print ‘<div class=”issue_view”>’;
// * display a subtitle for the view section
print ‘<h2>’ . t($node->title . ‘ Issues’) . ‘</h2>’;
// send $args to the View’s Argument Handler and display $view1 in the context-node
print (views_build_view(’embed’, $view1, $current_view->args, false,false));
print ‘</div>’;// * select the name of the view to embed as $view2
$view2 = views_get_view(‘how-to_view’);
// * define this section for CSS
print ‘<div class=”how-to_view”>’;
// * display a subtitle for the view section
print ‘<h2>’ . t($node->title . ‘ How-to’) . ‘</h2>’;
// send $args to the View’s Argument Handler and display $view2 in the context-node
print (views_build_view(’embed’, $view2, $current_view->args, false,false));
print ‘</div>’;
?> 

 

 

 

css.php