Fri, 2008.03.14 - 22:13 — müzso
In Drupal 5 you can control the visibility of each block by specifying a rule (allow all except ..., allow only ..., or use user submitted PHP code to evaluate the pattern) and a pattern on the URL. However this does not only control the visibility (show or hide) of the block, but controls whether the block is rendered (ie. the code of the block executed) at all or not. Of course this means a huge difference in performance.
You'll find in various PHPTemplate themes that some regions are shown or hidden based on a few conditions. But at the time the PHPTemplate engine gets to the various page/block/node/etc. templates, these regions were already rendered and the code of all the blocks in them were already executed. This execution takes place in the block_list
Drupal function, right after the evaluation of the various visibility factors. Unfortunately there's no hook for themes to inject their own logic into visibility rules, so the only place to do this remains the blocks' visibility configuration which you can do only in Administration/Blocks. A hook would be nice so one can enable or disable blocks (or even regions) via generic rules. Eg. if I wanted to have some region visible only on node pages, then I've to put the "node/*" pattern in every block that I put in that region.
Comments
Region hiding
theme_regions()
hook implementation of my theme'stemplate.php
. Unfortunately this does not work either. I've now taken a closer look at theblock_list
function and found that it first queries all the blocks in the current theme and renders them (unless the block's visibility rules prohibit this of course) and fills up an internal static array with the rendered block contents. In the end (when all blocks are ready) it checks whether there're any blocks for the requested region (parameter of theblock_list
function) and returns them to the caller.It means
block_list
runs all the blocks regardless whether they'll be needed (aka. requested) or not. This is a huge performance killer imho. Of course you can avoid all this by adding block visibility rules to all blocks (a quite tedious job since the block administration form can get awkardly slow with a hundred blocks or so). Unfortunately neither the region, nor the block name are available to the block visibilty code you might add, so if you want your visibility rule to depend on the region of the block (eg. you want to hide a region alltogether under certain circumstances), then you've to hard-code the region name into the block visibility code.Re: region hiding
theme_blocks
function, which used to callblock_list
. We simply make a copy oftheme_blocks
(replacing "theme_" with our theme's name) andblock_list
and put them into ourtemplate.php
file.In our copy of
block_list
we've to add the region filtering to the query that gets the list of blocks. Replace this part:if (!count($blocks)) {
$rids = array_keys($user->roles);
$placeholders = implode(',', array_fill(0, count($rids), '%d'));
$result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN ($placeholders) OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", array_merge(array($theme_key), $rids));
(...)
}
With this:
if (!count($blocks)) {
$regionlist = array_keys(system_region_list($theme_key));
if (isset($regionlist) && count($regionlist) > 0) {
$regionsholder = "'" . implode("','", $regionlist) . "'";
$rids = array_keys($user->roles);
$placeholders = implode(',', array_fill(0, count($rids), '%d'));
$result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND b.region IN ($regionsholder) AND (r.rid IN ($placeholders) OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", array_merge(array($theme_key), $rids));
(...)
}
}
PS: this works for Drupal 5.7. In Drupal 6 regions are handled in a completely different way.
Region Assign
If interested please report your feedback to issue queue: http://drupal.org/project/issues/region_assign
Blessings!
Re: Region Assign
Re: Block visibility, block rendering and performance in Drupal5
Thanks
Thanks very much for sharing. It's really very helpful. I will try using this trick.
Regards,
Ravi Verma
Joomla
Some really helpful information here. I Like of your website design . Did you make this templete yourself or did you get it from any templetes websites? Looks pretty cool for me . I use Joomla but wants something better.
Re: Joomla
joomla developer
I'm looking for freelance joomla developer or web designer webdesign.
Installing the site and I need someone to add functions to some site.
If you are interested thank you kindly send us an email.
Re: joomla developer
Drupal5 is so amazing