Before I begin I would like to point out that an enormous help to my understanding of how to do this came from this post on the Drupal Easy website.
This is a demonstration of how to show related nodes on a user profile page. Here is a bit about my specific implementation of this technique.
- I am using Drupal 6, I am going to wager that accomplishing this is going to be a lot less complicated in Drupal 7.
- I am using this technique to show related users on a user profile page.
- User profiles are made using the content profile module.
- The user profile page is a panel page made with Panels 3.
- I am showing 2 lists of other users:
- A list of users with the same selection of a CCK text field, select list, who share the same value as the user being viewed.
- A list of users who have the same selection of a node reference field as the user being viewed.
First, a bit about the user profile. In Drupal 6 I find that most often I prefer using content profile to handle user profiles. The option of using the core profile module does not have the same flexibility and power as using content profile. Content profile creates a node for the user profile of a custom content type. The Content Profile module comes with a custom type when you install it, the type has a machine name of 'profile' and that is the one that I prefer to use. I have added two custom fields to the 'profile' content type that we will be looking at today.
- A CCK text field with a select list widget type that has options for a user to choose a value.
- A Node reference field that allows a user to choose a node to relate their profile to.
Now a bit about the panel page. I do not think this technique changes whether or not you are using a panel to display the page that the view will be shown on. I am using panels to hijak the user profile display. This means that the page which we are working on is a panel and lives at "user/uid". I think that there may be an easier way to handle this in panels, since the central challenge to displaying the lists I would like to display is getting the proper argument to the view. This is the first time I have used panels in over a year and a lot has changed since that time. If there is a better way to accomplish this with Panels 3 please do leave a comment.
So, on to the views. I am going to be using a block display and passing that block an argument. If you are not familiar with arguments in views, think of the argument as a filter that is dynamic and can change based on a set of criteria - often that criteria is coming from the URL using Drupal's args. I want to look at the user profile being viewed, remember that we are viewing a node here of type 'profile' and we are on the url "user/uid", and we want a list of the content profiles that have the same value for a field as the profile that is being
viewed. Firstly we need to find the value of the current user's selection for the field before we can use that value as an argument, aka
filter, on the view. Since all we have in the URL is the uid we will need a little PHP to do the trick. This is a variation of the code found in the post on the Drupal Easy post linked above. To specify an arugment for the field I want to work on, in this case the node reference field, I click on the "Provide default argument" button and enter the following in the "PHP argument code:" text area:
// Get the uid of the user being viewed. $userdid = arg(1); // Pass the uid to the content_profile_load() function to get access to the node id for the profile for that user. $content_profile = content_profile_load('profile', $userdid); // Set up a variable with the nid of the profile for the user being viewed. $content_profile_nid = $content_profile->nid; // Load the profile node for the user being viewed. $node_ref = node_load($content_profile_nid); // Set a varaible with the value of the field we want to pass to the view. $refnid = $node_ref->field_home_court[0]['nid']; // Return the value to the view so we can use it as a filter. return $refnid;
Quite a bit of work to get that value, but now we have the argument we are looking for. There is just one problem and that is that we are
also getting the current node in the view as it meets the criteria of the query we built. We will need to add another argument of "Node:
NID". As before, click on the "Provide default argument" radio button and the "Default argument type:" with the following in the "PHP Code" textarea:
// Get the uid of the user being viewed. $userdid = arg(1); // Pass the uid to the content_profile_load() function to get access to the node id for the profile for that user. $content_profile = content_profile_load('profile', $userdid); // Set up a variable with the nid of the profile for the user being viewed. $content_profile_nid = $content_profile->nid; if($content_profile_nid) { // Return the value of the profile nid to the view so we can use it as a filter.return $content_profile_nid; } return false;
then choose the "Exclude the argument" option at the bottom of the argument settings and update the view and this view is ready to go. I can now place my block in the user profile panel and I get a list of other profile nodes that have the same value in their node reference field.
This turns out to be a difficult thing to explain, so I made a screencast and hopefully that will clear up any questions you may have. Please leave a comment if you have a question or if you have a suggestion about how to accomplish this in a different way.