Score:1

Local task for content node doesn't show up and raises 'Access denied'

bo flag

After spending two days trying to figure this out, it's probably better to ask for help.

I need to add a custom tab next to View Edit Delete Revisions Translate for content nodes (a local task, if I understand the terminology correctly). This tab is supposed to open a form where the user can select from a choice of tasks to perform on the current node (e.g. generating a summary of the text with A.I.).

I have already successfully added another tab that opens a View (/admin/content/query/%). It works fine:

MODULE_NAME.routing.yml

# This works fine
MODULE_NAME.manage_content:
  path: '/admin/content/query/{node}'
  requirements:
    _role: 'administrator, content_editor'
  options:
    parameters:
      node:
        type: 'entity:node'

MODULE_NAME.link.tasks.yml

# This works fine
MODULE_NAME.manage_content:
  route_name: 'MODULE_NAME.manage_content'
  title: 'Manage'
  base_route: entity.node.canonical
  weight: 200

I just can't get it to work for the new tab (it doesn't even show up), which is supposed to open a Form:

MODULE_NAME.routing.yml

# This won't work no matter what 
MODULE_NAME.node_options:
  path: '/node/{node}/options'
  defaults:
    _form: '\Drupal\MODULE_NAME\Form\ConfirmOptionsForm'
  requirements:
    _role: 'administrator, content_editor'
  options:
    parameters:
      node:
        type: 'entity:node'

MODULE_NAME.link.tasks.yml

# This won't work no matter what 
MODULE_NAME.node_options:
  route_name: 'MODULE_NAME.node_options'
  title: 'Options'
  base_route: entity.node.canonical  
  weight: 210

ConfirmOptionsForm is a subclass of ConfirmFormBase.

When I call /node/1234/options manually with a web browser, Drupal shows an 'Access denied' error (You are not authorized to access this page). This suggests the path is somehow off limits, but how? Trying other paths didn't help.

What am I missing?

unusedspoon avatar
aq flag
Have you tried changing the routing to point to a simple form/controller to rule out something within your form isn't causing the access denied? Also where is your first routing example actually routing too? Doesn't appear to be anything based on your code snippet
Anders avatar
bo flag
Thanks. Just tested with a basic 'Hello World' controller. Same access denied error and tab still doesn't show up. If it's the access denied issue that makes the tab hidden, that would at least narrow it down a bit. But I'm not sure about that. Oh, and the first snippet points to a View (a content query).
Anders avatar
bo flag
Changing **_role: 'administrator'** at least makes the tab appear. Will need to approach from there. This is weird, because it actually worked with multiple roles with a View and I remember seeing examples on the web that also used multiple roles.
unusedspoon avatar
aq flag
I'd get rid of the space in `'administrator, content_editor'`and the comma means the user needs to have BOTH roles, could that be the issue? Docs say to use `+`for an OR https://www.drupal.org/docs/drupal-apis/routing-system/structure-of-routes
unusedspoon avatar
aq flag
The reason your view probably works is because you've already defined the path/permissions within the view. There's no need to create a routing yml for views (unless you want multiple paths to the same view)
Score:2
us flag

One thing to note is that with _role: 'administrator,content_editor' the route is accessible to users who have both the roles, not either one or the other role.

As described in Structure of routes, you can separate the single roles an accounts needs to have to access the route with a + sign. In your case, instead of _role: 'administrator,content_editor', you would use _role: 'administrator+content_editor'. That would make the route accessible to users who have either the administrator or the content editor role.

However, in Drupal, it is preferred to use permissions instead of roles. It allows better flexibility because the permission can be added to more roles without changing the route definition.

This is the first step I would go with.

Anders avatar
bo flag
That helped, thanks. I now changed it to **_entity_access: 'node.update'** which also does the trick, allowing only node owners to see that tab. The main question however is still open: How to make the form work on the node. I should state that as a separate question, though.
Ivaylo Tsandev avatar
us flag
Great, glad it helped!
I sit in a Tesla and translated this thread with Ai:

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.