Here's an idea I thought I would present. It seems like an obvious idea, but I haven't been able to find any prior discussions.
A theme can create a series of regions for placing blocks. Drupal gathers the blocks in each region and presents them to page.tpl.php, which then puts each set of blocks in the right place.
Some blocks only display when a single node is being displayed. My idea is to provide some sort of extension so that these blocks could also be displayed when viewing multiple nodes. In this case, the theming would occur in node.tpl.php and the system would collect one set of blocks per node being displayed (rather than one set per page).
Even if the system is uncooperative, it seems possible to do some form of this in node.tpl.php. The simplest approach is to just hardcode the block you want. For instance, if you wanted the block provided by the Related Links module, just call relatedlinks_block('view') from node.tpl.php and then theme the returned data.
Only one problem: relatedlinks_block() needs to know the node to use and it does this with this piece of code
if (arg(0) == 'node' && is_numeric(arg(1))) {
It checks if the URL address is for a node display. So before calling relatedlinks_block(), we need to fool the arg() function into returning fake parameters. The arg() function looks like this:
function arg($index) {
static $arguments, $q;
if (empty($arguments) || $q != $_GET['q']) {
$arguments = explode('/', $_GET['q']);
$q = $_GET['q'];
}
if (isset($arguments[$index])) {
return $arguments[$index];
}
}
So if we do something like this:
$get = $_GET['q'];
$_GET['q'] = 'node/' . $node->nid;
$block = (object)module_invoke('tagadelic', 'block', 'view', 0);
if ($block) {
$block->module = 'tagadelic';
$block->subject = null;
$block = theme('block', $block);
echo "<li>$block</li>";
}
$block = (object)module_invoke('relatedlinks', 'block', 'view', 3);
if ($block) {
$block->module = 'relatedlinks';
$block = theme('block', $block);
echo "<li>$block</li>";
}
$_GET['q'] = $get;
We should be able to fool the modules so as to get the blocks we want. I tried this; it fooled the tagadelic module well enough. The relatedlinks module doesn't expect the hook-block method to be called more than once per page and reports problems as it tries to create a temporary database table that it already created.
In any case, it would be nice to see this functionality provided directly by Drupal or by a Drupal extension. Ideally, it would be packaged as a special block region managed by the standard block settings controls.
What do people think? Is this useful or interesting? Is it possible as an extension or does it need to be in core Drupal? What are the pitfalls, performance or otherwise?
Comments
I agree. I have been going
I agree. I have been going through Drupal heavily with a debugger for over three months now and keep finding code in the core that is not able to be used in any other context besides the context in which it was originally designed.