Score:0

Use specific theme [not template file] for 404 and 403 generated for specific path

mk flag

I have 2 themes, both enabled, assume they are called my_first_theme (default) and my_second_theme. I have /whatever path and lots of the pages under this path, and I have a theme negotiator, which sets my_second_theme as an active one for any page under this /whatever path, including nodes, views, custom controllers etc.

So far it works good. Problem is, when 404 or 403 is triggered, the theme used to generate the response is always the default one (my_first_theme).

What I need is when 404 or 403 response is generated for any path under /whatever path, I would like the my_second_theme to be used for those templates, not the default one. The only way to achieve it at this moment I see is that I create a copy of the frontend stuff under my_first_theme just to be used for 404 and 403 purposes, but that's definitely a dirty way to do that. Basically I will have a clone of my_second_theme assets under the my_first_theme folder just to serve 404 and 403 responses.

Few examples of what I would like to achieve:

  • /nonexistent404 - my_first_theme used
  • /exists/but/access/denied403 - my_first_theme used
  • /whatever/nonexistent404 - my_second_theme used
  • /whatever/path/exists/but/no/access403 - my_second_theme used
Score:1
cn flag

How does the theme negotiator get the path?

In a sub-request for a 403/404 error page you are probably looking for the path of the main request:

$main_request = \Drupal::requestStack()->getMainRequest();
$path = \Drupal::service('path.current')->getPath($main_request);
Alex Smirnoff avatar
mk flag
Unfortunately by the time the 404 error is handled, Drupal has already completed the theme negotiation process and set the active theme. This is why the theme negotiator does not affect the theme for 404 pages. I also tried to handle KernelEvents::EXCEPTION, without any luck, theme is already chosed by that time
4uk4 avatar
cn flag
Did you try to get the path I suggested in applies() and determineActiveTheme() of your theme negotiator? I just tested it with my debugger and it stops there in the sub-request.
4uk4 avatar
cn flag
Looking at the theme manager this service is global to the main request so it doesn't really matter when the theme is initialized. Important for a path-based theme negotiator is to get the path this way. Then you don't depend on the timeline. However, for a 404 this is very likely to take place in the sub-request because you are thrown out of the main request very early before any theming can happen.
Alex Smirnoff avatar
mk flag
Okay so basically getMainRequest() is what I needed. Before that I was using $route_match, which was only working for existing routes and in case of 404/403 it was an instance of NullRouteMatch. Thanks for your help.
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.