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.
Hi all,
I am having a problem with switchtheme and anonymous users. If I disable normal caching, they are able to switch themes, however when enabled, only authenticated users are permitted. Is this a known limitation of switchtheme? You can see the problem in action at www.myappleguide.com
Comment | File | Size | Author |
---|---|---|---|
#21 | switchmodule-caching-D6.patch | 463 bytes | Andrew Answer |
Comments
Comment #1
sunHm. Yes, that seems to be a limitation. Drupal's page caching for anonymous users statically caches all pages. Did you try the latest development snapshot already?
Comment #2
sunSorry, without further information this issue can only be marked as won't fix. Feel free to re-open this issue if you want to provide further information.
Comment #3
gausarts CreditAttribution: gausarts commentedhi,
I am in the process of proposing a CVS account, and I need to show the maintainers where my themes alive. It'll be great if it works for anonymous in normal cache. The latest dev release didn't even work for registered users, so I switched back to the stable one. At least it consistently works for the registered.
So I'd love to know if there's a plan to improve it. Thanks
Comment #4
bellesmanieres CreditAttribution: bellesmanieres commentedHi,
The only workaround I could find is using the ability of Switchteme to set the theme using the $_GET variable. It is'nt really satisfactory nor efficient, but I give it here for what it's worth.
Adding the following in settings.php will pass the theme parameter to all drupal generated links, making them look like example.com/content/mycontent.html?theme=theme_name.
Be aware that :
That should be sufficient to make anonymous users keep a theme.
Going further
As I want to stick with clean urls and don't want duplicate content to arise in search engine, i make a bit of additional rewriting.
Adding the following in settings.php ...
... and these lines in .htaccess, BEFORE drupal's own rewriting rules ...
... let me have url looking like 'theme2/content/mycontent.html' and exclude search engines from indexing the themed versions of the site via robots.txt.
You can see it 'in action' at http://www.pascal-morin.com
So, I know this in no way a good and proper solution, but I hope it can be of some use for a few of you.
Pascal
@sun : I'm not sure if this really the best place to post (in fact, I'm quite sure it isn't) but I couldn't think of a more suitable page. So, feel free to edit/move/delete my post. Thanks
Comment #5
sunRe-opening as feature request.
I'm not entirely sure, but my first guess would be to investigate whether we can use hook_init() to intercept the page request and assign a new theme. Probably needs a separate page cache per theme.
Comment #6
bellesmanieres CreditAttribution: bellesmanieres commentedThat would for sure increase performance to test the page request in hook_init instead (custom_url_rewrite is called +100 times / page, states the drupal doc).
I hope I'm not missing the point (I'm quite new to drupal API and do not understand well all the hook mechanism), but the main problem I see is that hook_init isn't called on cached pages, so we still have to perform url rewriting to make drupal generate a new page.
Moreover, I did'nt find a way to alter the url besides custom_url_rewrite_in/outbound (the incoming rewriting rules i made with .htaccess can be done that way too), that are not really hooks, as they need to be put in settings.php.
As you're far more experimented than me, you might have a few clues of how this can be done ? I'll try to experiment on all that next week, when I'll have more time.
Comment #7
gausarts CreditAttribution: gausarts commentedThanks for considering this as feature request. It's a great help.
Comment #8
JurriaanRoelofs CreditAttribution: JurriaanRoelofs commentedsubscribing
Comment #9
aryanto CreditAttribution: aryanto commentedI am waiting for this feature as well.
Comment #10
mikeytown2 CreditAttribution: mikeytown2 commentedSet a cookie, redirect to that theme (see global redirect). Whats the URL structure for different themes?
Comment #11
aryanto CreditAttribution: aryanto commented@mikeytown2
I am not sure what your question is referring to. But if you meant the structure of the URL for each of the themes, then from what I experienced there is no different at all. The URL remains the same when I switch from one theme to another. So I am not sure if global redirect would be able to help.
Comment #12
mikeytown2 CreditAttribution: mikeytown2 commented@aryanto
Guess this module does a POST to set the theme, If it used a GET, then it would be compatible with caching.
Comment #13
sunBut only if it would implement a custom_url_rewrite_outbound() handler that rewrites all following URLs to use the query string as well.
Comment #14
mikeytown2 CreditAttribution: mikeytown2 commentedYou could do it ghetto. Check for a cookie in jquery; get URL, if ?theme=* isn't set right, redirect.
Comment #15
AndrasAcs CreditAttribution: AndrasAcs commentedAs far as I understand, hook_init is not called on cached pages, but hook_but is also called on cached pages. So trying to rewrite the code to use hook_boot could help. I am looking very much forward to a Switchthemes version, that can handle caching.
Comment #16
mikeytown2 CreditAttribution: mikeytown2 commentedhook_exit() would be another option. boost_exit might give some inspiration.
Personally I think javascript would be the simple solution. Get it working there first then try to do it in PHP.
http://plugins.jquery.com/project/Cookie
http://plugins.jquery.com/project/parseQuery
Comment #17
mdixoncm CreditAttribution: mdixoncm commentedI reckon the easiest way to do this would be to use the purl module - http://drupal.org/project/purl - this will take care of all the "token" persisting for you, don't need to worry about cookies or javascript etc - lovely jubely :)
Comment #18
Rob C CreditAttribution: Rob C commentedSubscribing
Any news on this?
I'm using another approach, i patched the switchtheme module to show one single submit button with a hidden value for the theme name. I got four themes installed, but it only has to switch between the first two, created a small piece of code that checks the current theme name, gets the first two active themes and a case that switched the output to the hidden field (theme name) and submit button text (switchtheme alias from one of the first two themes).
And yes it has the same problem when caching is enabled, i need this for a new site i'm working on and i already have so much scripts that i would really like it to get this to work without an additional javascript. (aka the separate cache per theme sounds very very nice and i guess that would make the most sense? Still need to fumble the boot function somewhere...)(didn't see what purl can do, sounds promising, will look into this, or something similar to http://drupal.org/node/361832#comment-1587680 and trow away the form and just create some old fashion 'links'. :-)
Comment #19
RockSoup CreditAttribution: RockSoup commentedSubscribe
Mike could you please talk a bit about how you might implement this?
I am using switchtheme and caching is not allowing the theme to change once it has been cached.
Thanks!
Comment #20
Andrew Answer CreditAttribution: Andrew Answer commentedWhat about simply clear page cache when theme switched? This will fix that problem.
I found easy workaround for D6.20: add
db_query("TRUNCATE TABLE {cache_page}");
into switchtheme.module::switchtheme_switch_form_submit() function here:
Comment #21
Andrew Answer CreditAttribution: Andrew Answer commentedI made a patch for this.
Comment #22
mikeytown2 CreditAttribution: mikeytown2 commentedMight as well run with the page cache disabled. If 10 different uses change the theme for them self's it still doesn't solve this issue. The cache from one theme will be served to another user who is set to use a different theme.
Comment #23
rjacobs CreditAttribution: rjacobs commentedHello,
Until there is a solution built-in to the module itself, I think it would be useful to note in the documentation (README and project pages) that switchtheme is incompatible with Drupal page caching. This, of course, only applies if you have the permissions set to allow anonymous users to switch themes (and expect them to be able to do so), but it seems like an outstanding incompatibility non-the-less. Noting this somewhere might save folks some troubleshooting time.
Cheers,
Ryan
Comment #24
mikeytown2 CreditAttribution: mikeytown2 commentedJust had a brain storm; details on how to do it are here
http://groups.drupal.org/node/121054#comment-411834
Does NOT work with boost; or if it does not recommend.
Comment #25
RockSoup CreditAttribution: RockSoup commentedI have a solution that is working for me for this issue with much help from mikeytown2.
Using this solution means that the first time a user visits the site they will be served an uncached page. Once the first page is loaded and switchtheme does it's magic to assign the proper theme we set a cookie in the user's browser with a value of the theme name. A few lines are added to settings.php that check for that cookie and when it exists the page is served from cache. We are setting a separate cached version of the page as sun suggested in #5 above.
Here is the code added to switchtheme.module:
And the code from settings.php:
Comment #26
RockSoup CreditAttribution: RockSoup commentedUpdating issue to show only minimum required code.
Also want to mention that this code came from collaboration at the most excellent Seattle Drupal User Group.
So, one only needs to add these 5 lines to the bottom of switchtheme_init()
Here is the bare minimum for settings.php
Comment #27
trante CreditAttribution: trante commented@RockSoup thank you for patch.
I was curious for that issue for months, but didn't solve this issue in a good way.
After some research i found ThemeKey module.
It is written in info page:
I write this if somebody like me needs Boost caching + Theme switching.
PS: ThemeKey switches themes relatyed to your written rules, on the contrary of Themeswitcher gives a manual preference.
PS2: In ThemeKey's settings, i saw this and i became suspicious. "Page Cache
Unsupported! If you enable page caching on your system, you have to ensure that any rule using this property is wrapped by another rule that excludes anonymous users, such as "user:uid > 0"."
Comment #28
nevosa CreditAttribution: nevosa commentedI've created a sandbox project that allows for theme selection for anonymous users with page caching enabled,
view it here:
Anonymous Theme
and leave comments/reviews.
Comment #29
mikeytown2 CreditAttribution: mikeytown2 commented@nevos
hook boot only fires on a cache miss. hook exit fires after the page has been retried from the cache_page bin. See
case DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE:
in _drupal_bootstrap(). Your sandbox won't work from what I can tell.Comment #30
rjacobs CreditAttribution: rjacobs commentedI'm not 100% on this but I believe that hook_boot will indeed always run even when caching is enabled, so long as aggressive caching is not enabled. I think the issue may be that Drupal decides what cached details to serve up before hook_boot fires, so it's hard to manipulate these details by the time we get to hook_boot.
The following links might be useful here:
http://drupal.org/node/916552
http://drupal.org/sandbox/brian_c/1413374
Sorry if I'm off-base on this, I have not been following this thread for a while and I have not looked the nevos's sandbox... I just saw comments #28 and #29, and they lead me to believe this is related to a separate issue I was researching where the above links proved very useful.
Comment #31
mikeytown2 CreditAttribution: mikeytown2 commentedhook boot will run. read the if statement incorrectly (thought I saw an and instead of an or).
Comment #32
nevosa CreditAttribution: nevosa commented@mikeytown2
I did see the the or statement there, so I tested it some more, to find that hook_boot does actually get called.
However in testing the code - on some situations cached pages were still being served.
Perhaps I'm wrong in this, but I've added the "dynamic cache" to all the theme switching cases via,
http://drupal.org/sandbox/brian_c/1413374
and it work perfect.
But I'm still not sure the bootstrap hijacking is necessary... let me know if you have a clearer notion of this,
Thanks,
Comment #33
mikeytown2 CreditAttribution: mikeytown2 commentedThe only way to do this is to put the hijack code in settings.php. Unless you do that, it wont work. See #26
Comment #34
rjacobs CreditAttribution: rjacobs commentedIt could be that you need to make "dynamic cache" a dependency for this new module. My understanding is that this kind of thing is exactly why that module was made. From what I've been able to read, and as noted in #26 and #33, the only real alternative is making custom mods to settings.php.
What I understand is that a cached page is calculated and retrieved from the DB (as the content to be loaded) before hook_boot, so adjusting any global cache settings in hook_boot does not stop the cached version from being prepared. Then after hook_boot, and before bootstrapping is done, the cached version is loaded. So the only way to dynamically prevent a cached version from being used, based on any logic called in hook_boot, is to hijack the rest of the bootstrap process that happens after hook_boot.
However, if you do your logic (to test if you need to dynamically disable caching) in settings.php, that will fire before the cached page is calculated and retrieved from the DB (and certainly before hook_boot), making it the only other option... though not as "modular" of an option.
Even more reading available here:
http://drupal.org/node/875152
I just wanted to convey a summary of my understanding in case that helps. The notes in the discussions leading up to brian_c's module certainly offer a better and more complete explanation.
Comment #35
idflood CreditAttribution: idflood commentedAnother method is to simply have different paths for different themes (either different subdomain, path prefix, query string, .... ). There is the purl module (http://drupal.org/project/purl) that make it relatively easy to do. This makes what is proposed in #4 much more easy to implement. Here is a first patch I've done for another module using this: http://drupal.org/files/mobile_theme_cache_purl-328675-10.patch
Since the issue is relatively similar to this here is the link: #328675: Single domain incompatible w/ Drupal 'Normal' caching. Switch theme based on domain...
Comment #36
nevosa CreditAttribution: nevosa commented@rjacobs thank you for you comments, they helped a lot!
So I guess hijacking boot would do the trick, and the anonymous theme does seem to work well this way.
However, I am troubled by the fact that the dynamic cache is still in a sandbox mode, and it is too short to be considered a module - so I can't really set a dependency, on the other hand it wouldn't be very collaborative to just use that code inside hook boot and suggest a new module...
Do you have an idea how to advance this?
Thanks,
Comment #37
rjacobs CreditAttribution: rjacobs commentedHi nevos. If all you need to do is turn off the cache for a page load based on some conditional logic in hook_boot, then I do imagine that dynamic_cache would be the easiest "drop-in" solution. Having dynamic_cache maintained separately might also help ensure that it gets updated whenever part of Drupal core's bootstrap gets updated, otherwise you would have to monitor your module for those updates as well. In this regard keeping it separate could be an asset... though I'm not too sure if that effort will become an official project or not. I'm personally only using it in conjunction with a custom module for a single site, so my usage of it is very isolated.
I guess the real danger of the whole dynamic_cache approach is that it's dependent on another module (dynamic_cache) properly mimicking Drupal core functionality. It can probably work pretty gracefully, but only if dynamic_cache is kept up-to-date with core's bootstrap code.
Perhaps you could explore whatever is the easiest approach to turn your module into a working proof-of-concept and later also think about adapting it to work with other alternative "dynamic cache control" methods? It looks like you would be offering quite a few dynamic methods to control a theme selection at 'runtime', so the alternative of putting all that logic directly into settings.php might not fly, but the PURL method in #35 might be interesting to explore. I'm guessing that method would even allow for alternatively themed versions of pages to be cached given that they would live under their own URLs.
Just some general thoughts. I'd be curios what others think as well.
Comment #38
krishanchandra CreditAttribution: krishanchandra commentedThis Patch work fine for me
http://drupal.org/files/issues/switchmodule-caching-D6.patch
Thanks
Comment #39
Sarah_G CreditAttribution: Sarah_G commentedRegarding the code by RockSoup in #26
I've been trying to get this to work. Should I be replacing any of the variables with my unique variables? For example where it says 'theme_default' am I supposed to put in the name of my theme on my site? I know this is really old and I've been working it for over a year. I felt like I was close but the cacheing part just doesn't work all the time. Thanks for any insight.