Score:0

Controller on /taxonomy/term/{taxonomy_term} route

lc flag

I have a regular Controller on the taxonomy term page (the original view is disabled). It works all right to show what I want it to show, however, neither its getTitle nor its access is ever called (the second being more vexing, of course). The problem is not with my controller, because using a different route works just fine:

example.content.documents_list:
  path: '/taxonomy/term/{taxonomy_term}'
  defaults:
    _controller: '\Drupal\example\Controller\DocumentListController::content'
    _title_callback: '\Drupal\example\Controller\DocumentListController::getTitle'
  requirements:
    _custom_access: '\Drupal\example\Controller\DocumentListController::access'

example.content.documents_list2:
  path: '/xxx/{taxonomy_term}'
  defaults:
    _controller: '\Drupal\example\Controller\DocumentListController::content'
    _title_callback: '\Drupal\example\Controller\DocumentListController::getTitle'
  requirements:
    _custom_access: '\Drupal\example\Controller\DocumentListController::access'

I can create a RouteSubscriber if needed but is it really needed? Are those settings never really picked up?

Kevin avatar
in flag
Guessing your custom access is not properly tagged. Why not use TVI?
lc flag
And it still gets called when the path is any different? Because my needs are drastically different. My controller decides what to show depending on many factors, embedding various blocks or creating tables as the situation dictates. Those are not solvable with views the way I want them to be solved. I'm a programmer, so have no problems with creating content with my own code instead of Views (don't misundestand me, I have nothing against Views and I do have a few on this site, just that there are places where a view is not the best solution).
4uk4 avatar
cn flag
The View is an override for an already existing core entity route, which is re-enabled when you disable the View. See https://drupal.stackexchange.com/questions/241880/override-specific-routing-from-a-core-module
lc flag
This was the probable solution I hinted at but in the meantime, I tried another approach, and it fails. Isn't the EnhancerInterface applicable here? I can change the incoming $defaults['_title_callback'] to something else but it doesn't make any difference. (I already have an enhancer for a different route, so it was more straightforward just to try adding another condition there).
lc flag
Oh dear, oh my, I already had a subscriber, I forgot when I added it, just that it only set the _controller not the others... :-) I'll copy it to an answer for eternity. Thanks for the right pointer.
Score:1
lc flag

It was partly my mistake, I did have a RouteSubscriber already in place but not fully engaged yet, as the comment of 4k4 pointed out. The final solution is: yes, it has to be overridden because it's a system route:

class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.taxonomy_term.canonical')) {
      $route->setDefault('_controller', 'Drupal\example\Controller\DocumentListController::content');
      $route->setDefault('_title_callback', 'Drupal\example\Controller\DocumentListController::getTitle');
      $route->setRequirement('_custom_access', 'Drupal\example\Controller\DocumentListController::access');
    }
  }

}
sonfd avatar
in flag
To clarify, you use the route subscriber to alter the existing routes **instead of** defining your routes via my_module.routing.yml?
lc flag
I have both. Belt and braces, you know. :-) But now you made me curious, I check if just the subscriber is enough. Answer: the subscriber on its own is enough. The .yml on its own isn't.
Kevin avatar
in flag
The yaml defines it, the alter modifies the existing - that is why. That route already exists.
apaderno avatar
us flag
Route subscribers are used to alter a route defined from another module; they are the equivalent of `hook_menu_alter()` in Drupal 7. The .routing.yml files are the equivalent for `hook_menu()` in Drupal 7. As with Drupal 7, you don't use both for the same route.
lc flag
One small question or remark then: if I omit the same from .routing.yml, I lose the comfort of my different route name and I have to use the original one throughout my code. Specifying it both there and in the subscriber seems to offer the best of both worlds, even if redundant: I can use my own route name and it still gets overridden.
4uk4 avatar
cn flag
You could remove the core route in the route subscriber `$collection->remove('entity.taxonomy_term.canonical');` so that you don't have two routes for the same path after you've added your own route in *.routing.yml. Caveat: This might break dependencies, for example in menu links.
4uk4 avatar
cn flag
There is no problem having two routes for the same path, but it only makes sense if they differ when matching the route, for example having different protocols. Otherwise the route match results in random behavior. By having the same controller you don't notice the random behavior now, but this could be difficult to debug later when you change one of the routes.
4uk4 avatar
cn flag
So it is probably the best idea to use the original route throughout your code.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.