Relationships and Contextual Filters In Views 3 for Drupal
In Drupal, I’ve encountered a common problem: setting up a view to pull content that relates to the node the view is on at that moment. In this post I’m providing a few quick-reference guides to this Views problem.
Before we start, a few assumptions:
1) The view in question is a block display. Otherwise none of what I’m about to say will make sense, as the “View Is Here” indicator relates to what node the block display is on.
2) Your content has a Node Reference field.
3) In these examples, I describe the referenced node as a “Parent” and the node making the reference a “Child”. (This is an arbitrary distinction since the node reference field could just as easily be called “Child Node,” but this is less likely since “Parent” to “Child” is more frequently one “Parent” yielding many “Children.”)
We’ll cover the following views:
- Pulling fields from the node it’s on
- Pulling fields of a “Parent” node by node reference
- Pulling fields of “Child” nodes by node reference
- Pulling fields of “Sibling” nodes by node reference
View pulling fields from the node it’s on:
Here’s an easy one. You want a view to return information about the node the block display is on.
For example:
Let’s say we have an online grocery store. When a customer is on the product page for Oranges, we’d like a view that shows fields from that particular product. We’d like the fields to appear in the sidebar, and while this wouldn’t normally be done with Views, it’s important to do this first step to build on later.
This looks like:
What’s happened here?
This contextual filter orients the view to the page it’s on. It basically says, “Show content that has [Content: NID] values that match [Content ID from URL].”
[Content ID from URL] is another way of saying “this page’s NID”, so the only result is the current node.
Note that this can be achieved more efficiently with proper templating and modules like CCK Block.
Pulling fields of a “Parent” node by node reference:
Now, let’s say you want to pull fields from the node that the page you’re on is referencing.
For example:
The grocery store has two content types: Product (Oranges), and Food Group (Fruit). He’d like to show information about the Food Group on the Product page.
At the bottom of the Oranges page, the Nutritional Benefits of Fruit are displayed–this is not a field on the Oranges node, but it’s parent, Fruit.
This looks like:
The first step is the same, orient the view to the node you’re on. Then add a relationship to the node reference field.
You will want to use the relationship for any additional fields, otherwise they will be pulling from the node you’re on.
What’s happened here?
Like the last example, the contextual filter says “Show content that has [Content: NID] values that match [Content ID from URL]“, but by using the Relationship, we’re telling the view to look at the referenced node for this information.
Pulling fields of “Child” nodes by node reference:
This time it’s the reverse, instead of pulling information from the node the current node is referencing, we’re pulling from nodes that reference it.
For example:
When you’re on the Fruit page, we want any item that has Fruits selected as its Food Group (node reference) to be displayed.
Now, you might think this would be easily accomplished by creating several displays of the same view, filtering by content type Product, and filter those by a different Food Group content type for each display. That’s the brute force method. For five or six Food Groups it might be fine, but if your example has hundreds of possible referenced nodes, you will have to use a contextual filter.
This looks like:
What’s happened here?
Unlike the previous examples, we’re not choosing NID as the Contextual Filter; we’re choosing the Node Reference field itself. So, this time the contextual filter is saying “Show content that has [Node Reference Field] values that match [Content ID from URL],” i.e. nodes that reference this node.
Pulling fields of “Sibling” nodes by node reference:
At first glance this may seem simple. This is a behavior usually associated with Taxonomy (i.e. “related content”), and there are a lot of built-in solutions for this kind of View when working with taxonomies. What if the relationship is defined by something else, such as in our example, Node Reference? Then you need to build it from scratch.
First, you need to ask, “what is this node referencing?” then “who else references this?”
For example:
Oranges, Banana and Mango all have the Fruit node selected in the Node Reference field. So, we would like Bananas and Mangos to show up in the sidebar when you’re on the Oranges page.
This looks like:
What’s happened here?
The first relationship sends the view through the Node Reference field to the referenced node. Anything that uses this relationship will now point at the referenced node. In other words, the first relationship says “that references X,” and the second, being reversed, says “that is referenced by X”.
We still need to orient the view, this time to the node we are referencing.
All the parts come together to read: “Show content [that is referenced by] content [that references] [Content ID from URL] using the [Node Reference Field]“.
Put these Views tips to work!
These four examples should cover all the basic scenarios of pulling content that relates to the page you’re on. I expect many of you, like myself, will use this post as a quick reference for setting up complicated views in your Drupal development. I hope it gives you a better understanding of Views and make expanding the Advanced tab a little less intimidating.