Using Views to manipulate connections between content.
This is the first of a set of blogs that could be called quick (and sometimes dirty) solutions to everyday problems. The plan is to provide examples and code snippets from actual projects as they come up. In this first one, I'll look at a couple of examples of how to use views to manipulate node references and relationships; the first example is from Drupal 6 and the second from Drupal 7.
In D6, you can create custom fields using CCK (content construction kit) and one really useful one is the node reference field type that allows you to create links to related content when you are creating a node. This can be used to create a parent-child connection between content nodes; in this project we use it so the client can produce a set of articles on a single topic. This functionality could also be achieved using the book module as that also allows you to string together a set of related nodes, but as we don't need book module's capacity to build a deep hierarchy this is a more user-friendly way of achieving the desired result.
We start with an article content type, which has a field called related_articles. To make for a better user experience we also use the Node Relationships module because it gives a popup modal form for creating new related nodes as well as referencing existing ones. In the image below you can see a set of articles that have either been created or selected as articles that are related to a parent article called 'The Art of Anatomy':
So far so good, but there is a drawback with this approach. When you are in the parent article, you can easily list the related articles, and when you are in a related 'child' article it is easy enough to show a link to the parent because node relationships module makes that available to you. What is more difficult is to show not only the parent article, but also the other related articles when you are in a related/child article. The next image shows what we want to achieve:
In this example we are in one child article called 'The Influence of the Renaissance' and its parent is shown at the top of the list on the right, while its fellow related articles are also shown. This is done using 'reverse node relationships' module and views.
The next image shows the view that lies behind the side menu. The key to being able to show the parent but also the peer related articles is to use the reverse relationship module to create a reverse relationship using the 'related_article' field. The reverse comes because instead of referencing the related nodes from the parent article, which is simply a matter of adding the 'related articles' field in the list of fields, what is happening here is the reverse; we are referencing the parent node from the child and then figuring out what the other related articles are called.
The actual relationship field information is as shown next. The image shows that the reverse relationship is based on the field_article_related, which is the node reference cck field. You can give the relationships a user-friendly name and in this case it's 'Related reverse'. You can see that in the previous image this is used in brackets before each of the two fields, which lets us know that these fields are using the relationship to fetch their data.
Having set up the relationship, the only other thing we need to do to make this work is to use that relationship when adding fields. As you can see in the above image, we add two fields - node title is there so we can reference the parent article and the second field shows the titles of the related articles. One other setting is then needed for the list of related articles so that we see them all. We need to group multiples as shown below:
One last minor point is that the menu block needs to know which node it's appearing beside so it can work out which parent article to reverse reference. This is done using the field node nid as an argument, and then configuring the argument's default settings as shown here. The default is the node id from the URL, which is one of the standard options available for node view arguments:
So now we can take a look at a varation on this for Drupal Seven. In the D7 example the use case is slightly different but is dealing with similar issues. Again the site uses the concept of related nodes so that when you are on a given article you can also see a list of related items. The challenge is going to be that we don't just want the node titles; we also need the node teaser and a thumbnail image. Sadly we don't have the outstanding node relationships module in D7 as yet but at least cck is part of the Drupal core. We do also have to enable the references module to get node references working. With all that done here's a set of related articles using node reference field. As you can see we don't have the nice buttons for opening popup forms but otherwise this is the same as the previous example in D6:
With the content type and field in place for creating relationships between a parent node and its related 'child' nodes we can build a view to show the related nodes, and here's that view in design:
Again we start by adding a relationship to the basic view and again it's using a field called 'related articles'. In this case there is no reverse relationship because we are referencing the related nodes from their parent but we need the relationship because that is used by the related node fields. Here's the modal form with the details of the relationship. As you can see, the relationship references a field called 'field_article_related' and in this case we've not bothered to give it a more friendly name.
Again we are passing an argument to the block of related articles although in Views 3 this is now called a 'contextual filter' rather than an argument. this contextual filter also uses the default value setting to get the nid of the current article. With the relationship and contextual filter in place we can select the fields that are going to be displayed in the related articles block. Here's an example of the related article title field being set up with the important point to notice being that this field uses the 'field_article_related' relationship for getting its data.
And just to round off, here's what gets shown when the parent article page is being viewed:
If you need this type of views functionality but are struggling to make it work, feel free to get in touch and I can export the view code so you can get a working model.