Check out DrupalEasy around the web:
DrupalEasy is the collective expertise of Ryan Price and Michael Anello, who joined forces to provide training and consulting services worldwide. Read all about them and what they can do.
Drupal is a free, super-powerful content management system for sites that require information posting and collection, including blogs, forums, videos, photos, and databases of information. We think it is the best platform available. Here's why...
More and more savvy organizations are going with Drupal for content management, and its no mystery why. It’s free, flexible, and easy to maintain for small or large volume sites. Learn more...
Today's question comes from Dale at NFi Studios in Orlando, FL - my home town:
Essentially:, what i'm trying to do is
1. Determine the current nodes taxonomy terms
2. Determine all other pages that share taxonomy terms
3. Display the title (and link) to those pages in a blockUsing Drupal 6.2 and Views - Looked at a few modules, but nothing quite
exact - Reviewing some module snippets right now to see if I can
potentially use an argument to do it.
Dale asks a good question: before the release of Panels for Drupal 6, how can one associate a block with the node it's being displayed next to without writing a custom module? It turned out to be simpler than I expected. I actually started going down the path of custom modules, but in the process I noticed that Views still have the ability to load Arguments with PHP Code, and my solution wrote itself.
Dale, you're already pretty far along: you know you need a view inside of a block, displayed based on taxonomy terms to relate the view to the pages. Instead of giving you a full-fledged tutorial on Views and the Black Arts, you'll be getting a recipe that outlines how to create the block in question.
First, you'll want to download and install Views 2 for Drupal 6, currently in Beta 4, then enable the module under admin/build/modules - remember that Views also requires you to activate Views UI, as the views.module is more of an API for creating views.
The first step in your new Views journey is to Add a new view at admin/build/views. Just click on the tab near the top of the screen:![]()
Now you'll be asked to name your view something computer-friendly - in this case you'll name it related_by_term:![]()
Once you click through, you'll be presented with the granddaddy of all administration screens, but don't be afraid, things move pretty quickly in here if you know what you're doing. Notice the Orange text in the top right: New view. Until you push the Save button at the bottom of the screen, all you hard work could be lost, and especially don't forget to save once you've finished configuring your view.
I want you to skip all those fancy options and dive right in: you've got to eat your vegetables, so let's get the hard part over with and set up the arguments:![]()
Arguments were the most powerful (and hardest to understand) feature of the old Views - think of this as the WHERE clause of your SQL statement. Your first and only argument will be keyed off of a Taxonomy Term ID:
Since you don't have Panels at your disposal, you'll need to specify a Default Argument. There are several (powerful) ways to accomplish this, but in your case, resort to tried-and-true PHP Code. The code displayed here loads the object for the current $node (if any) and concatenates a list of all the Term IDs on that node, then returns the string to Views in the format 1+2+3, just like the arguments on taxonomy/term pages:
In order to activate this muitliple-term-driven argument scheme, you need to check a few boxes below the PHP code. The first sets up the fact that you can use the 1+2+3 format, and the second removes duplicate entries that have more than one term. Make sure you read the warnings about performance; if you don't use multiple taxonomy terms, leave this box unchecked. You can proceed by clicking the Update button:
At this point, you'll see an error message inviting you to extract some fields in your view, which is set up to display fields by default. If you wanted to view full nodes or teasers, you could change that option and be safe, but the block you want to build needs titles that link to the node:![]()
Now you want to tackle adding fields to your view. This is the building block of any view, analogous to the SELECT part of a SQL statement:![]()
You should recognize this next picture, because it's very similar to the way you chose your argument type, and how you'll choose your filter in the future. Use the Add button to move to the next screen:
If you don't delete the word "Title" in the Label text box, it will appear next to all your links. There are some situations where this is wanted; yours is not one of them. You also said you wanted the titles to be links, so check that box:
At this stage, you should be able to get a working preview of your view. Just type a number or a 1+2 in the arguments area and push the button to trigger the AJAX. That blue text is your view, and there's also some geeky information below. Notice that currently "This display has no path"; that's OK, you want a block:
At this point, you still haven't told Views that you want your view to be a block, so make sure you choose block from the drop-down in the main interface. If you're working strictly with Page nodes, you may also want to throw a filter on your view to limit the results. You also should never forget the all-important Save button:
The last thing you need to view is activate your block on admin/build/block (you may need to use block visibility rules, but that's another tutorial), and finally visit one of your Taxonomy-tagged pages to see if your other taxonomy-tagged pages shows up. If you've followed all the steps here, everything should be a snap. Maybe the best feature about your new block is the handy links that pop up when you mouse over your new block (if you have administer views access, at least):
Well Dale, I think that should just about answer your question. Since this is my first Drupal 6 tutorial, I'll have to say, this was a lot more fun for me than I'm sure the last few days have been for you. Wave hello to Corey and Sterling and Derek and Daniel and the other NFi folks, and I hope I was able to save you some precious time with this post.
Martijn, There is probably an
Martijn,
There is probably an easier way to do this with a contributed module, or possibly Panels context.
A quick Google search returned:
http://drupal.org/project/related_terms
http://groups.drupal.org/node/10829
http://davidherron.com/content/improving-navigability-drupal-taxonomy-hi...
Leonardo, When setting up an
Leonardo,
When setting up an Argument, there is an area called "Title". Type your text, but instead of "X", put the characters "%1". This is a placeholder for whatever the argument returns. In this case it would be "Other nodes in category Sheep", where you entered %1 in the place of Sheep.
Enter it on this screen, in the Title box.

Thank you very much. Just a
Thank you very much. Just a question: how can I set the title of the block to something related to the view argument? I would like to set it as "Other nodes in category X". I tried to preprocess the block through template.php but I lost myself in the API. Thanks
Hi Great tutorial! How could
Hi Great tutorial!
How could I build a sort of related terms block using this method on taxonomy/term/x page (not on nodes pages) of "foreign" vocabulary?
Logic something like this:
1.Get the x out of the url (url= taxonomy/term/x)
2. Get the terms out of all the nodes shown on taxonomy/term/x page
3. Show the terms from a specific other vocabulary (not the one from the url).
Would this be doable using above method. What would be the phpcode please?
Thanks a lot in advance for your reply!
Greetings,
Martijn
I had a problem using gost_
I had a problem using gost_ "What if you want to show only" comment below for my site. The code worked great expect that the block I was using it for was isolated to a single Content Type. Here is his original code:$node = node_load(arg(1));if ($node) {
$terms = taxonomy_node_get_terms_by_vocabulary($node, 6);
foreach ($terms as $tid => $term) {
$tids[] = $tid;
}
return implode ("+", $tids);
}
return false;
if ($node) {with this:if ($node->type == 'episode')where "episode" is my Content Type. So my entire code looked as follows:$node = node_load(arg(1));if ($node->type == 'episode') {
$terms = taxonomy_node_get_terms_by_vocabulary($node, 3);
foreach ($terms as $tid => $term) {
$tids[] = $tid;
}
return implode ("+", $tids);
}
return false;
Fantastic tutorial and
Fantastic tutorial and comments...what a lifesaver
One nice thing to call out
One nice thing to call out might be the 'Theme: Information' link which tells you which templates the styles will be using, and gives you a full list of names that you can choose from for your own template; and also will show you the default template so you don't even have to go and seek out the original .tpl.php file if you want to look at it.
Hi! The big problem is when
Hi! The big problem is when you have to negate the term ID argument... how could that be possible??????????
I have to echo my thanks.
I have to echo my thanks. The post is almost two years old and yet so valuable!
This is fantastic thanks,
This is fantastic thanks, works a dream.
@sukant The reason why this
@sukant
The reason why this happens is because the paths that get reserved by views allow for arguments to be passed.
A workaround for this is to add an argument to the view in question, and then add some validation. One of the options in validating an argument is to return a 404 / Not Found error.
Hope that helps
you shouldn't run a mile when
you shouldn't run a mile when only ten yards is needed
just one field "title" does it
Thanks!
Thanks!
hi in my site which is
hi
in my site which is created with drupal 6 if i write the url as
www.hellotravel.com/members
it works fine but when i write
www.hellotravel.com/members/dkfjdjfkdjkfjdjfkdjfkdjkfd
it should display page not found error but it reloads the same members page
this bug is happen only with those pages which are created with views so please help someone asap
thanks in advance
Thanks a lot for this step by
Thanks a lot for this step by step guide! How can I change to code to limit this to a specific vocabulary and multiple terms?
Othe steps are clear! Thanks a lot for this guide
James
Great tutorial! If you do
Great tutorial!
If you do this, consider adding a sort criteria for Taxonomy: Term ID descending and put it at the top of your criteria list. That way, newer tags - which are more likely to be *specific* tags - take precedence over more general ones.
For example, I might have an article tagged "Anthrocon" and "conventions". As the "Anthrocon" tag was created later, I get all the stories related to Anthrocon before the ones about other conventions, which is what I want.
@Hilko, You should look at
@Hilko,
You should look at using a special field called a user reference. While this article mostly refers to the node reference field, the concept is the same:
http://drupaleasy.com/blogs/ultimike/2009/07/using-views-relationships-a...
and another:
http://drupaleasy.com/blogs/ultimike/2009/02/displaying-hierarchical-con...
Peace,
Ryan
Great tutorial! I've put it
Great tutorial! I've put it to good use already.
However, I tried to do something similar and failed miserably. Perhaps someone here could help.
I have two content types: 'person' and 'publication'. I want to create a view that shows up on an individual 'person' page, and shows all publications by this person. Both content types contain a field for the first name, one called field_firstname, the other field_pub_firstname. The view should show all the publications where field_pub_firstname == field_firstname (of the current visible single node).
If I add custom php argument code like so:
return 'John';
it correctly shows only the publications by John. However, using what I thought I learned from this page, I tried the following:
return $node->field_firstname[0]['view']
where, in case of John's 'person' page being open, should do the exact same thing.
This doesn't seem to work though. Can anyone tell me why, and what I should do to fix this?
Thank you - I learned
Thank you - I learned something important from this post!
Wish I would have seen this
Wish I would have seen this yesterday ;)
Before I found this, I created a similar one using the views group by module where it shows the number of terms in common. The views export is here:
http://kristen.org/content/use-drupal-views-group-module-show-closest-ma...
Also, some less views-savvy folks may want to check out the featured content module for easily creating lots of different kinds of featured and related content blocks including sorting by closest match by terms.
http://drupal.org/project/featured_content
Cheers,
Kristen
@TR_Master thanks for your
@TR_Master thanks for your comment. However, this tutorial is simply meant as an example. There are some great modules out there to handle similar situations. Read some of the earlier comments, which refer to numerous solutions.
Pingback
[...] Using Views 2 and Drupal 6 to Create a Related Pages Block | DrupalEasy nice args code [...]
Great tutorial, it worked
Great tutorial, it worked perfectly.
Any chance of getting the sort by count(common tags) working ..?
The sort order should be:
1 - Drupal, CSS, HTML
2 - CSS, HTML
3 - Drupal
Thanks.
Thank you Ryan! And, thanks
Thank you Ryan! And, thanks to all the commenters who posted with fixes/updates/adjustments/additional use cases to consider. Stuff like this is why I love Drupal. :)
Great stuff, i just got
Great stuff, i just got related pages working by follow your great guide.
Thanks :-)
Or you could use the Related
Or you could use the Related Links Module and be done with it. Using Views is a very advanced concept for geeks not everyday users.
Great Post. I have
Great Post. I have implemented a view that displays a picture in a block based on the taxonomy of the page with this. However I have a page that is generated by a view. How can I give the page from a view a taxonomy so that my block view can pick it up to display a page?
Good article but still lacks
Good article but still lacks the sorting mechanism. There is no way to dictate that the nodes with highest number of matches should come first.
Use of PHP inside views is
<?php$nid = str_replace('node/','',$_GET['q']);
if (!is_numeric($nid)) return; // i only work for nodes
$ns = db_query('select distinct nid,title from {node} n inner join {term_node} tn using (nid) where nid<> %d and tid in (select tid from {term_node} where nid=%d))',$nid,$nid);
$out = array();
while ($n=db_fetch_object($ns)) {
$out[] = l($n->title,'node/'.$n->nid);
}
echo theme('item_list',$out);
?>
Great tutorial! I'd also like
Great tutorial!
I'd also like to add that this will display the current node in the list... in order to exclude it you would need to add a second Node: Nid argument with the following PHP code:
$node = node_load(arg(1));
if($node){
return $node->nid;
} else {
return null;
}
And select the "Exclude the Argument" box.
Excellent post, as someone
Excellent post, as someone who has next to no PHP knowledge, this post just saved me a lot of time. Thank You.
Thanks for such a good
Thanks for such a good article. I need some help here.
I have two content types.
1. Staff Profile.
2. Staff Video.
Now when one user create staff video content, he also select a staff profile in the Node reference field in Staff Video Content Type.
Now I want to make a view and embed it's link in the Staff Profile content type. SO that whenever any user views any Staff Profile content and click on the Views Link, he should be able to view only that Staff Video where the same name of the Staff profile node was selected. I hope that the picture is clear.
Kindly help me in this regard how am I going to make such a view.
Thanks and regards
I dig this method for making
I dig this method for making a related content block via Views - it works, except I've found that when I have the term in related nodes actually displayed as a field in my view powering this block only 1 term will display - the term field renders empty for any nodes tagged with different terms which the live node shares.
Odd.
q./
Any way to sort by the number
Any way to sort by the number of commun terms ? showing the nodes that have more commun terms first ?
found that if use multiple
found that if use multiple vocabs to node, this trick pulls all of term.
to restrict turned this
foreach($node->taxonomy as $term){$terms[]=$term->tid;}
into this
foreach($node->taxonomy as $term){if ($term->vid=="4"){$terms[]=$term->tid;}}
-----------------------------------------------------------
ps
here we put number of our vocabulary, in my case 4
if ($term->vid=="4")
For anyone wanting to do a
For anyone wanting to do a similar thing but with node reference rather than taxonomy, you'd create the argument using content: the node reference field (rather than term id), and then use this code:
$node = node_load(arg(1));
if($node) {
$refnid = $node->node_ref_fieldname[0]['nid'];
return $refnid;
}
return false;
First, thank you so much for
First, thank you so much for this. It is of great help :D
Hoping that this is still alive, I would like to ask the following:
Having 4 vocabularies assigned to the node, how can i display relevant nodes that much terms for all 4 vocabularies?
In other words:
Right now, this works like an OR statement. Even if it finds a match for one of the four vocabularies, it will display a node as relevant.
Would it be possible to display relevant nodes with an AND? So that relevant nodes should have one common term from all four vocabularies?
Thanks :D
Hi, There is one more thing
Hi,
There is one more thing to do with your 'related' view, please:
sorting by numer of common terms. This will make this view more useful in hardly tagged sites.
Thx,
Szy.
Almost the PHP code I was
Almost the PHP code I was looking for, would it be possible to wish for a similar snipet for "Taxonomy: Term" instead of "Taxonomy: Term ID" ? :-P
Thank you, Ryan! The solution
Thank you, Ryan!
The solution to this scenario was puzzling me the last couple of days, building a relatively simple Drupal based site. Couldn't figure out how to do it myself, but now got it working perfectly with your solution. It was the last pending piece of functionality, so I'm really glad someone at drupal.org forums pointed me to this post!
Thanks a great deal for contributing this!
Views has now moved on
Views has now moved on 6.x-2.6, and unfortunately is quite a bit different to the screen dumps in this article - in particular the arguments screen - any chance of an update?
Thanks for posting this
Thanks for posting this tutorial. I suffered the same errors as a few others (incorrect entry of the code) but after a quick browse through the comments and your replies amendments were fast, easy and effective.
The resulting functionality is excellent! kudos to you.
one of the few decent drupal
one of the few decent drupal tutorials that's both easy to follow and does what it says on the box. THANKS
This is a crucial piece of
This is a crucial piece of functionality, it's amazing that this isn't rolled into stock Views. Thanks for taking the time to publish the snippet!
Pretty good tutorial, I
Pretty good tutorial, I actually understood it (still being a drupal noob). Still have a lot to learn about Drupal...the platform just rocks.
Wexy, You may need to include
Wexy,
You may need to include the Comments as a Views Relationship, but I don't think so.
First, try creating a new View with just node title and comment count and see what happens.
For some reason when I add
For some reason when I add "Node: Comment count" as a field I get no results at all, when I remove it I get the normal results. Node: Teaser and Node Statistics: View count work normaly it just bugs when I wanna print out number of comments for the node.
Any ideas? Pretty much tried everything :/
* the problem turned out to
* the problem turned out to be a typo... I though I had checked - my apologies
* On your suggestion I tried similar_terms which also lead me to relevant_content. Both of these are much easier to configure, but don't give the layout options that your views solution does. For instance, I have a lot of node titles that are going to relate (perhaps over a hundred) and I can use views to lay them out in a grid within the block.
* Is there a reason to avoid using this as a permanent solution, having regard to the layout issue? I'm obviously fairly new to Drupal.
David, Please double-check
David,
Please double-check the code you have entered in the default arguments box. This could make or break the block.
Also, this article is simply meant as a tutorial -> in the real world, you may want to use a module like http://drupal.org/project/similarterms
I must have missed something
I must have missed something important. I can get the view to work up to the point that if i click the preview I get the expected result.
I can't see how I am supposed to trigger that view to display?
If i activate the block at admin/blocks/ I get this php errors:
warning: implode() [function.implode]: Bad arguments. in /var/www/html/drupal/sites/all/modules/views/plugins/views_plugin_argument_default_php.inc(48) : eval()'d code on line 4.
I've tried the patch suggested above but it didn't help.
IfI cliick on any node that contains a taxonomy term I get:
Fatal error: Cannot use object of type stdClass as array in /var/www/html/drupal/sites/all/modules/views/plugins/views_plugin_argument_default_php.inc(48) : eval()'d code on line 3
This is on a test site, but it's exactly the sort of thing that I need to do in production.
Any help appreciated.
Add your comment