By jefgodesky on
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
Could you be more specific?
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.
Stuck at the beginning
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.
Focusing on the block for the moment
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?
Does this require a module?
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?
_
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.
Using relationships in "the other direction"
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?
D6 solution
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.
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.
I got the block working
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."
Thank you this helped me
Thank you this helped me as well.
Works on D7
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!
thank you!
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!
Not a real solution, but...
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).
I'm shooting blind here,
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.
Video tutorial available for child-->parent
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.
I also needed to target
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).