E.g.

Node A:
Product Category: Bikes > Fixed Gear Bikes

Node B:
Product Category: Scooters

Now if I want to setup custom breadcrumbs and I want to use something like Home > [root term] > [node_title] I'd use something like [node:product_category:root] to get the root category term.

This works for Node A as it will show the crumb as Home > Bikes > Node A Title.
Node B however is broken and it does not render the root term. Perhaps because Scooters itself is a root term and does't have any parents?
Why is this? Is it fixable or intended functionality?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

geophysicist’s picture

Here is patch. Added possibility to use real root. Just insert real-root token instead root

Dave Reid’s picture

Issue summary: View changes
Status: Active » Closed (won't fix)

It sounds like you want a token like [term:root-or-current] that has logic depending if the term itself is a root term or not. You can easily create custom tokens via the core token APIs (hook_token_info() and hook_tokens(), or via the Custom tokens module). I cannot change the behavior of the [term:root] token to fit this need.

valderama’s picture

Here is an implementation of the said hooks to add this [term:root-or-current] token: http://dropbucket.org/node/1535

In my opinion this should be the default behavior of the [term:root] token. I would be glad if this get into future version, where backwards compatibility can be broken.

Or - as a less philosophical solution - add this extra token to the token module.

zwerg’s picture

Status: Closed (won't fix) » Needs review

Both patches won't fix this issue...

mrweiner’s picture

To implement the described custom token in Drupal 8, use the following in your custom module:

use Drupal\Core\Render\BubbleableMetadata;

/**
 * Implements hook_token_info().
 */
function custom_changes_token_info() {
    $info = array();
    $info['tokens']['term']['root-or-current'] = array(
        'name' => t('Root or Current Term'),
        'description' => t("The root term of the taxonomy term unless the term itself is the root."),
        'type' => 'term',
    );
    
    return $info;
}

/**
 * Implements hook_tokens().
 */
function custom_changes_tokens($type, array $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) {
    if ($type == 'term' && !empty($data['term'])) {

$term = $data['term'];

        foreach ($tokens as $name => $original) {
            switch ($name) {
                case 'root-or-current':
                    $storage = \Drupal::service('entity_type.manager')->getStorage('taxonomy_term');
                    $parents = $storage ->loadAllParents($term->id());
                    $root_term = end($parents);
                    if ($root_term->id() != $term->id()) {
                        $replacements[$original] = $root_term->label();
                    }
                    else {
                        $replacements[$original] = $term->label();
                    }
                    break;
            }
        } 
    }
    
    return $replacements;
}
osopolar’s picture

Priority: Major » Normal
Status: Needs review » Needs work

I was surprised as I discovered that [term:root] is only set if the current term is not a root term. I would like to see that behavior implemented, but ss of #2, it may not get fixed. If that is still the case, at least it should be mentioned in the token description, that the token would be empty if term itself is a root term.

It would be the same for other root tokens like the the menu link's root.

BTW: The code in #3 and #5 will work only for the term name/lable, but not for chaining, as it misses following code (see D7 patch):

    if ($root_tokens = token_find_with_prefix($tokens, 'root-or-current')) {
      $parents = taxonomy_get_parents_all($term->tid);
      $root_term = end($parents);
      $replacements += token_generate('term', $root_tokens, array('term' => $root_term), $options);
    }