regions.module in Regions 6
Same filename and directory in other branches
Add regions to the screen that are cross-theme compliant
File
regions.moduleView source
<?php
/**
* @file
* Add regions to the screen that are cross-theme compliant
*/
/**
* Implementation of hook_help().
*/
function regions_help($path, $arg) {
if ($path == 'admin/help#regions') {
return '<p>' . t('Regions adds regions that are cross theme compliant. This way you can add blocks to any number of areas of the screen without having to define them in your themes.') . '</p>';
}
}
/**
* Implementation of hook_perm().
*/
function regions_perm() {
$regions = _regions_list();
// Generate a list of regions and permissions.
foreach (array_keys($regions) as $region_name) {
$perms[] = 'view ' . $region_name . ' region';
}
return $perms;
}
/**
* Implementation of hook_init().
*/
function regions_init() {
// Check for current theme.
init_theme();
global $theme_key;
$regions = _regions_list($theme_key);
foreach ($regions as $region_info) {
// Add optional js files if defined.
if (isset($region_info['js'])) {
drupal_add_js($region_info['js']);
}
// Add optional stylesheets if defined.
if (isset($region_info['css'])) {
drupal_add_css($region_info['css']);
}
}
}
/**
* Implementation of hook_footer().
*
* @todo consider implementing drupal_set_content() so we can use theme_blocks()
*
* @todo for D7 use hook_page_alter().
*/
function regions_footer($main = 0) {
// Check for current theme.
init_theme();
global $theme_key;
$regions = _regions_list($theme_key);
// Regions the user has access to are added the end of the site.
$output = '';
foreach ($regions as $region_name => $region_info) {
// Check for access to regions.
if (user_access('view ' . $region_name . ' region')) {
$region = array();
// Get themed blocks string.
$blocks = _regions_blocks($region_name, $region_info);
if (isset($blocks)) {
$region['start'] = '<div id="' . $region_name . '" class="regions">';
$region['blocks'] .= $blocks;
$region['end'] .= '</div>';
}
// Allow other modules to alter the region array before the each element
// is concatenated into a single HTML string.
drupal_alter('regions_region', $region, $region_name);
$output .= !empty($region) ? implode('', $region) : NULL;
}
}
return $output;
}
/**
* Implementation of hook_system_info_alter().
*/
function regions_system_info_alter(&$info, $file) {
if (isset($info['regions'])) {
$list = module_invoke_all('define_regions');
// Add the regions into the definition typically only provided by the theme
// layer.
if (count($list) > 0) {
$info['original_regions'] = $info['regions'];
}
foreach ($list as $machine_name => $region) {
$info['regions'] += array(
$machine_name => $region['title'],
);
}
}
}
/**
* Helper function lists newly defined regions against regions already declared by a theme.
*
* @param $theme_key
* A theme key to check against. Defaults to current theme.
*
* @return
* An array keyed by region identifier, containing:
* - title: the region title
* - css: optional path to stylesheet for theming the new region, relative to
* implementing module directory.
* - js: optional path to javascript file, relative to implementing module
* directory.
* - render_callback: optional function to use in rendering blocks of this
* region (will be passed 'block' and $block parameters).
* Or an empty array.
*/
function _regions_list($theme_key = NULL) {
if (!isset($theme_key)) {
init_theme();
global $theme_key;
}
// Tap the stored info file for the original_regions variable.
$info = unserialize(db_result(db_query("SELECT info FROM {system} WHERE type = 'theme' AND name = '%s'", $theme_key)));
if (isset($info['original_regions'])) {
$theme_regions = array_map('t', $info['original_regions']);
}
else {
$theme_regions = array_map('t', $info['regions']);
}
// Allow modules to define new regions.
$defined_regions = module_invoke_all('define_regions');
// Build an array of new regions, if defined ones don't already exist.
$new_regions = array();
if (!empty($defined_regions)) {
foreach ($defined_regions as $key => $value) {
if (!in_array($key, array_keys($theme_regions))) {
$new_regions[$key] = $value;
}
}
}
return $new_regions;
}
/**
* Helper function to get a list of blocks per region, as provided by core block and context modules.
*
* @param string $region_name
* The region identifier.
* @param array $region_info
* An individual element child of the array returned by _regions_list().
*
* @return
* A string containing the rendered blocks for this region.
*
* @see _regions_list()
* @see regions_footer()
*/
function _regions_blocks($region_name, $region_info) {
// Update the {blocks} table with the blocks currently exported by modules.
_block_rehash();
$blocks = array();
if (module_exists('context') && function_exists('context_get_plugin')) {
$blocks = context_get_plugin('reaction', 'block')
->block_list($region_name);
}
else {
$blocks = block_list($region_name);
}
// Allow other modules to alter the blocks array before the each block object
// is rendered by theme_block().
drupal_alter('regions_blocks', $blocks, $region_name);
// Render the array of blocks using either an optional module-provided
// callback, or the default theme('block', $block).
$render_callback = isset($region_info['render_callback']) && function_exists($region_info['render_callback']) ? $region_info['render_callback'] : 'theme';
$output = '';
foreach ($blocks as $block) {
$output .= call_user_func_array($render_callback, array(
'block',
$block,
));
}
return $output;
}
/**
* Implementation of hook_theme_registry_alter().
*/
function regions_theme_registry_alter(&$theme_registry) {
// Remove any existing instances of our pre page preprocessor.
$position = array_search('regions_preprocess_pre_page', $theme_registry['page']['preprocess functions']);
if ($position !== FALSE) {
unset($theme_registry['page']['preprocess functions'][$position]);
}
// Add an additional page preprocess function prior to template_preprocess_page()
$position = array_search('template_preprocess_page', $theme_registry['page']['preprocess functions']);
if ($position !== FALSE) {
array_splice($theme_registry['page']['preprocess functions'], $position, 0, 'regions_preprocess_pre_page');
}
}
/**
* Preprocessor that runs *before* template_preprocess_page().
*/
function regions_preprocess_pre_page(&$vars) {
// stub for now
}
/**
* Implementation of hook_preprocess_page().
*/
function regions_preprocess_page(&$vars) {
global $theme_key;
$regions = _regions_list($theme_key);
foreach ($regions as $region_name => $region_info) {
// Check for access to regions.
if (user_access('view ' . $region_name . ' region')) {
$vars['body_classes'] .= " bclass_enabled_{$region_name} ";
}
}
}
Functions
Name![]() |
Description |
---|---|
regions_footer | Implementation of hook_footer(). |
regions_help | Implementation of hook_help(). |
regions_init | Implementation of hook_init(). |
regions_perm | Implementation of hook_perm(). |
regions_preprocess_page | Implementation of hook_preprocess_page(). |
regions_preprocess_pre_page | Preprocessor that runs *before* template_preprocess_page(). |
regions_system_info_alter | Implementation of hook_system_info_alter(). |
regions_theme_registry_alter | Implementation of hook_theme_registry_alter(). |
_regions_blocks | Helper function to get a list of blocks per region, as provided by core block and context modules. |
_regions_list | Helper function lists newly defined regions against regions already declared by a theme. |