Investigating this issue with killes and heine: http://drupal.org/node/231587 we discovered that there is a bug back to 5.x at least. On a page not found, we don't want to render the left and right sidebars to reduce server load. However, block_list() will always be called (for example to find blocks in the footer or content regions).

This ruins the attempt to improve performance, since block_list() renders ALL blocks the first time it is called.

Comments

pwolanin’s picture

Status: Active » Needs review
StatusFileSize
new1.52 KB

patch should apply to both HEAD and 6.x

moshe weitzman’s picture

I always assumed that if $show_blocks is FALSE, then no blocks would render into any region. we can't change that behavior for D5 or D6, but we might want to consider that for D7.

killes@www.drop.org’s picture

block_list doesn't have a $show_blocks parameter.

pwolanin's patch looks harmless to me. Actually, it doesn't seem to change anything, left and right sidebar regions aren't with and without the patch for me.

pwolanin’s picture

@moshe - this is a bug, since other parts of Drupal only expect the blocks to be rendered if you call that specific region. It's not an API change, since the exact same output is returned for any call to block_list(). The only change is to what is stored in the static var at any given moment.

floretan’s picture

StatusFileSize
new5.08 KB

This patch works as expected, but I see it as a good candidate for some refactoring in order to do some unit testing on it.

The patch makes a clear distinction between loading block information and rendering blocks. Here's another version of this patch that refactors block_list() into the private functions _block_load_blocks() and _block_render_blocks().

The patch isn't pretty because of the code being moved around, but it's necessary if we want to test the case for which this issue was originally written.

catch’s picture

Status: Needs review » Needs work

flobruit: thanks for the patch, however it's not in unified diff format. Please see http://drupal.org/patch for more.

floretan’s picture

Status: Needs work » Needs review
StatusFileSize
new5.52 KB

catch: thank you for the note, that was my bad. Here's the patch in the correct format.

pwolanin’s picture

StatusFileSize
new5.85 KB

I like the general idea, but I'm not sure about altering the array by-ref. How about this - also perhaps easier to test too.

floretan’s picture

Status: Needs review » Reviewed & tested by the community

pwolanin, I agree with you on the by-ref, and in this case passing only the blocks for the desired regions makes a lot of sense.

There are no test cases for the block module yet. I started writing some, but in order to automatically test the current issue I need to be able to make a call to _block_render_blocks() on a "page not found" which turns out to be a little tricky. I'll create a separate issue to create tests for block.module so that this patch can be committed.

dries’s picture

The code and approach look good but can we rename $block_region back to $blocks -- it's more consistent with the rest of Drupal's coding style.

I'm left wondering if we can further "clean up" this functionality and its APIs. Like, would it make sense to load blocks on a per-region basis instead of loading all regions at once. Specifically, I have a website where I have a custom block region which is only used on the main page of the site (i.e. only the main page has one or two blocks assigned to that region). Given a good set of APIs, I might be able to optimize my theme not to load a list of redundant blocks. I'm not sure it would buy me a significant performance gain but I figured I'd bring up a potential use case.

pwolanin’s picture

@Dries - I considered that, but thought is would be confusing if in the parent function we have an array $blocks and in the called function we would also have $blocks which is just one element of the array from the parent function. So essentially, $blocks_region == $blocks[$region] which seemed to be more clear about what's happening.

pwolanin’s picture

how about $region_blocks rather than $blocks_region?

pwolanin’s picture

StatusFileSize
new5.89 KB

re-rolled as $region_blocks

dries’s picture

Status: Reviewed & tested by the community » Fixed

OK, I reviewed this once more and it looks good. I still think there is room for improvement but this is probably the most important step, and we can bolt incremental improvements on top of this.

dries’s picture

OK, I reviewed this once more and it looks good. I still think there is room for improvement but this is probably the most important step, and we can bolt incremental improvements on top of this.

pwolanin’s picture

Version: 7.x-dev » 6.x-dev
Status: Fixed » Reviewed & tested by the community

same patch should apply for 6.x; 5.x will need a different patch.

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

This refactoring patch looks a bit scary to apply to Drupal 6 without much testing and although it does not modify any APIs, it does rework quite some amount of code. I'd prefer to have a more limited changeset to work with, which is easier to verify, review and test.

floretan’s picture

Status: Needs work » Needs review

The patch from #1 came before the refactoring but was already fully functional. It still applies to 6.x-dev and works as expected.

pwolanin’s picture

@flobruit - yes, good idea, though probably #1 should be rerolled a little to match where possible the code that went in 7.x. Probably just 1 or 2 lines to change.

pwolanin’s picture

StatusFileSize
new1.5 KB

minor changes made (see $key) - applies cleanly to 6.x and seems to work fine.

floretan’s picture

Status: Needs review » Reviewed & tested by the community

Does indeed apply cleanly to 6.x and works fine.

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

Walked through this patch line by line and it looks to be all-good. Thanks, committed to 6.x. (Dries already committed to 7.x, so this makes this one fixed).

pwolanin’s picture

Version: 6.x-dev » 5.x-dev
Status: Fixed » Patch (to be ported)

great - now we need to backport similar changes to 5.x, where this is still a bug.

Freso’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new1.51 KB

This is a straight(!) patch from the one in comment #20. Not tested.

drumm’s picture

Status: Needs review » Fixed

Committed to 5.x.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

schuyler1d’s picture

Status: Closed (fixed) » Needs review

In 5.x this caused a regression, and doesn't even work, because the blocks are all called explicitly in _phptemplate_default_variables(). See the patch/comment at http://drupal.org/node/281042#comment-916600 for a fix to this problem that will work.

It's in phptemplate.engine instead of block.module, because $show_headers is available there, so that's where the logic should be anyway.

snufkin’s picture

Status: Needs review » Active

this patch breaks drupal_add_js (at least thats what we managed to reproduce) from blocks

schuyler1d’s picture

Can you be more explicit about which patch you're talking about. The patch at:
http://drupal.org/node/281042#comment-921255 (http://drupal.org/files/issues/fix_block_loading_on_404-v3.patch)
should probably be applied with
http://drupal.org/files/issues/block_regression_fix.patch
since the block_list change is ineffective (and breaks an assumption in theme_page() ), but I believe it's arbitrary.

If it's my patch, where is your drupal_add_js() getting called from? All of my drupal_add_js() calls in modules and blocks are working.

schuyler1d’s picture

Status: Active » Needs review
snufkin’s picture

I meant the patch that got committed into 5.8. I probably didn't read your comment in #27 properly, we're talking about the same thing. I just wanted to stress that with this stock drupal 5.8 blocks might be broken.

Your patch on http://drupal.org/node/281042#comment-916613 does provide a fix.

drumm’s picture

Status: Needs review » Closed (fixed)

Setting this back to closed, there is another issue where the work is being done.

owen barton’s picture

Status: Closed (fixed) » Active

Considering that this patch caused several problems, which were attempted to be fixed by http://drupal.org/node/281042 - which caused further problems, I am wondering if this is the right direction - is there a less intrusive way to disable block rendering for 404 pages only or (perhaps simpler, especially for a stable core) could this simply be done in contrib with a module that loads the requested content in hook_init and does print theme('page', $output, FALSE)?

drumm’s picture

Maybe just revert it all.

drumm’s picture

Status: Active » Closed (fixed)

Further updates on this are in #281042: regression in 5.8 from 5.7 theme('blocks','all') broken - so no header alteration possible. I suspect the remaining problems are isolated and sometimes caused by not using updated versions of various modules.