Using Views Relationships, Arguments, and Attachments

Published July 6, 2009

This article is also available in French from KolossalDrupal.

There's an incredible amount of functionality that can be provided by the Views module, especially when it is combined with intelligent use of Node Reference fields. When you relate your site's nodes with Node Reference fields, these relationships can be easily leveraged to create some very useful views.

I'm going to build a view for a sample music site. In the site, I have 3 related content types for "Band" nodes ("Black Eyed Peas", "Linkin Park", etc...), "Album" nodes ("Back in Black", "Bat Out of Hell", etc...), and "Events" (concerts, television appearances, etc...)

Content Type relationships

Each of these content types has only the minimum fields to demonstrate the Views functionality that is the subject of this article. For example, the "Event" content type doesn't have any location or date fields - they can be easily added at a later time.

To associate the 3 content types, both the "Album" and "Event" content types have a Node Reference field that allow their nodes to point back to a "Band" node. For example, when a new "Album" node is created, the user is forced to select the appropriate "Band".

Album Node Reference Field

In order to make use of these content types, I went ahead and populated several nodes of each type so I have some data to work with when creating the view.

The goal of this article is to be able to create a page that displays a single band node along with all of its albums and events. Here's a quick sample of what I'm aiming for:


Band Info
[Band Name]

Albums
[Album 1]
[Album 2]
[Album 3]

Events
[Event 1]
[Event 2]
[Event 3]

There are several ways to accomplish this - Panels (context) and blocks (visibility) come to mind - but I'm going to use a method that utilizes only Views Attachments. Regardless of the method choosen, it's almost guaranteed that you'd have to create some views so why both with the extra overhead of additional modules and/or code?

A Views Attachment is simply a type of Views Display that gets attached to another View Display (usually a page display or a block display). Simplifying things, it can be thought of like this:

The diagram shows that Page and Block displays (as well as other types of displays defined by other modules) can have any number of attachment displays. These attachment displays can physically appear on the page either before or after the display it is attached to.

For this example, I'm going to create a view that has one Page Display (called "Band Page") and two Attachment Displays (called "Albums Attachment" and "Events Attachments"). The two Attachment Displays will be attached to the bottom of the "Band Page" so we end up with the desired outcome as outlined above.

As usual, you can download all the CCK types and view exports at the end of this article.

For the first step in creating the view, I went to the admin/build/views/add page and created a new node-based View called "band_info" with the following values on the "Defaults" display:

Basic Settings
Title: Band Info
Arguments
Node: Nid ("Action to take if argument is not present: Hide view / Page not found (404)")
Fields
Node: Title
Filter
Published: Yes
Type: Band

Next, I created a new "Page" display and named it "Band Page" and set its path to: "band/%". Remember, the "%" is just a placeholder for the "Node: Nid" argument I set up in the "Defaults" display.

At this point you can save the view and check it out in the "Preview" pane by entering in a valid Node ID for a "Band" node in the argument field. The view should show only the band's name that is associated with the Node ID you provided as the argument.

Now for the interesting stuff. I'm going to create an Attachment display that shows all of the Album nodes for the Band specified by the Node ID in the argument. Remember, there's nothing all that special about Attachment displays. They're just like any other Views Displays except that you can attach them to other displays. To create the "Albums Attachment", I started by selecting "Attachment" from the display select box and clicking the "Add display" button.

Add an attachment display

Initial setup for the new display is straight-forward:

Basic settings
Name: Albums Attachment
Attachment settings
Position: After
Attach to: Band Page

Since this display is going to show a list of "Album" nodes, I want to set the "Node: Type" to "Album". When doing this, I have to be careful not to change the default settings for the entire View - I want to change the settings just for this attachment. To do so, I click to edit the "Node: Type" in the "Filters" section, then click the "Override" button so that I'm only modifying the current display and not the entire view:

Override the Node: Type setting.

Once the setting is overridden, I can then safely change it to "Album" without worrying that I'm messing up the other displays. It is easy to tell when a setting is overridden: it is no longer displayed in italics in the display summary:

Overridden settings

Here comes the tricky part: now that our display is going to show only Album nodes, how do you filter it by the Band's Node ID? With a "Relationship", of course! Remember, the Band and Album content type are related via a Node Reference field. We can utilize that relationship to filter the Album nodes. The first step is to add a new relationship to the "Albums Attachment". In this case, I'm going to add a "Content: Band" relationship. Before I do this, however, I have to ensure that I'm adding this relationship only to the Albums Attachment, not the entire view. This is a common source for mistakes. Take note of the "Relationships" section - notice how it is italicized? That means anything I add to it is actually getting added to the Defaults display - and all of the displays that inherit from it. I first need to click on the "Relationships" link and click the "Override" button.

Override the relationships

