3

how do you use contextual filters to a views block when you want to use a reference field from the content type displaying the view?

here's the simple scenario

  1. artist content type has some basic fields
  2. song content type has a reference field referencing which artist
  3. event content type has a reference field referencing which artist is headlining
  4. view has a block with fields

on each Artist content page, it's working and i have a block of songs for that artist in the sidebar. i used views provide default entity and basic validation (but does not work for below)

on each Event content page, i want a block of songs for that artist in the sidebar. Essentially i want the reference field in the event to match up with the artist's songs.

since we don't have access to the path, i've been playing around with contextual filters on the reference field (and reverse of it) to no avail.


Ok thanks to @Jimajamma I seem to have figured it out, it's actually quite simple.

In order to get the argument into the Song view, you add a 'contextual filter' and select the Song's artist reference field. Then under 'When the filter value is NOT available' choose 'provide default value' and PHP Code. In that PHP code you want to return the value of the Event's artist reference field like so

$node=menu_get_object();
return $node->field_event_artistref['und'][0]['target_id'];

then under 'When the filter value IS available or a default is provided', choose 'Specify validation criteria' and basic validation

In a nutshell, this is simply taking the argument of the artist the Song references and comparing it to the default value you provided which is the current node's artist reference field. also as @Jimajamma said, best practice would be to use a switch statement on the node->type to be able to use the songs by %artist block on several different types of content like artist nodes.

2
  • Glad it's all working out. The way I best wrapped my head around arguments/context filters is to think of them as what they are: the "where" clause of the sql. So, in this example, what you want is to "show me songs by this artist" or "show me songs by the headliner of this concert," or in pseudo sql "select * from songs where artist=foo" so you just figure out what foo is and then you're all set. Oh, and I am by far one of the biggest users of dull axes when it comes to programming, so I have no idea if any of what I say is ever "best practice," but it somehow does work reasonably well :)
    – Jimajamma
    Commented Mar 10, 2012 at 16:51
  • Just a follow up, the 'right way' to do this is to work with entity approach and avoid the ['und'][0] business but I never got it to work in views. i.e. code $node=menu_get_object(); $field = field_get_items('node', $node, 'field_event_artistref'); return field_view_value('node', $node, 'field_name', $field['target_id']); code. Here's a link I was following on the topic computerminds.co.uk/articles/…
    – Will
    Commented Apr 2, 2012 at 21:21

4 Answers 4

6

In the contextual filter, you can use php to supply the argument. There, you could put in something like:

$node=menu_get_object();
return $node->field_headliner[0]['nid'];

where field_headliner is the node reference field of your event content type. The exact syntax above is D6, but I am pretty sure it's the same or at least very similar in D7.

Then, just as long as this view block is being show in/on an event page, the above will return the nid of the headlining band, and if your view is set up to filter on that node nid, you should be set.

You could even get fancy up in there with something like:

$node=menu_get_object();

switch ($node->type) {
  case 'band':
    return $node->nid;
  case 'event':
    return $node->field_headliner[0]['nid'];
  default:
    return 0; // or however you want to return an error
}

and then the same view block display could be used on both types of page. Then just put this block on band and event pages and you should be all set.

3
  • this is helpful. thanks! $node=menu_get_object(); return $node->field_event_artistref['und'][0]['target_id']; so using this for D7, i'm able to get provide a default argument to the Songs view. the trouble now is how can i compare it to the Artist (which is also referenced as a field in the Songs content type.)
    – Will
    Commented Mar 10, 2012 at 15:06
  • in other words i have 1 a Song content type with a reference field to an artist (a node) 2 an Event content type with a reference to an artist. There are multiple songs by each artist. In events featuring an artist, i want songs by that artist in a block. is that relationships and not contextual filters? how do i compare these two reference fields in the Song view if they are equal? and when equal, show the Song fields for that artist Nid? validation on the view is tripping me up! i don't understand what field to use for the contextual filter in the first place and how to filter on Nid.
    – Will
    Commented Mar 10, 2012 at 15:22
  • This is very close to a solution I'm currently looking for. Any chance of updating this to include Drupal 8? Commented Jan 30, 2017 at 18:37
0

You could use this snippet to get the target_id of your field entity reference. It's permits multipes target_id.

$ Node = menu_get_object () // we get the current node
switch ($ node->type) {     // We can manage multiple scenarios with the content type
  case 'type A':            // For the content type A
    $ Related_ids = array ();
    $ Related = field_get_items ('node', $node, 'field_event_artistref') // Get the entity reference field
    if ($related && is_array ($related) && sizeof ($related)> 0) {
      for ($i = 0; $i <count ($related); $i++) {
        $ Related_ids [] = $related [$i]['target_id'];
      }
    }
    return implode ('+', $related_ids) / / It returns the values ​​of the field entity reference

  default:
    return 0 / / default it returns 0
}

http://drupal.org/node/1714188

0

I've created a new sandbox module to solve this exact problem:

https://drupal.org/sandbox/nickurbits/2070451

Allows you to change a contextual filter's default value using a field from the current entity.

0

You can do this without code. Here's how:

  1. Create a block view which lists fields and do a content type filter on "Event"
  2. Add an entity reference to the artist
  3. Add a contextual filter of NID and use the entity reference of the artist as the relationship
  4. Add another entity reference of content that is referencing the song content and use the the artist entity reference as the relationship.
  5. Add a field for the song name (perhaps it's title?) and use the song relationship.

That should do it. Basically you're starting with the Event and building relationships to Artist and then to Song.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.