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
Comment #2
brayfe commentedThis 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.
Comment #3
mrweiner commented@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.
Comment #4
brayfe commentedFantastic! 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.
Comment #5
mrweiner commentedGreat, glad it's workin!
Comment #6
berdirSorry 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.
Comment #7
mrweiner commented@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?
Comment #8
berdirIt 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.
Comment #9
mrweiner commentedAh okay, got it. Thanks
Comment #10
chrisckI 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.
Comment #11
bgilhome commentedHere's an updated patch which implements the chained tokens using findWithPrefix(), and refactors a little.
Comment #12
jay.dansand commentedThank 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!
Comment #13
jay.dansand commentedRe-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!