Print a block directly from a theme
Completely revised and updated: print a block directly in a theme or page the Agaric way
Print block directly in a theme with its title
The approach taken here combines that of Panels module's content_types block submodule (relevant code below) and something factored out of block_list. The problem is that Drupal only expects blocks to be printed by regions, and provides no generic function for printing them. Thus, for most blocks this still works with Panels or basic direct printing techniques, but custom titles set in admin/build/blocks will be lost. And for completely custom blocks, having to hardcode titles would defeat the purpose of allowing administrators to edit certain content as a block at all. A generic function to do this is what Agaric tries to provide here.
(My reaction on learning this: "Only content and subject - http://api.drupal.org/api/function/hook_block/5
and subject/title isn't even provided for core custom blocks!!!!!!!!")
How Panels deals with it (answer-- it doesn't fully. Block titles do not transfer from the block admin page to the panel implementation, but you can set your own titles to override any block.
<?php
/**
* Output function for the 'block' content type. Outputs a block
* based on the module and delta supplied in the configuration.
// from Panels
*/
function panels_content_block($conf) {
$block = (object) module_invoke($conf['module'], 'block', 'view', $conf['delta']);
$block->module = $conf['module'];
$block->delta = $conf['delta'];
if ($conf['override_title']) {
$block->subject = check_plain($conf['override_title_text']);
}
// Test for block visibility
$result = db_query("SELECT pages, visibility FROM {blocks} WHERE module = '%s' AND delta = %d", $block->module, $block->delta);
$block_visibility = db_fetch_object($result);
if ($block_visibility && $block_visibility->pages) {
if ($block_visibility->visibility < 2) {
$path = drupal_get_path_alias($_GET['q']);
$regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($block->pages, '/')) .')$/';
$page_match = !($block->visibility xor preg_match($regexp, $path));
} else {
$page_match = drupal_eval($block->pages);
}
} else {
$page_match = TRUE;
}
if ($page_match) {
return theme('block', $block);
}
}
?>
The block table:
Full Texts module delta theme status weight region custom throttle visibility pages title
Edit views image_latest chameleon 0 0 left 0 0 0
Edit views image_random chameleon 0 0 left 0 0 0
Edit views send_most_emailed chameleon 0 0 left 0 0 0
Edit views send_recently_emailed chameleon 0 0 left 0 0 0
Edit block 10 sky 0 0 0 0 1 node/1
Edit block 27 sky 0 0 0 0 1 <front>
Edit block 31 sky 0 0 0 0 1 taxonomy/term/14
Edit block 41 sky 0 0 left 0 0 0 Download our toolbar!
Edit block 42 sky 0 0 left 0 0 0 Buy our necklace
Edit block 40 sky 0 0 left 0 0 0 Be a Catalyst for the Cure
Edit block 17 sky 0 1 0 0 1 node/add/story
<?php
global $user; if ($user->uid == 1) drupal_set_message('<pre>'. var_export($block,TRUE) .'</pre>');
?>
#
stdClass::__set_state(array(
'module' => 'block',
'delta' => '41',
'theme' => 'sky',
'status' => '0',
'weight' => '0',
'region' => 'left',
'custom' => '0',
'throttle' => '0',
'visibility' => '0',
'pages' => '',
'title' => 'Agaric example block title set at admin/build/block!',
))
#
stdClass::__set_state(array(
'content' => '
Agaric example block content here, also set at admin/build/block.
',
))
Alternate and simpler, but won't get titles for block.module defined (custom) blocks, implementations here: http://drupal.org/node/161443
Make sure to change the module (the optional 'module' => 'block' definition) and the delta (25 in our block module shortcut method) to whatever correctly identifies the block you want to see. An easy way to find out this info is to go to your block admin page and point at the configure link for the block you want to use.
Extra trick: Provide edit links to block and view blocks for admin users.
Resolution
<?php
/**
* Output function for the 'block' content type. Outputs a block
* based on the module and delta supplied in the configuration.
*
* module_invoke block only gets what is defined by hook_block
* the block module itself provides ONLY CONTENT for this hook
*/
function agaric_block_output($conf) {
if (!is_array($conf)) {
$conf = array('delta' => $conf);
}
if (!isset($conf['module'])) {
$conf['module'] = 'block';
}
$result = db_query("SELECT b.* FROM {blocks} b WHERE b.module = '%s' AND b.delta = '%s'", $conf['module'], $conf['delta']);
$block = db_fetch_object($result);
$array = module_invoke($conf['module'], 'block', 'view', $conf['delta']);
if (isset($array) && is_array($array)) {
foreach ($array as $k => $v) {
// anything defined in hook_block will override anything from block table
// we could add if (!isset($block->$k)) { .. } to have oppositen behavior
$block->$k = $v;
}
}
// get a subject for this block (and all block table data if we wanted)
if ($conf['override_title']) {
$block->subject = check_plain($conf['override_title_text']);
} elseif ($block->title) {
// Override default block title if a custom display title is present.
// Check plain here to allow module generated titles to keep any markup.
$block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
}
return theme('block', $block);
}
?>
Comments
Post new comment