Once this is done, I know that I'm safely adding the relationship to only the "Albums Attachment" display. I'm going to add the relationship that links an "Album" node to a "Band" node - in this case, that is the "Content: Band" Node Reference field.

Select the relationship

After adding the relationship, I'm presented with a couple of settings. The "Label" is used only to help identify the relationship as it appears in this particular view. When adding multiple relationships to a view, it is helpful to give them meaningful names. Luckily, Views does a pretty good job at assigning the default, so I'll stick with that.

Select the relationship

In this case, the "Require this relationship" option is not necessary because I know that the argument will filter out all but those Album nodes I want to see.

The final piece of the puzzle has to do with the "Node: Nid" argument. Since the "Albums Attachment" display is inheriting the argument from the "Band Page" display, I have to make sure that it is using it correctly. As it stands now, the display will try to filter the list of Albums with the incoming Node ID argument. This won't do much of anything since the incoming argument is the Node ID of a Band. I need to tell the view to use the argument to filter the Album nodes returned by the Band - using the Relationship I just set up. Turns out this is pretty easy to do.

First off, I need to click to edit the "Node: Nid" argument and then click the "Override" button so that my changes only affect this display. Then, I need to set the "Relationship" select box to "Band". This will effectively filter the Album nodes returned by their associated Band node's ID.

Albums attachment argument relationship

One final thing I did to the attachment to make it a little more user friendly was to override the "Header" setting and add the following:


Albums

This will simply display a nice header above the albums. Taking a quick look at the Preview pane with the appropriate Node ID for a Band, you'll see something like this:

Band page and album attachment preview

At this point, the "Albums Attachment" is just about done. You can add some additional fields, sorts, and display options, but the challenging part is complete.

The "Events Attachment" works exactly the same way. The main difference is that the "Node: Type" filter uses the "Event" content type, but everything else is analagous to the "Albums Attachment" display.

Putting everything together, the final view looks like this:

Final Band Info page

It's not too hard to imagine how you can utilize these tools to generate all sorts of interesting views of this same data. Perhaps an Album or an Event page that shows information from the associated Band node. Maybe add a new content type for "event location", then you can build a view that displays all events by location along with Band information for each event. The method outlined here is flexible enough to allow you to drill as far down into your data as you need.

Comments

j-o-h-n, you might have to use additional modules to accomplish your goal.

I would recommend having your genre view include the Full or Teaser display of the node, first of all. Secondly, there are lots of modules that can add the output of a view to a node - some as fields, some just get attached, others use even stranger methods.

The key here would be to use Views' caching feature so you're not running 60 new queries on each page load - setting a cache lifetime of an hour or two will retrieve the data once, then save the result so views can recall it without rebuilding the output. The show dates, and particularly album names aren't likely to change that often. You may be able to get away with a cache lifetime of a day or more in this case.

This is THE article I was looking for. Thanks a lot!
It is really strange that until now, this kind of operations is still complicated in Drupal. Almost every website I would ever create will need what is mentioned in the above article. these should be built into the core and made easier to implement! Hopefully once I become an expert, I will contribute.
Anyhow, I tried the above but it did not work as expected. I will not go through details for now, but I have a question:

Is what is mentioned in the article still applicable to today's core and modules
Am using: Drupal 7
References: 7.x-2.x-dev
Eva 7.x-1.x-dev
Views 7.x-3.0-beta3
Views UI 7.x-3.0-beta3
Thanks

Submitted by postscripter (not verified) on Tue, 04/19/2011 - 03:34

The problem for me was that the node display will override the view.
So I had to set all fields in the node display to hidden, and I created a block instead of a page and attached the block to the content type I needed.
Is this the right way to do it?

Submitted by postscripter (not verified) on Tue, 04/26/2011 - 16:44

Amazing post. Views relationship are such a complex topic but explained in really well way. Exactly what I was looking for.

Submitted by Pankaj Kumar Sharma (not verified) on Fri, 04/29/2011 - 08:03

In the main block I have content fields. I attach another block to this block.

Attachment block must show content that is related via node reference field to content in the main block.

The problem of course is that there's no way to pass argument from main block to attachment block. Setting relationship like in your tutorial in the attachment block doesn't help.

What am I doing wrong?

Submitted by Serhiy (not verified) on Thu, 06/09/2011 - 07:46

Thank you. This article help me to better understanding of views attach and relationship.

I also note using Relationship and Node:nid as argument is equivalent to use just Content:field_nodereference as argument... or is there an advantage in use of Relationship?

Thanks a lot for your post. It's really helpful.

The question is whether it's possible to create not a page, but a feed, using relationships. How can I make rss for a band which items are albums and events related to the band?

Thanks in advance

Submitted by Andrew (not verified) on Mon, 08/22/2011 - 12:01

Sign up to receive email notifications of whenever we publish a new blog post or quicktip!

Name
CAPTCHA