I'm running Drupal 7, with Views 3 and References. I have a content type called "Session," and another called "Session Time." The Session Time content type has a node reference field, which points to a node from the Session content type.

I'd like to set up two views:

  • a block view that shows on any Session node, listing all of the Session Time nodes that point to it, and
  • a page view that lists all of the Session nodes that do not yet have any Session Time nodes associated with them

I've had some difficulty figuring out how to set these up, though. Any advice? Thanks!

Comments

gooney0’s picture

Could you be more specific? I'm not sure where you're stuck.

If your nodes have been created I'd start working on one of the views. You can then post a more specific issue with views.

I imagine we have quite a few Views experts here. I bet someone can chime in.

jefgodesky’s picture

It's the very beginning I'm stuck at. I can set up a View that will list all of my Sessions, or all of my Session Times, but given one, I don't know how to get a listing of the others related to it.

jefgodesky’s picture

I want to create a block that will show on any page that displays a Session node. I want it to list all the Session Time nodes that reference it.

I managed to get a Page View working for this (it looks like I must have made some mistakes with the validation criteria on the conditional filter before). My contextual filter is field_session, the node reference field used by the Session Time nodes to refer to a Session node. Works fine for a Page.

When I make it a block, it works in Preview when I supply the ID of a Session node for the filter. But when I set up the block, nothing appears on the Session page. I've cleared my caches and refreshed the page a few times to eliminate the obvious. Is there something I need to change somewhere, so that the block can take the NID of the current node, and pass it as the contextual filter for the View?

jefgodesky’s picture

I just saw the Nodereference filters module, which purports to do what I'm hoping to accomplish with the Page View: list all of the Session nodes which do not have a Session Time referring to them.

I'd rather not use another module just to do this, and the Nodereference filters module in particular doesn't look like it's very well supported. Is it true that there's no way to do this without a module?

WorldFallz’s picture

No need to create a duplicate thread-- you should be able to edit this post, bump it, or move as you like. If not you can always ask in the webmasters queue. I've deleted the dupe, thanks.

As for your question, blocks have no innate knowledge of arguments-- you need to use the 'provide default view' option with 'content id from url'.

As for using fields from referenced nodes, you would use a relationship for that. See http://drewish.com/content/2008/12/howto_views_2_relationships and http://gotdrupal.com/videos/drupal-views-relationships for good info on how relationships work.

jefgodesky’s picture

Thanks, worldfallz. That helps a lot. Though, all the examples given, and in the videos you link to, have the parent node with a field that refers to the children node. This strikes me as a bit messy. I'd rather have a field on the child nodes that refer to the parent node. Is there a way to set up the relationship so that the parent node can find all of the child nodes that refer to it? Or do I need to set up the reference fields in the other direction?

makro’s picture

I have just done something similar, although with Views 6.x-2.x and views_attach module, not block display. I'm not ready for D7 yet, but I would think that the fundamentals of Views haven't changed. You'll have to figure out how to get the block working yourself, but here's how to get reverse references working.

  1. Create a new view, add the relevant relationship.
  2. Add an argument Node: NID, and set default argument to get nid from URL. Set the argument to use the relationship from 1.
  3. Add the fields you want to display from the referencing nodes. These must not use the relationship, it is handled by the argument.
  4. Add a filter for Node Type: (type of the node that is referenced). Set the filter to use the relationship from 1.
  5. Add other filters as you like.

I am not entirely sure if 4 is needed, I have it, and it works.

You can now pass a nid as an argument, and the view will display all nodes that reference it in the chosen reference field.

jefgodesky’s picture

Thanks, Magnus! Your post got me pointed in the right direction, and I got the block working. It turned out to be easier than I was making it. All I had to do was create a contextual filter for the node reference field, then use "Provide default value" and "Content ID from URL."

melissa.evans’s picture

Thank you this helped me as well.

Elehas’s picture

Oh. My. God.

This took me forever to accomplish. It's rather simple logic too. Thank you makro for your suggestion on #2. I didn't select the delta 1 and as soon as I changed it it worked. No idea how that makes a difference but it works now. Thank you!

Anonymous’s picture

Great solution makro... thanks for sharing it. I got it working in D7 by doing the following:
re: #2 - Contextual filter (obviously)
re: #3 - I had to set the fields to USE the relationship - otherwise it grabbed the title from the node being viewed - not the related node
re: #4 - same

This saved me many hours :)

Thank you!

jefgodesky’s picture

This isn't much of a solution, per se, but it achieves what I need right now. I used the Flag module to create a global flag for Session nodes called "topic submission." Then, I used the Rules module to set up two rules. The first rule flags any new Session node with the "topic submission" flag. The second rule removes that flag on the Session node whenever someone creates a Session Time node. That way, I can use the flag as a filter on the View, so that I just get the Sessions that don't have Times yet.

I'd rather have some way of doing this entirely in Views, but I don't know how to do that yet (or even if it's possible).

makro’s picture

I'm shooting blind here, since my dev environment is offline, and I'm still at the basics regarding references and relationships.

Have you tried adding a filter on the reference field: Is empty, and using the relationship on that filter? Or something similar to that?

Edit: No, of course that won't work. Still mixing which node is referencing and which is referenced. I'll just blame 3:45 AM.

fkrogstad’s picture

After struggling with the same issue in creating a view to show a list of all child nodes that refer to the parent, I found a different NodeOne tutorial that does exactly this: http://nodeone.se/sv/node/742. Mr. Falk explains that you can use relationships to go in one direction and contextual filters to go in the other.

drshearer’s picture

I also needed to target blocks (of one content type) to views page displays (of another content type). Here's a solution that worked for me.

1) Add a text (list) field to your block’s content type. Set the labels to something that will indicate to your user which page display you’re referencing, and set the keys to be ONLY THE LAST SEGMENT of the path for each page display (e.g. if your URL is /about/staff/bios, the key should simply be “bios”).

2) When you set up the block display in views, you don’t need a relationship. Simply add a contextual filter for the field you created in step #1 and provide a default value = “Raw value from URL.” Set the path component to the segment you’re using for your page displays (e.g. if your URL is /about/staff/bios, the component would be 3). If you have page displays using different path components, you will need to create clones of each block and set different component values for each of them.

3) Don’t forget to enable the blocks you create (i.e. put them in a region in your block admin page).