Last updated June 5, 2009. Created by fgm on January 6, 2008.
Edited by greggles. Log in to edit this page.
The Goal
When choosing a [term] token in one of your aliases, you want to exert some control over which term in which vocabulary is used. There is no way in the current version to specify to which vocabulary the term must belong: for node types with terms from multiple vocabularies one may be more "canonical" to the meaning than others.
Case in point: on my demo site for the G2 Glossary module, G2 definition nodes carry three visible vocabularies:
- thematic context: things like storage, networking, machines...
- grammatical nature
- language
As you can guess, the thematic context is the one to be used by aliases: the entries from the other two vocabularies are interesting, but nowhere near meaningful enough to warrant appearing in the alias, whereas the context definitely adds semantic value to the URLs.
The Internals
(Skip if you're not interested in pathauto internals) Function pathauto_token_values starts by extracting a single $vid for the node being aliased, using db_result(db_query(some SQL .. ORDER BY v.weight, t.weight, t.name ... LIMIT 1));.
At this point, it only has a single vocabulary from which to choose a term, and it is not necessarily the one you want.
The Solution
The vocabulary selection query orders its result by vocabulary weight, so the term actually chosen by pathauto to build the alias is actually selected as the first term in alphabetical order among the lightest terms in the lightest vocabularies.
Which gives the needed solution: order the vocabularies used by the selected node type by weight so that the vocabulary from which you want to use terms for aliasing is the lightest one. You can find these weights at http://example.com/admin/content/taxonomy/edit/vocabulary/<vid>
Comments
Using terms from multiple taxonomies
If you want to use terms from multiple taxonomies, the following work-around may be helpful:-
I had a vocabulary of towns / venues and another of labels / bands.
I wanted to create a "gigs" node with a url containing town/venue/band
The venue and band are selected from the two taxonomies as part of the node creation/update.
The following workaround works for me:-
Using the Automatic Nodetitles module (http://drupal.org/project/auto_nodetitle), I set the option "Automatically generate the title and hide the title field" within "Automatic title generation"
This option allows pre-population of the node title.
I also checked the "Evaluate PHP in pattern" option and inserted the following code in the "Pattern for the title" textarea.
$result = "";$node = node_load(arg(1));
$vid = 1; // Labels and Artists
if($node->taxonomy){
$term = taxonomy_node_get_terms_by_vocabulary($node, $vid);
foreach($term as $t) { $terms[] = $t->name; }
$result = implode('+',$terms) ;
}
return $result;
This code populates the title field with terms from taxonomy 1 (Labels & Artists) which is the more heavily weighted taxonomy in my site.
Then, I set the "Node path settings" within "URL aliases" for the relevant node type to "gigs/[termpath-raw]/[title-raw]".
As the title contains terms from the heavier taxonomy, the final path contains terms from both taxonomies.
Obviously the PHP code used in my example could reference many taxonomies, but this method does rely on not needing the node title for anything else.
HTH
Terry
Recent Drupal sites:-
www.defaqto.com www.quarkexpeditions.com www.sportrelief.com www.intelflexplus.com www.aprilroseturner.com www.businessclubagent.ihg.com www.businessclub.ihg.com www.university-bookseller.co.uk www.philipturnercrafts.co.uk
Saved Me
A spin on this saved me from a headspin on trying to get a clean auto-title out of dual, multi-tiered, Hierarchical Select taxonomies for one of my content types. Below is what I'm using in the auto_nodetitle settings:
<?php
$result1 = "";
$vid1 = 1; // Home Team (HS multi-level taxonomy)
$vid2 = 2; // Venue (Freetagging taxonomy)
if($node->taxonomy){
$term1 = taxonomy_node_get_terms_by_vocabulary($node, $vid1);
foreach($term1 as $t1) {
$tid = $t1->tid;
if(count(taxonomy_get_children($tid, $vid, 'tid')) == 0) { // Only grab the deepest term (Sport >> Division >> Team (No child terms allowed))
$terms1[] = $t1->name;
}
}
$result1 = $terms1[0];
$term2 = taxonomy_node_get_terms_by_vocabulary($node, $vid2);
foreach($term2 as $t2) { $terms2[] = $t2->name; }
$result2 = $terms2[0];
}
else{
$result = 'failed-attempt-at-auto-titling';
}
return $result1 . ' at ' . $result2;
?>
Thank you!
Use this code to allow to use
Use this code to allow to use terms from one vocabulary:
/**
* Implementation of hook_token_list() for Pathauto specific tokens.
*/
function $YOURMODULE_token_list($type = 'all') {
$tokens = array();
if (module_exists('taxonomy')) {
if ($type == 'node' || $type == 'all') {
$vocs = taxonomy_get_vocabularies();
foreach ($vocs as $voc) {
$tokens['node']['term-' . $voc->vid] = t("Name of top taxonomy term in vocabulary " . $voc->name);
$tokens['node']['term-' . $voc->vid . '-raw'] = t("Unfiltered name of top taxonomy term in vocabulary " . $voc->name . ". WARNING - raw user input.");
}
}
}
return $tokens;
}
/**
* Implementation of hook_token_values().
*/
function $YOURMODULE_token_values($type, $object = NULL, $options = array()) {
$values = array();
if ($type == 'node') {
$node = $object;
// And now taxonomy, which is a bit more work. This code is adapted from
// pathauto's handling code; it's intended for compatability with it.
if (module_exists('taxonomy') && !empty($node->taxonomy) && is_array($node->taxonomy)) {
$vocs = taxonomy_get_vocabularies();
foreach ($vocs as $voc) {
$terms = taxonomy_node_get_terms_by_vocabulary($node, $voc->vid);
$raw_terms = array();
foreach ($terms as $term) {
$raw_terms[] = $term->name;
}
$raw_terms_str = implode('-', $raw_terms);
$values['term-' . $voc->vid] = check_plain($raw_terms_str);
$values['term-' . $voc->vid . '-raw'] = $raw_terms_str;
}
}
}
return $values;
}
worked great
this worked great. thank you!
Thanks!
Worked Perfectly :)
from Tridz, Bangalore
Token Vocab Module
See this, instant top terms per vocab as token:
http://drupal.org/node/185446#comment-1480398
Morningtime, a digital agency
Drupal services, web development, project management.
"The vocabulary selection
"The vocabulary selection query orders its result by vocabulary weight, so the term actually chosen by pathauto to build the alias is actually selected as the first term in alphabetical order among the lightest terms in the lightest vocabularies." Jesus Christ!
Just say- Set the lowest weight to the one you want pathauto to use.
Some people make things too complicated. (/rant off)
-Find Open Source Software Tutorials at http://www.penguintutorials.com