Closed (fixed)
Project:
Drupal core
Version:
7.x-dev
Component:
Garland theme
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
15 Feb 2009 at 07:15 UTC
Updated:
8 Aug 2014 at 14:26 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
wretched sinner - saved by grace commentedHave a look at http://drupal.org/node/195435. It is a bit trickier to theme the maintenance page, due to when you will use the maintenance page, but it is doable!
Comment #2
mattyoung commentedI've no idea what's going on. I did set 'maintanence_theme' in settings.php and it works for database error page. But site off-line is always un-themed.
I don't understand what's going on.
theme('maintanence_page', ...)is called and the built-in 'maintanence-page.tpl.php' are actually a full page. But in off-line mode, only a plain text page is shown.Comment #3
mattyoung commentedI figure out what's wrong. It's a bug in the garland theme. It doesn't have
phptemplate_preprocess_maintenance_page(&$variables)in its template.php file. So the required variables needed in the maintenance-page.tpl.php are not set, resulting in a plain page. If you do a view page source, that page actually has all the divs. Just that they are all blank.Once I add the following to garland's template.php file, site off-line page display correctly:
Comment #4
wretched sinner - saved by grace commentedI would caution about modifying core template files, as the changes will get wiped out next time you upgrade. I'll move this to the main queue as a (possible) bug and get those in charge of Garland to have a look.
Comment #5
mattyoung commentedAfter some more research, I found that just do:
at the end of Garland's template.php in enough to fix this problem. The reason is the theme registry build look for the existence of a function template_preprocess_maintenance_page(). If one exists, it's included in maintenance_page() theme hook preprocessor function.
Defining this function:
work also because theme registry build also look for the existence of phptemplate_preprocess_maintenance_page() and since we define one, it's included in the preprocessor hook list. In normal page execution, template_preprocess_maintenance_page() is undefined because it's defined in theme.maintenance.inc and it's never require/include in normal page render. But when in off-line mode, drupal_maintenance_theme() is called and that's defined as this in bootstrap.inc:
I don't know which method is better. I suspect defining phptemplate_preprocess_maintenance_page() is probably better because in normal operation, theme.maintenance.inc does not get included, saving some parsing.
BTW, setting maintenance_theme = 'garland' in settings.php and when database is bad, that page is displayed correctly with Garland's tempalte.php as is now. But that's a special case: drupal_maintenance_theme() is called early on, causing theme.maintenance.inc to be require_once and template_preprocess_maintenance_page() comes into existence. So when the theme registry is then build from scratch, it's included as preprocessor hook.
Comment #6
dvessel commentedI'm not sure what isn't being themed. I tried with Garland and it seems to work just fine.
This point may be obvious but just in case it was missed. -You have to be logged out to have the maintenance theme take over.
Comment #7
dvessel commentedBTW, all the variables for Garlands page.tpl.php file and maintenance-page.tpl.php should be available. Some for maintenance-page.tpl.php might be just an empty string but that was done to keep the two templates very similar.
As long as Garland wasn't modified, it should work just fine.
Comment #8
mattyoung commentedIt definitely doesn't work for me and I don't see how it should work. With Garland's template.php as is, neither of these function exist when the theme registry is built:
So the theme registry will not have the necessary preprocess function. Just use the devel module to dump out the theme registry, you will see this for the maintenance_page hook is like this:
maintenance_page
(Array, 7 elements)
template
(String,
16 characters )
maintenance-page
path
(String,
14 characters )
themes/garland
type
(String,
12 characters )
theme_engine
theme path
(String,
14 characters )
themes/garland
arguments
(Array, 3 elements)
content
(NULL)
show_blocks
(Boolean)
TRUE
show_messages
(Boolean)
TRUE
theme paths
(Array, 2 elements)
0
(String,
14 characters )
modules/system
1
(String,
14 characters )
themes/garland
preprocess functions
(Array, 1 element)
0
(String,
19 characters )
template_preprocess
|
(Callback)
template_preprocess();
=
=
=
=
But if I define
phptemplate_preprocess_maintenance_page()in template.php, it becomes this:maintenance_page
(Array, 7 elements)
template
(String,
16 characters )
maintenance-page
path
(String,
14 characters )
themes/garland
type
(String,
12 characters )
theme_engine
theme path
(String,
14 characters )
themes/garland
arguments
(Array, 3 elements)
content
(NULL)
show_blocks
(Boolean)
TRUE
show_messages
(Boolean)
TRUE
theme paths
(Array, 2 elements)
0
(String,
14 characters )
modules/system
1
(String,
14 characters )
themes/garland
preprocess functions
(Array, 2 elements)
0
(String,
19 characters )
template_preprocess
|
(Callback)
template_preprocess();
1
(String,
39 characters )
phptemplate_preprocess_maintenance_page
|
(Callback)
phptemplate_preprocess_maintenance_page();
Comment #9
mattyoung commentedAttached is the plain looking garland off-line page
Comment #10
mattyoung commentedHere is what the page look like after patching template.php
Comment #11
dvessel commentedhttp://api.drupal.org/api/function/template_preprocess_maintenance_page/6
It's there. Could you try it on a fresh install to rule out your server? I'm not having any problems with it myself and I'm running it off of MAMP on Mac OS X.
Comment #12
dvessel commentedI misread, you know it's there.. I'm not sure why it's not being included in your install. I can't recreate it myself.
Comment #13
mattyoung commentedI tested this on several sites and they are all the same.
Can you go to 'devel/php' and execute this:
On my install, the first is true, and second is false and that's the problem. I suspect for you it might be both true and this mean 'theme.maintenance.inc' is require/include somewhere in your install for normal site operation. That's not the case for my 6.9 install. The only place this file is required is in bootstrap.inc:
and this function is only called when the site is off-line. During normal operation like when the theme registry is built, no body include/require theme.maintenance.inc. If yours is different, some body else is include/require this file. Try to find who is doing this by 'egrep -lr "theme.maintenance.inc" .' or use whatever recursive search tool from the top of your Drupal install. I suspect some other code is include/require this file and that's not in the normal Drupal install.
In any case, I now think this is a bug for core to fix. Theme.inc should include 'theme.maintenance.inc' when it builds the theme registry so the
template_preprocess_maintenance_page()hook can be found. Every theme has this problem actually and it should be taken care of in core like this:in theme.inc:
Comment #14
dvessel commentedI'm responsible for allowing the maintenance page to be themable. The registry handling for the maintenance page is handled differently. It doesn't need to be in the cached registry while in normal operation. It's only when set to offline mode and you're viewing the site as an anonymous user, the registry gets built with template_preprocess_maintenance_page. This includes when the db is offline. In all other cases, it's not needed and so it isn't included.
As long as drupal_maintenance_theme() is invoked while in offline mode, it should work. Why your install doesn't call this is beyond me.
Comment #15
mattyoung commented>I'm responsible for allowing the maintenance page to be themable.
Ha, I'm talking to real McCoy.
>It's only when set to offline mode and you're viewing the site as an anonymous user, the registry gets built with template_preprocess_maintenance_page.
Okay, I know what's going on. Your assumption is no body cause the theme system initialized during bootstrap. I have a module that makes
theme()call in its _init() hook. This has the unfortunate side effect of initializing the theme system even in off-line mode._drupal_bootstrap_full()invoke all init hooks. By the time execution gets todrupal_site_offline(), global $theme is set:so the rest is skip and the database version theme registry is used.
For maintenance-page to work in off-line mode,
theme()cannot be called ininit(). A lot of things may need to use theme hook in init. Especially consider that fact that site off-line need to work normally for admin. So this restriction may not be reasonable. If we addthe whole problem is solved.
Comment #16
dvessel commentedI would think about why you're calling a theme function so early. It causes other problems like throwing off the block configuration page and possibly others so it shouldn't be done. And the line to include the file may fix it but it's out of place. What does building the theme registry have to do with including the maintenance file?
I'm sorry but I think it's more of a problem with your module ATM due to the other problems with initializing the theme system so early. Unless Drupal can initialize the theme very early with no consequence, I see little point in fixing it here.
Comment #17
mattyoung commentedThe api page does not indicate any restriction: http://api.drupal.org/api/function/hook_init/6. It says "For example, this hook is a typical place for modules to add CSS or JS that should be present on every page." Adding css affects the look so
theme()function should be used to allow theme to override. hook_init() is called at the very end of bootstrap, I can't see it have any limitation on what it can do. But if there really is some limitation, then hook_init() should indicate this clearly and Drupal need another hook, say a 'prepagecallback' hook:>It causes other problems like throwing off the block configuration page and possibly others so it shouldn't be done.
I don't see any problem with the block configure page. In fact I'm writing a custom block right now and I have been using the block configure screen very often and encounter no problem. Can you point me to the code in the block configure screen where the problem is?
>What does building the theme registry have to do with including the maintenance file?
It's a combination of two things. Since theme got initialize in hook_init, the global $theme variable is set. So in here:
you cut out early and don't go on to build the special maintenance page theme registry from scratch in memory. So the database cache version is used. In order the get the 'template_preprocess_maintenance_page()' in included as 'maintenance_page' template preprocess function, the function 'template_preprocess_maintenance_page()' must be defined at the time when the registry is build. Therefore, by including theme.maintenance.inc at the top of:
make the 'template_preprocess_maintenance_page()' defined so the normal theme registry will have the preprocess function for maintenance_page.
Anyway, I don't think this fix is a good idea because you want to handle off-line page using your special logic
_drupal_maintenance_theme(). What you can do is this:this way, hook_init() can touch
theme()and you still get to make your own maintenance_page theme registry.Can you take a look at this other thing I reported: http://drupal.org/node/374651
Comment #18
dvessel commentedHere the issues I'm aware of:
#219756: blocks cannot be configure if administration theme used
#219846: breaks blocks editor if administrative theme used
#219910: Calling theme function from hook_init() interferes with administration theme
Adding styles and scripts are not handled the same way as calling a theme functions in Drupal so your assumptions about treating them the same doesn't work out. The docs do need to be updated for hook_init() or a lot of the bootstrap process has to be reorganized.
Comment #19
dave reid"Adding css affects the look so theme() function should be used to allow theme to override."
Yes, you can add CSS and JS in hook_init(), but they are not actually processed until the page is rendered at the end of the request. If you call a theme function in init(), it loads the theme registry immediately. There's a big difference. Maybe we should document this in hook_init()?
Comment #20
mattyoung commented>There's a big difference. Maybe we should document this in hook_init()?
Yes, document this. Maybe even add a flag to indicate bootstrap happening so
theme()can check for this flag, put itself in "no-can-do" mode and log a message/blow itself up to tell whoever call it to stop that. This flag should be clear after bootstrap_full() so theme() can operate normally.If
theme()cannot be called inhook_init(), then how does one allow theme to override css for the css added inhook_init()? SOL?Seeing how others have running into this problem, I think another hook just prior to page handler would solve this problem. Some thing like this:
Comment #21
benthroop commentedWe've run into this same problem where the maintenance mode ends up building the page as all white with plain black text. I"m posting here because it seems to be the same symptom, if not the same cause.
In our case Drupal is actually using the proper theme (ours is based off of Acquia_Marina), but none of the theme PHP variables are filled in. So the entire page looks like this:
The really weird part is that no matter what we change the maintenance theme to in setting.php, it uses this page. I've even made edits to it and they are properly shown. Just can't get it to look at anything else or to fill in the vars.
FWIW, we have this same setup working on a different server and this just started happening after we migrated (successfully except for this) to another server. This is in D6.8
Is there anywhere else in Drupal that you can set the maintenance theme?
Has anyone else run into this?
Comment #22
benthroop commentedI've verified that this is a DB issue. Cloning the DB from the working server to the new one makes it work fine on the new server.
So I'm cloning the DB and will play with it until I get the maintenance page to show. FUN! Hopefully documenting this will help someone else.
Comment #23
mattyoung commentedSomething initialized theme during bootstrap. That's why you get empty maintenance-page theme variables. Most likely some init hook did it.
Find out if this is happening to you. If you have access to a debugger, put a breakpoint in
init_theme()and see if it's called during bootstrap init hook phase.If you don't have access to a debugger, use devel module, go to 'devel/php' and execute this:
dpm(module_implements('init'));This will show you a list of modules that implements
hook_init(), look into each non-core module'shook_init()and see if any of them causeinit_theme()to be called like callingtheme(),drupal_render_form()etc. If you find any, that is the problem.>Is there anywhere else in Drupal that you can set the maintenance theme?
Nope. The variable 'maintenance_theme' is it. But if theme system is initialized during bootstrap, all the logic in
_drupal_maintenance_theme()is by-passed. You end up empty theme variable. Also the maintenanc-page.tpl.php is from your regular theme, if one is not is define there, the one in system module is used. The variable 'maintenance_theme' is totally ignored. Whatever you set in settings.php $conf['maintenance_page'] doesn't matter.Find out who is messing with theme during bootstrap and you will find the problem.
Comment #24
benthroop commentedmattyoung, if I ever meet you, beer's on me. Thanks!
That line of PHP gave me a list of 25 modules and the culprit turned out to be the Rules Module dev release. One rule that we had was running on Page View, and turning that off fixed the issue. I'll log an issue with those guys.
Comment #25
axel pressbutton commentedHi, I'm subscribing to this thread as I'm having the same problems.
I had a list of 20 modules returned (see attached list in screenshot) but am not sure what I should do next to eliminate each of them...is it a case of disabling modules one at a time or do I search the code for something? If I need to search the code, what exactly am I looking for and where?
I disabled the Rules module (see previous post, #24) but still had the same issues.
Thanks in advance for any help :)
Comment #26
mattyoung commentedopen 'includes/common.inc', go to line: 2544 and comment this line out:
then browse your site normally and you should see a stack trace. that'll tell show you which module call theme. If it originates from some init() hook, then you found the problem.
Comment #27
axel pressbutton commentedThanks for the reply mattyoung,
I've tried your suggestion but get the following error as soon as I refresh the page with the site in 'online mode'...
Fatal error: Call to undefined function theme() in C:\xampp\htdocs\drupal6\includes\common.inc on line 2871
Line 2871 contained in 2869 - 2873;
Just to note, I'm using Drupal 6.10 and a Custom theme based on the Basic theme.
Hope this is of some use.
Comment #28
mattyoung commentedIt should have printed out a stack trace. I guess your php version doesn't do this.
try this: insert this in the beginning of init_theme() in line 31 of includes/theme.inc:
access your site and see what it print out.
Comment #29
axel pressbutton commentedThanks,
I've now included that code and get the following list on the homepage...
Not sure if this points the finger at anything or not? Not exactly sure what's going on with "node_page_view() at in "
Both XAMPP and my remote server show the PHP version as being 5.2.6
Comment #30
mattyoung commentedWell, this mean nothing during bootstrap call init_theme(). So it's something else is messing up mainenace-page.
Looks like you are running this with the site online normally. Try to put the site off-line first, then run the code and see what it print out.
What you do is comment out the code you added int init_theme(). Put you site off-line. uncomment the code in init_theme(), access your site and see what it print out.
Comment #31
axel pressbutton commentedSorry, i did that before but had the same error message...my fault, i needed to clear the cache so i could see the site from a non-logged in perspective in IE6. Being logged in as super admin in Firefox obviously also returns the same list as previous
The list is reduced to 3 items...
and I'm guessing that this looks all OK :(
Comment #32
mattyoung commentedEverything looks normal. I don't know what can be wrong.
What does the maintenance-page actually looks like? Do a view source and paste the content here and see.
Comment #33
axel pressbutton commentedI've tried this with Lightbox2 switched off for this page as well...just in case
Comment #34
mattyoung commentedI don't see anything wrong with the page itself. But I don't see any theme settings. That error message indicates there is something wrong with the theme. The theme is somehow broken. What do you have 'maintenance_theme' variable set to? This is the one you set in settings.php like this:
try 'minnelli'.
Anyway, there is nothing wrong with the maintenance-page. The problem is your theme.
Comment #35
axel pressbutton commentedmy theme lives in /sites/all/themes/zodbod/.
I tried minnelli as you suggested and it worked, along with all of the other themes that live in /themes/.
As settings.php suggested, I've copied the template for the offline message from /modules/system/maintenance-page.tpl.php into my theme and it has no effect. I've also just made a copy of page.tpl.php and renamed it to maintenance-page.tpl.php and that didn't work.
Do these only work if they live in the main /themes/ dir?
Comment #36
mattyoung commentedSomething is wrong with your theme and you need to debug it. Your theme is probably not even working correctly for normal operation.
What does zodbod.info looks like?
when you render a normal page like the home page, what does the page source look like?
>I've copied the template for the offline message from /modules/system/maintenance-page.tpl.php
This is not strictly necessary unless you need to modify that template. The theme system falls back to the system copy if one is not defined in the maintenance_theme.
>Do these only work if they live in the main /themes/ dir?
No, any theme can be used and they can reside in any usual locations: /themes, /site/all/themes, /sites/www.SITENAME.XXX/themes. There is nothing special about maintenance theme.
Again, something is wrong with your theme. This problem has nothing to do with maintenance-page.
Comment #37
axel pressbutton commentedMany thanks for your ongoing advice mattyoung.
I think you may have hit something here....I've just had a look and noticed that the .info is still labelled as the original theme name that it was based on but with modifications within that (Not sure if it needed to be renamed....I'm guessing it did :( ).
My .inf file is currently called basic.info, NOT zodbod.info - the site works ok BUT if i then change the name to zodbod.info and clear my cache the site then breaks completely...i'm guessing that the name is being referenced in the db somewhere?
Sorry, forgot to add the code...there's a lot of it there compared to the standard .info files though i must admit
Comment #38
mrfelton commented2 modules that are offenders of calling theme related functions are textsize and pagestyle which both call path_to_theme() in hook_init():
I will lodge a bug report in their issue queues now.
Comment #39
mattyoung commentedI reported this as a bug that core should not allow: #405578: Need to prohibit hook_init() from initializing theme system: just not allow hook_init() to touch theme and problem solve.
Comment #40
David_Rothstein commentedThis is still an issue in Drupal 7, and there, we ought to be able to fix it. The relevant part of the theme system has been completely refactored in #553944: Define hook_menu_get_item_alter() as a reliable hook that runs before the page is doomed so that now, all the other issues with calling theme functions in hook_init() are solved, and this seems to be the only one remaining.
(Actually, right at the moment calling theme functions from hook_init leads to a white screen, but that is a temporary condition - applying the patch at #592008-24: Don't save theme registry before modules are included fixes that.)
I think the issue with the site offline theming is possible to fix for Drupal 7.
Comment #41
wibbsy commentedOn my offline page, the layout and content (i.e. the images) are the same as online, the only thing that doesn't carry over from the "online" theme is the colour scheme? The above new funcitons in template.php don;t make a difference either?
Comment #42
mlncn commentedNote that elements of this issue appear to stem from #341140: drupal_get_filename() when database is down, does not deal with phptemplate themes which is fixed in 7 now but not yet in 6.
benjamin, agaric
Comment #43
heather commentedIs this a feature request for D8 rather than a bug for D7?
See related issues:
#421062: Maintenance theme is ugly and cannot be altered
Just tested, and yes, if Garland or Bartik are the default theme, and any color changes have been set- they don't display in offline mode.
Bartik gets around this by showing a plain maintenance-page.tpl.php with no styling, hiding the color.
In both cases below, I set the color module with some custom colors:
See Garland:
See Bartik:
Comment #44
mrfelton commentedRelated issue - #1742756: Hardcoded preprocess css or js breaks the maintenance page
Comment #45
pasqualleI don't see any remaining issues here