As described in this issue, it's can be confusing that the "root" token does not return anything if the relevant term is actually itself the root. I'd suggest that we add another token to the module to account for this. It would be as simple as adding a few lines to the module file. Basically all that is needed is to modify the "root" token to state that if the current term is "not !=" the root term, then use the term label as the token replacement.

Not an expert at making patches, but could figure it out again if needed. Is my logic here sound? It seems like a no-brainer to include this token in the core module's functionality.

/**
 * Implements hook_token_info().
 */
function tokens_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 tokens_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;
}

Comments

mrweiner created an issue. See original summary.

brayfe’s picture

This exact instance came up today. I need a URL pattern based on a hierarchical taxonomy tree. The pattern is setup to use "term:root" as the token, however, when a user selects the root term itself, much to my surprise, the term is not in the URL. This is not the behavior I want or need. In the meantime, I've copied the above code (thanks @mrweiner!) into a custom module to handle my use case.

Going forward, would love to see the "term:root" token behave where the term itself can be selected as its own root.

mrweiner’s picture

StatusFileSize
new1.25 KB

@brayfe here's a patch that adds the above code and token. I haven't done any testing so YMMV but I think it should work. Give it a shot and let me know whether or not it works/you see any issues.

brayfe’s picture

Status: Needs review » Reviewed & tested by the community

Fantastic! I updated my site to use the patch provided in #3 (Thanks again @mrweiner!) and it's exactly what I needed. I still believe we should make the root behavior have this functionality, but I'll leave that option to the module maintainers.

mrweiner’s picture

Great, glad it's workin!

berdir’s picture

Status: Reviewed & tested by the community » Needs work

Sorry for the slow response. Does seem like a useful feature, but wondering if we should define it as type term and support nested tokens. Also, tests would be good to have.

mrweiner’s picture

@berdir I'd be happy to jump back into this. I think the patch does define it as type term. Are you saying it would be better to not do that? And do you have a quick reference for how I could add in nested token support and where the test should live?

berdir’s picture

It does, missed that. Unfortunately, that part doesn't happen automatically but it's also not very complicated. You have to find all tokens starting with that and then pass them along to generate the nested tokens. Look for findWithPrefix calls, plenty of examples around that.

Tests should also be pretty easy, there's existing test coverage, just need to add tokens and expected values.

mrweiner’s picture

Ah okay, got it. Thanks

chrisck’s picture

I ran into this today, needing the parent level terms only and found out that [term:root] isn't going to work properly if the root term is the only active term. It would be great to see this new token added to the token module. Thanks for your work so far.

bgilhome’s picture

StatusFileSize
new2.32 KB
new3.04 KB

Here's an updated patch which implements the chained tokens using findWithPrefix(), and refactors a little.

jay.dansand’s picture

Thank you for this patch!

#11 worked to solve our problem. Any reason this has stalled out for more than 2 years? There are use cases where it's a pretty critical ability - get the root item, including if the current item is the root item.

Anyway, +1 RTBC!

jay.dansand’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new2.64 KB

Re-roll against latest 8.x-1.x after commit af85e5f - #3545229: Convert hooks to OOP

The issues in #6 I think have been addressed by #11 (so status would be Needs Review), and we've been using this in production for several years, so I'm marking RTBC. Would be great to get merged so future re-rolls aren't necessary!