Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I'm creating a taxonomy for reptiles in drupal and wish to use pathauto for the term url's. The problem is to find the right tokens (I do have entity token installed). Lets look at an example of the taxonomy-tree for the vocabulary Reptiles:

Lizards
--Family
----Genus
------Species

So far so good:

[term:vocabulary]/[term:parent:parent:parent]/[term:parent:parent]/[term:parent]-[term:name]

result: /reptiles/lizards/family/genus-species

However sometimes there is also a subspecies, thus:

Lizards
--Family
----Genus
------Species
--------Subspecies

then starting at the lowest level and using [term:parent] doesn't work anymore.

Been looking for [term:child] and to generate the path from the opposite direction but I find nothing similar. Another way would be if I could define the term patters with levels in the hierarchy?

something like this:

    [term:vocabulary]/[term:level:1]/[term:level:2]/[term:level:3]-[term:level:4]-[term:level:5]

Maybe someone else knows how to crack this nut?

A better example on the outcome I seek:

/reptiles/lizards/gekkonidae/phelsuma-klemmeri 

or as with a subspecies:

/reptiles/lizards/gekkonidae/phelsuma-klemmeri-subsp
share|improve this question
    
Is the reason it doesn't work that you don't know a priori how many levels of parents you need? I'm not sure I understand why starting at the top would make a difference? –  Ollie Feb 25 at 11:44
    
I added a "something like this" example. The problem when beginning with the lowest term (level 5) is that it may or may not be there. If we began coding from root level we could just skip level 5 if it is missing. Or maybe there is another way of building an taxonomy in drupal. The end result should be that a plant or an animal name is made up of a Genus-Species and maybe also a Subspecies. –  HauRuck Feb 25 at 15:07
add comment

3 Answers 3

up vote 0 down vote accepted

@hitesh's solution using [term:parents:join-path] is good, but it won't create the hyphenated sub-path that you're after. To generate that you could add something like the following to a custom module (not tested):

  //move your module's execution of hook_taxonomy_term_presave to the end of the list, 
    //so that it won't be overridden by the pathauto module.
    function YOUR_MODULE_module_implements_alter(&$implementations, $hook) {
      if ($hook == 'taxonomy_term_presave') {
        // Move hook to the end of the list.
        $group = $implementations['your_module'];
        unset($implementations['your_module']);
        $implementations['your_module'] = $group;
      }
    }

 // invoke hook_taxonomy_term_presave().
function YOUR_MODULE_taxonomy_term_presave($term) {
  switch ($term->vocabulary_machine_name) {
    case 'reptiles':
      //create the alias
      module_load_include('inc','pathauto','pathauto');
      $vocab = taxonomy_vocabulary_load($term->vid);
      $path = pathauto_cleanstring($vocab->name) . '/';
      $parents = array_reverse(taxonomy_get_parents_all($term->tid));
      foreach ($parents as $key => $parent) {
        // use '-' as glue for the second level down and '/' elsewhere
        $glue = ($key >= 1) ? '-' : '/';
        $path .= pathauto_cleanstring($parent->name) . $glue;
      }
      $path = rtrim($path, "-");
      $path_save('taxonomy/term/'.$term->tid, $path);
  }
}
share|improve this answer
    
This looks interesting, but maybe hook_taxonomy_term_presave($term) is too early? $term->tid is NULL –  HauRuck Feb 26 at 6:19
    
ref img of my desktop: picoolio.net/images/2014/02/25/… –  HauRuck Feb 26 at 6:55
    
Of course... You should be able to use hook_taxonomy_term_insert(), I think, but then, it only works when you create new terms. If you use the ..._update() hook, it will override any attempts to set the alias manually. –  Ollie Feb 26 at 13:08
add comment

You can configure URL pathauto alias for taxonomy terms as :

[term:vocabulary]/[term:parents:join-path]/[term:name]
for creating url aliases for taxonomy taxonomy hierarchy.

Explore more using replacement patterns for specific taxonomy terms.

Please refer this image for url aliases configuration page

share|improve this answer
    
result: 'reptiles/lizards/gekkonidae/phelsuma/klemmeri' This is a pretty good solution that would be ok for the taxonomy, but better would be if Genus and Species where joined with a '-' instead: 'reptiles/lizards/gekkonidae/phelsuma-klemmeri' or as with a subspecies: 'reptiles/lizards/gekkonidae/phelsuma-klemmeri-subsp' –  HauRuck Feb 25 at 12:57
    
@HauRuck For that you can use below pattern : [term:vocabulary]/[term:parents:join-path]-[term:name] Replace last slash with dash that will result in format you required . –  hitesh Feb 25 at 13:24
    
That works great when there is only a species: 'reptiles/lizards/agamidae/pogona-vitticeps'. But if there is a subspecies it breaks: 'reptiles/lizards/agamidae/pogona/vitticeps-subspecies'. Correct path with subspecies should be: 'reptiles/lizards/agamidae/pogona-vitticeps-subspecies' –  HauRuck Feb 25 at 15:17
add comment

@olyN Big thank you for the code, it works like wonders. I'll post the finished code for future reference below if someone else seeks a php solution when tokens is not enough.

<!-- language: lang-php -->

 //move your module's execution of hook_taxonomy_term_presave to the end of the list, 
    //so that it won't be overridden by the pathauto module.


function YOUR_MODULE_module_implements_alter(&$implementations, $hook) {
    if ($hook == 'taxonomy_term_insert') {
        // Move hook to the end of the list.
        $group = $implementations['YOUR_MODULE'];
        unset($implementations['YOUR_MODULE']);
        $implementations['YOUR_MODULE'] = $group;
    }
}

function YOUR_MODULE_taxonomy_term_insert($term) {
  switch ($term->vocabulary_machine_name) {
    case 'VOCABULARY_MACHINENAME':
      //create the alias
      module_load_include('inc','pathauto','pathauto');
      $vocab = taxonomy_vocabulary_load($term->vid);
      $path['alias'] = pathauto_cleanstring($vocab->name) . '/';
      $parents = array_reverse(taxonomy_get_parents_all($term->tid));
      foreach ($parents as $key => $parent) {
        // use '-' as glue for the second level down and '/' elsewhere
        $glue = ($key > 1) ? '-' : '/';
        $path['alias'] .= pathauto_cleanstring($parent->name) . $glue;
      }
      $path['alias'] = rtrim($path['alias'], "-");
      $path['source'] = 'taxonomy/term/'.$term->tid; 
      path_save($path);
  }
}

function YOUR_MODULE_taxonomy_term_update($term) {
  switch ($term->vocabulary_machine_name) {
    case 'VOCABULARY_MACHINENAME':
      //create the alias
      module_load_include('inc','pathauto','pathauto');
      $vocab = taxonomy_vocabulary_load($term->vid);
      $path['alias'] = pathauto_cleanstring($vocab->name) . '/';
      $parents = array_reverse(taxonomy_get_parents_all($term->tid));
      foreach ($parents as $key => $parent) {
        // use '-' as glue for the second level down and '/' elsewhere
        $glue = ($key > 1) ? '-' : '/';
        $path['alias'] .= pathauto_cleanstring($parent->name) . $glue;
      }
      $path['alias'] = rtrim($path['alias'], "-");
      $path['source'] = 'taxonomy/term/'.$term->tid; 
      path_save($path);
  }
}
<!-- language: lang-none -->
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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