Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Blocking core issue: #1954892: Replace 'theme callback' and hook_custom_theme() with a clean theme negotiation system
- Turn Rule Chains from tables to configuration entities (http://previousnext.com.au/blog/understanding-drupal-8s-config-entities and http://www.pixelite.co.nz/article/practical-example-converting-drupal-7-module-work-drupal-8). This way Features support will become obsolete and issue #2024915: rule chain storage refactoring will be fixed.
- hook_init() is gone. ThemeKey Redirect could be implemented like described at https://drupal.org/node/2013014. ThemeKey CSS might use https://api.drupal.org/api/drupal/core!modules!system!system.api.php/function/hook_page_build/8. For ThemeKey Debug we need to find another early hook after hook_theme or do it the Symfony way somehow.
- $_GET['q'] is gone: https://drupal.org/node/1659562
- No more variable_get(): https://drupal.org/node/1667896
- ...
Comments
Comment #0.0
mkalkbrennerUpdated issue summary.
Comment #0.1
mkalkbrennerupdated
Comment #0.2
mkalkbrenneradded blocker
Comment #1
mkalkbrennerhttps://drupal.org/node/2150863
Comment #2
mkalkbrenner'theme callback' and hook_custom_theme() got replaced by theme negotiators
https://drupal.org/node/2158619
Comment #3
markhalliwellComment #4
mkalkbrennerWe need to figure out how to deal with cache tags and cache keys. Do we need to set or invalidate something when a rule matches, for example based on the user agent?
How do we deal with #lazy_builders, placeholders and big pipe?
We have to ensure that a lazy builder uses the same theme that was used to generate the page that contains the placeholder.
Comment #5
mkalkbrennerHi Markus,
Sorry for the delay.
Okay :) Interesting. This screams ‘cache contexts’, but more about that later.
BigPipe works in the *same* request. Given that there are not multiple requests going on, ThemeKey’s negotiated theme will continue to be active.
It’s only once you start using ESI that this becomes potentially tricky, depending on how ESI is implemented. But let’s address that in the future :)
If a theme is selected based on part of the request context (path, language, IP address, country …), then it needs to set a matching cache context: https://www.drupal.org/developing/api/8/cache/contexts.
If a theme is selected based purely on the day of the week, then it needs to set a matching max-age: https://www.drupal.org/developing/api/8/cache/max-age. (Assuming this is determined from the POV of the server, not from the user; if it also takes into account the user’s timezone, then you’ll also need the ‘timezone’ cache context.)
If the “rule chain” is modified and you want changes to take effect immediately, you will also need to associate the cache tag for the config object that contains this rule chain.
In other words: it looks like you’ll need cache contexts, max-age and tags: i.e. all bits of cacheability metadata.
The question is: *where* to associate this? All your logic must run in a ThemeNegotiatorInterface. So that would also be the natural place to apply the corresponding cacheability metadata to the response, right? Except, at that time, there’s no Response object yet!
For cases like this, we use request attributes. There is a very similar example in core: access checking performed during routing. An access check result also has cacheability metadata. We need that to be associated with the Response object, but it doesn’t exist yet. So what the AccesssAwareRouter does is store an “_access_result” attribute on the request that contains the access result object (which includes cacheability metadata). Then there is a RouteAccessResponseSubscriber that applies the cacheability metadata to the Response object when the response is ready.
The final challenge is that theme negotiators do not get the Request object by default. But you can just inject the RequestStack and get the current request, then modify it. An example of that can be found in the BatchNegotiator theme negotiator.
I think/hope this answers all your questions :)
Wim
Comment #6
Wim LeersNow also following this issue :)
Comment #7
Wim LeersIn e-mail, you replied to #5:
To which my answer is this.
That’s not really true.
Drupal 7 just ignored tons of dependencies, it used lots of globals. It was very easy to cache things incorrectly. Consequently, the majority of Drupal 7 sites disable all caching altogether. Because once they enable caching, they’re broken.
Drupal 8 just strongly encourages you to think about dependencies, so that it *can* cache things. See http://wimleers.com/talk/making-drupal-fly-fastest-drupal-ever-here for a more comprehensive explanation.
You could make the ThemeKey module ignore caching or let it continue to break caching like in Drupal 7.
Interestingly, the project page says this:
So I took a look at the 7.x-3.x branch. It has
HOOK_themekey_properties()
, which is essentially *exactly* what cache contexts are. For each, you have to state eitherTHEMEKEY_PAGECACHE_SUPPORTED
,THEMEKEY_PAGECACHE_UNSUPPORTED
orTHEMEKEY_PAGECACHE_TIMEBASED
. The first two basically mean “this is determined solely based on the URL, or a subset of it”. So, that’s what the “url.*” cache contexts are for. You don’t need the first two anymore. The latter is to let it affect the max-age. That’s what cache max-age is for.In other words: instead of modules like ThemeKey having to invent their own concepts, abstractions and implementations, they can now be expressed using the three concepts that Drupal 8 core provides. So, yes, *you* as a module developer will have to learn these concepts, but it means that users of your module don’t have to learn the slightly different concepts in different modules anymore, and will greatly simplify/improve the debuggability of cached things.
Comment #8
eclipce CreditAttribution: eclipce commentedHI;
ThemeKey not showing config
Thanks
Comment #9
markhalliwell@eclipce, please don't hi-jack issues. Create new ones and reference any existing related issues (except that a simple "it's not working" comment here would have certainly sufficed).
Restoring issue metadata and summary.
Comment #10
gavip CreditAttribution: gavip commentedHi, has there been additional progress made to the porting of this module?
Thanks
Comment #11
mgiffordIs the best D8 module for this type of functionality https://www.drupal.org/project/styleswitcher
Comment #12
WillyT CreditAttribution: WillyT commentedIs there any further progress on the porting of this module?
Comment #13
mkalkbrennerWe still wait for a sponsor or to be involved in a project that will use ThemeKey. It's too much work to do it as a hobby.
Comment #14
farida69 CreditAttribution: farida69 commentedI would like to know when the module will be released ?. Drupal 9 will be available soon and because of this module we stocked in drupal7.
Comment #15
amarincolas CreditAttribution: amarincolas as a volunteer commentedI have recently published a module called "Theme Switcher Rules" to bring the ability to create theme-switching rules which allow automatic selection of a theme based on Drupal 8 Conditions system.
Thanks.
Comment #16
mkalkbrenner@amarincolas see #3213791: Co-maintaining this module?
Comment #17
mkalkbrennerThemeKey rules and properties should be migrated to Drupal's condition system that was introduced in Drupal 8. There's already a tiny theme negotiator that does the theme switching based on conditions: Theme Switcher.
We decided to leverage Theme Switcher as new "engine" for Drupal 8 and 9.
So the current plan is to keep Theme Switcher small and to use ThemeKey as an extension to provide additional conditions if required.
Like in the past it would be better if other contrib modules provide their own conditions, just like we encouraged them to provide their own ThemeKey properties. But we still have the freedom to do some stuff here.
Any help in migrating the rules and properties to conditions is welcome!
Comment #18
ressa CreditAttribution: ressa at Ardea commentedIt sounds like a great plan! Is it worth considering creating an issue for each rule and property which could be moved?
A meta issue in the Theme Switcher issue queue (or here) could list these issues, to better organize the project.
Comment #19
mkalkbrennerHaving a such a list would be good. I'm sure that they have to be implemented in different ways. Help is welcome, even for creating the issues.
Comment #20
ressa CreditAttribution: ressa at Ardea commentedI have created #3214528: [meta] Port ThemeKey rules and properties to Drupal's condition system, feel free to edit the title or Issue Summary if necessary. I have added a single issue, just as an example, since I am not sure if that rule exists in ThemeKey. Other users should feel free to add more issues, as they are created.
Perhaps I can ask you to create an issue for a ThemeKey rule or property which should be migrated to Drupal's condition system? Just a title and rough outline of the feature would be great, more details can always be added later.