$custom_theme when does it take effect... when does it not
I notice a bug in D6.4 and CVS in the block module. This post, however, is not to report the bug (i will use bug tracker for that). This post is to ask a development question that will help me create a patch for the issue. On our website we use different themes for different sections of the site. As the user browses to different sections of the site, the theme is changed automatically by changing $custom_theme global in hook_init(). Bug background: The bug occurs when administering blocks. For example, if my current active theme is foo_theme and I click admin/build/block/list/bar_theme a list of blocks for bar_theme is not displayed. Instead, a list of blocks for the active theme foo_theme is displayed. When the user clicks the link "Bar theme" they could reasonably expect that a list of the blocks for bar_theme should display. The development question: I think the bug has something to do with the code in the block module function block_admin_display(). In this function the author of the code tries to display a list of blocks for the theme the user selected by changing the global variable $custom_theme. The problem with this approach is that outside of hook_init() I have found that changing $custom_theme variable has no effect on changing the active theme. Have others found this to be the case that changes to $custom_theme variable have no effect on changing the active theme outside of hook_init()? If this is the case then we need to rethink how we are pulling the list of blocks in the block module admin. Thanks Jon
Jon Saints wrote:
I notice a bug in D6.4 and CVS in the block module. This post, however, is not to report the bug (i will use bug tracker for that). This post is to ask a development question that will help me create a patch for the issue.
On our website we use different themes for different sections of the site. As the user browses to different sections of the site, the theme is changed automatically by changing $custom_theme global in hook_init().
Bug background: The bug occurs when administering blocks. For example, if my current active theme is foo_theme and I click admin/build/block/list/bar_theme a list of blocks for bar_theme is not displayed. Instead, a list of blocks for the active theme foo_theme is displayed. When the user clicks the link "Bar theme" they could reasonably expect that a list of the blocks for bar_theme should display.
The development question: I think the bug has something to do with the code in the block module function block_admin_display(). In this function the author of the code tries to display a list of blocks for the theme the user selected by changing the global variable $custom_theme. The problem with this approach is that outside of hook_init() I have found that changing $custom_theme variable has no effect on changing the active theme.
Have others found this to be the case that changes to $custom_theme variable have no effect on changing the active theme outside of hook_init()?
If this is the case then we need to rethink how we are pulling the list of blocks in the block module admin.
Thanks Jon
$custom_theme takes effect as soon as init_theme() is run. The later in the page that you set it, the more likely that init_theme() will already have run. That makes it definitely work best inside hook_init(), but often later is ok, as long as some module isn't calling theme(...) very early. Calling theme() functions in hook_init(), for example, could be very bad as it can destroy $custom_theme setting.
As Earl points out, $custom_theme only has effect before init_theme() is run. Afterward, it's too late. So when you set $custom_theme you had better be sure no code has called theme(...) yet. You can check with: global $theme; if (isset($theme)) { // too late to set $custom_theme. } And look out for modules that set $custom_theme without checking first whether some other module has set it. (I won't name names, but initials are "og") So if you want to set the custom theme and make sure noone overrides it, call theme(...) right after you set $custom_theme. -Dave On Thursday 14 August 2008, Earl Miles wrote:
$custom_theme takes effect as soon as init_theme() is run. [snip] ... as long as some module isn't calling theme(...) ...
On our website we use different themes for different sections of the site. As the user browses to different sections of the site, the theme is changed automatically by changing $custom_theme global in hook_init().
If you're doing this in with custom code, you should give http://drupal.org/project/sections a try. The module has been thoroughly tested and works AFAIK. Similar, but different purpose is http://drupal.org/project/switchtheme.
The development question: I think the bug has something to do with the code in the block module function block_admin_display(). In this function the author of the code tries to display a list of blocks for the theme the user selected by changing the global variable $custom_theme. The problem with this approach is that outside of hook_init() I have found that changing $custom_theme variable has no effect on changing the active theme.
You should not try to change the theme on block administration pages. Above mentioned modules implement exactly this exception. Thanks, Daniel
If you're doing this in with custom code, you should give http://drupal.org/project/sections a try. The module has been thoroughly tested and works AFAIK. Similar, but different purpose is http://drupal.org/project/switchtheme.
Thanks. I will check out these modules
You should not try to change the theme on block administration pages. Above mentioned modules implement exactly this exception.
As for the bug in the block module, I think there is actually a good reason that the author of the block module in core is trying (but not succeeding) to change the theme on block administration pages. As you to edit blocks for different themes in the block admin it helps to have the active theme change accordingly so that a user can see where on the page the block regions will be appearing. Different themes can have different arrangements of regions. The bug occurs when the block_admin_display() function changes $custom_theme variable and calls init_theme(). The global variable $theme has already been set by a previous init_theme() call somehwere in drupal so init_theme() is essentially ignored in block_admin_display(). The theme does not change. That is why we are seeing the wrong list of blocks appear for any theme that is not the active theme. So... how best to deal with this? Do we: 1) always show the current default theme when editing blocks for other themes (even though region arrangements might differ theme to theme) or 2) do we write a block_init() hook to change the theme each time a user chooses to edit blocks for a specific theme in the block admin. I wonder how this would affect users that choose to use the admin theme setting. Thoughts on this one? Thanks Jon
On Thursday 14 August 2008, Jon Saints wrote:
So... how best to deal with this?
Put something like print_r(debug_backtrace()) in your init_theme(), temporarily. Use that to determine what call is initializing the theme. If possible, change that code so that the theme is not initialized so soon.
Jon Saints wrote:
If you're doing this in with custom code, you should give http://drupal.org/project/sections a try. The module has been thoroughly tested and works AFAIK. Similar, but different purpose is http://drupal.org/project/switchtheme.
Thanks. I will check out these modules
You should not try to change the theme on block administration pages. Above mentioned modules implement exactly this exception.
As for the bug in the block module, I think there is actually a good reason that the author of the block module in core is trying (but not succeeding) to change the theme on block administration pages. As you to edit blocks for different themes in the block admin it helps to have the active theme change accordingly so that a user can see where on the page the block regions will be appearing. Different themes can have different arrangements of regions.
The bug occurs when the block_admin_display() function changes $custom_theme variable and calls init_theme(). The global variable $theme has already been set by a previous init_theme() call somehwere in drupal so init_theme() is essentially ignored in block_admin_display(). The theme does not change. That is why we are seeing the wrong list of blocks appear for any theme that is not the active theme.
So... how best to deal with this?
IMO this is not a bug in block module; it's a bug in whatever is calling theme() or init_theme() before block module has a chance to set custom_theme.
IMO this is not a bug in block module; it's a bug in whatever is calling theme() or init_theme() before block module has a chance to set custom_theme.
Interesting. I added var_dump(debug_backtrace()); exit(); to init_theme() after the if(isset($theme)) section and found that the first functiont that calls init_theme(). As best I can tell, system_init() (system.module around line 700) is the first function to call theme() function. It is the reason that the block module cannot change the theme later on. backtrace looks like this: init_theme() -> theme() -> system_init() -> call_user_func_array() -> module_invoke_all() -> _drupal_bootstrap_full() -> _drupal_bootstrap() -> drupal_bootstrap() I am not sure the problem is with system_init(). Shouldn't the block module just use a hook_init() instead? Thanks Jon
Jon Saints wrote:
IMO this is not a bug in block module; it's a bug in whatever is calling theme() or init_theme() before block module has a chance to set custom_theme.
Interesting. I added
var_dump(debug_backtrace()); exit();
to init_theme() after the if(isset($theme)) section and found that the first functiont that calls init_theme(). As best I can tell, system_init() (system.module around line 700) is the first function to call theme() function. It is the reason that the block module cannot change the theme later on.
backtrace looks like this: init_theme() -> theme() -> system_init() -> call_user_func_array() -> module_invoke_all() -> _drupal_bootstrap_full() -> _drupal_bootstrap() -> drupal_bootstrap()
I am not sure the problem is with system_init(). Shouldn't the block module just use a hook_init() instead?
Thanks Jon
Indeed, it appears that a theme() call was added in HEAD to init_theme(). To whomever added this: *THWAP* bad developer. No biscuit!
Indeed, it appears that a theme() call was added in HEAD to init_theme().
To whomever added this: *THWAP* bad developer. No biscuit!
Did you mean to say " Indeed, it appears that a theme() was added in HEAD to system_init()"? If so, what is the alternative to that theme() call in system_init()? These are the lines we need to change: // Emit the META tag in the HTML HEAD section theme('meta_generator_html', $version); // Emit the HTTP Header too theme('meta_generator_header', $version); I can change it and submit a patch. Thanks Jon
participants (4)
-
Daniel F. Kudwien -
Dave Cohen -
Earl Miles -
Jon Saints