Show block by taxonomy term - Drupal 4.7
Last modified: March 28, 2007 - 23:07
To show a block only for an specific taxonomy term, here is how to do it:
<?php
$myterm = 163; // replace this id with the term id you want to use.
// This will show on all nodes having this term
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$terms = taxonomy_node_get_terms(arg(1));
foreach($terms as $term) {
if ($term->tid == $myterm) return TRUE;
}
}
// This will show on the index page for that term
if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (arg(2) == $myterm)) {
return TRUE;
}
// Otherwise
return FALSE;
?>To do the same for more than one taxonomy term use in_array() instead:
<?php
$myterms = array(8, 9, 12, 21); // list the ids of the terms you want
// This will show on all nodes having this term
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$terms = taxonomy_node_get_terms(arg(1));
foreach($terms as $term) {
if (in_array($term->tid, $myterms)) return TRUE;
}
}
// This will show on the index page for that term
if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (in_array(arg(2), $myterms))) {
return TRUE;
}
// Otherwise
return FALSE;
?>Enjoy!

Show block by taxonomy term - Drupal 6.2
In Dripal 6.2 the parameter to the function
taxonomy_node_get_terms()is not a node ID, but an object.Yestarday was my first day using Drupal and I spent several hours figuring that out.
My solution is based on the code available here: http://api.drupal.org/api/function/taxonomy_node_get_terms_by_vocabulary/6
That function is very simular to the one used above (http://api.drupal.org/api/function/taxonomy_node_get_terms/6) and
I am only using the former in order to be slightly more efficient as I already know both - the term and vocabulary IDs. You can adjust the code below if you do not know the vocabulary ID in your case.
Note, this function is executed during every page load. For efficiency reasons I have copied the SQL statement from
taxonomy_node_get_terms_by_vocabulary()directly into my own code. This often saves traversing thewhileloop too many times, but is bad style and you should not do it if you have enough computing power.By code is:
<?php$tid = 1; // vocabulary term ID for whivh to display the block
$vid = 1; // Vocablulary ID (We ignore all but one vocabularies for speed)
if (arg(0) == 'node' && is_numeric(arg(1))) {
$nid = arg(1);
$r = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $nid);
while ($term = db_fetch_object($r)) {
if ($term->tid == $tid)
return TRUE;
}
}
return FALSE;
?>
Show block by taxonomy term + ancestors - Drupal 6.2
Reg. my previous post (http://drupal.org/node/113651#comment-841679):
In opposite to the examples in the main post it does not show the block on index pages for the term in question - this was intended.
Here is an extended version. It shows a block when the current node belongs to a taxonomy category with the ID
$displayTermIDor any of the sub-categories of that category. For instance if you have a taxonomy like:Windows
- Windows 95
- Windows XP
Linux
- SuSE
- Debian
and you want to display a block on all nodes that belong to all sub-categories of Windows (i.e. "Windows", "Windows 95", "Windows XP") you can use this approach.
$displayTermIDmust be the ID of "Windows".Note, today is my second day of using Drupal, so I apologise if something is wrong, but I think that this version uses the Drupal 6.2 API correctly.
<?php
// Vocabulary term ID for which to display the block:
$displayTermID = 1;
// If current node is not a normal node, then fail-fast:
if (arg(0) != 'node' || !is_numeric(arg(1))) {
// echo "<p>Will return FALSE1.</p>";
return FALSE;
}
// Get all taxonomy terms for current node:
$currNode = new stdClass();
$currNode->vid = arg(1);
$currNodeTerms = taxonomy_node_get_terms($currNode);
// If there are no terms, fail-fast:
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
// echo "<p>Will return FALSE2.</p>";
return FALSE;
}
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
$ancestors = taxonomy_get_parents_all($term->tid);
// Chech for each ancestor term whether is is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid) {
// echo "<p>Will return TRUE.</p>";
return TRUE;
}
}
}
}
// If we didn't find our term of interest, return FALSE:
// echo "<p>Will return FALSE3.</p>";
return FALSE;
?>
works for nodes...
as you indicated, but not on the taxonomy index listing page.
Here is a suggestion on how to get this to show the block on the index page as well:
<?php
// Vocabulary term ID for which to display the block:
$displayTermID = 4;
// This will show on the index page for that term
if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (arg(2) == $displayTermID)) {
return TRUE;
}
// Get all taxonomy terms for current node:
$currNode = new stdClass();
$currNode->vid = arg(1);
$currNodeTerms = taxonomy_node_get_terms($currNode);
// If there are no terms, fail-fast:
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
// echo "<p>Will return FALSE2.</p>";
return FALSE;
}
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
$ancestors = taxonomy_get_parents_all($term->tid);
// Chech for each ancestor term whether is is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid) {
// echo "<p>Will return TRUE.</p>";
return TRUE;
}
}
}
}
// If we didn't find our term of interest, return FALSE:
// echo "<p>Will return FALSE3.</p>";
return FALSE;
?>
doesn't show on all index pages
Can anyone assist in modifying this snippet so that blocks will show on all sub-term index pages, as well as that of the root ancestor?
Also displaying for taxonomy listings
Hi,
not sure what you mean by "so that blocks will show on all sub-term index pages, as well as that of the root ancestor". Your code (I think, I have not tried it) should show the block in the following cases:
- When a node is displayed that has a category term with the ID
$displayTermIDassigned to it.- When a node is displayed that has a category term
Tassigned to it, such thatThas an ancestor term with the ID$displayTermID.- When a category listing for the term with the ID
$displayTermIDis displayed.I think, what you want is to also display the block when a category listing for a term is displayed that has an ancestor with the ID
$displayTermID. I have removed the Drupal 6 installation and replaced it with it with Drupal 5.7 because of the serious lack of modules for Drupal 6 makes is not very useful for me (e.g. see discussion at http://drupal.org/node/259586, but that is unrelated). Because of this I cannot really show you a WORKING Drupal 6 snippet here, but here is what you need to do in general:<?php
/*
Note, I have written this directly into the Drupal forum text box.
I have not tested this code, as I am now using a different Drupal version, so it is likely to contain bugs.
This code is just supposed to give an idea of how to proceded.
*/
// Fetch an array of currently displaying taxonomy terms according to the current display:
if (arg(0) == 'node' && is_numeric(arg(1))) {
// Get all taxonomy terms for current node:
$currNode = new stdClass();
$currNode->vid = arg(1);
$currNodeTerms = taxonomy_node_get_terms($currNode);
} else if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && is_numeric(arg(2)) {
// The current term is the one being listed:
// (note, you need to adjust this if you want to process listings of several category terms)
$currNodeTerms =array();
$term = new stdClass();
$term->tid = arg(2);
$currNodeTerms[] = $term;
} else {
return FALSE;
}
// If there are no terms, fail-fast:
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
return FALSE;
}
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
$ancestors = taxonomy_get_parents_all($term->tid);
// Check for each ancestor term whether is is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid)
return TRUE;
}
}
}
// If we didn't find our term of interest, return FALSE:
return FALSE;
?>
Found a working method (D6)
I tried the code above but it didn't work, the code below should work though.
<?php
// Vocabulary term ID for which to display the block:
$displayTermID = 6;
// This will show on the index page for that term
if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (arg(2) == $displayTermID)) {
return TRUE;
}
$ancestors = taxonomy_get_parents_all(arg(2));
// Check for each ancestor term whether it is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid) {
// echo "<p>Will return TRUE.</p>";
return TRUE;
}
}
}
// Get all taxonomy terms for current node:
$currNode = new stdClass();
$currNode->vid = arg(1);
$currNodeTerms = taxonomy_node_get_terms($currNode);
// If there are no terms, fail-fast:
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
// echo "<p>Will return FALSE2.</p>";
return FALSE;
}
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
$ancestors = taxonomy_get_parents_all($term->tid);
// Check for each ancestor term whether it is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid) {
// echo "<p>Will return TRUE.</p>";
return TRUE;
}
}
}
}
// If we didn't find our term of interest, return FALSE:
// echo "<p>Will return FALSE3.</p>";
return FALSE;
?>
--
How to override HTML in Drupal 6
Here is a TESTED simple method:
Hi, and thank you for the small examples. Unfortunately, they did not work on my install. Here is a version which worked for me:
<?php
if ( arg(0) == 'node' and is_numeric(arg(1)) and arg(2) == FALSE ) {
// Vocabulary term ID for which to display the block:
$displayTermID =1;
// Get all taxonomy terms for current node:
$currNodeTerms = taxonomy_node_get_terms(node_load(arg(1)));
// If there are no terms, fail-fast:
if (is_null($currNodeTerms) || 0 == count($currNodeTerms)) {
return FALSE;
}
// For each term of the current node, get all the ancestor terms:
foreach($currNodeTerms as $term) {
$ancestors = taxonomy_get_parents_all($term->tid);
// Check for each ancestor term whether it is the term we are looking for.
// If it is, return TRUE immediately:
if (!is_null($ancestors) && 0 < count($ancestors)) {
foreach($ancestors as $ancestor) {
if ($displayTermID == $ancestor->tid) {
return TRUE;
}
}
}
}
}
// If we didn't find our term of interest, return FALSE:
return FALSE;
?>
basically, the difference with prior art is:
$currNodeTerms = taxonomy_node_get_terms(node_load(arg(1)));Hi, Is there a working
Hi,
Is there a working version for D6 with arg(2) working within custon php in a delegator panel?
THis because the views path and panels path taxonomy/term/% interfere.
Thanks for your reply!
greetings,
Martijn
More than one TID?
This worked very well for me, but is there a way of doing this with multiple TIDs?
See also
See also:
Block Visibility by Book
Does anyone have any code snippets to control Block visibility by Book (rather than by taxonomy)?