blocklib: MDL-19010 add block and get_blocks methods

This commit is contained in:
tjhunt 2009-05-06 09:14:42 +00:00
parent 86b5ea0f85
commit 08eab89703
6 changed files with 571 additions and 60 deletions

View File

@ -91,7 +91,6 @@ if ($editing) {
// but I'm not sure if it's worth the complexity increase...
$pageblocks = blocks_get_by_page($PAGE);
}
$missingblocks = blocks_get_missing($PAGE, $pageblocks);
}
if (!empty($tagid)) {

View File

@ -55,21 +55,21 @@ require_once($CFG->libdir.'/pagelib.php');
* responsibility to ensure that those fields do not subsequently change.
*/
class block_manager {
/**#@+ Tracks the where we are in the generation of the page. */
const STATE_BLOCKS_NOT_LOADED = 0;
const STATE_BLOCKS_LOADED = 1;
/**#@-*/
/// Field declarations =========================================================
protected $loaded = self::STATE_BLOCKS_NOT_LOADED;
protected $page;
protected $regions = array();
protected $defaultregion;
protected $allblocks = null; // Will be get_records('blocks');
protected $addableblocks = null; // Will be a subset of $allblocks.
protected $blocksbyregion = null; // Will be an array region-name => array(block_instances);
/// Constructor ================================================================
/**
@ -101,6 +101,86 @@ class block_manager {
return $this->defaultregion;
}
/**
* The list of block types that may be added to this page.
* @return array block id => record from block table.
*/
public function get_addable_blocks() {
$this->check_is_loaded();
if (!is_null($this->addableblocks)) {
return $this->addableblocks;
}
// Lazy load.
$this->addableblocks = array();
$allblocks = blocks_get_record();
if (empty($allblocks)) {
return $this->addableblocks;
}
$pageformat = $page->pagetype;
foreach($allblocks as $block) {
if ($block->visible &&
($block->multiple || !$this->is_block_present($block->id)) &&
blocks_name_allowed_in_format($block->name, $pageformat)) {
$this->addableblocks[$block->id] = $block;
}
}
return $this->addableblocks;
}
public function is_block_present($blocktypeid) {
// TODO
}
/**
* @param string $blockname the name of ta type of block.
* @param boolean $includeinvisible if false (default) only check 'visible' blocks, that is, blocks enabled by the admin.
* @return boolean true if this block in installed.
*/
public function is_known_block_type($blockname, $includeinvisible = false) {
$blocks = $this->get_installed_blocks();
foreach ($blocks as $block) {
if ($block->name == $blockname && ($includeinvisible || $block->visible)) {
return true;
}
}
return false;
}
/**
* @param string $region a region name
* @return boolean true if this retion exists on this page.
*/
public function is_known_region($region) {
return array_key_exists($region, $this->regions);
}
/**
* @param $region a block region that exists on this page.
* @return array of block instances.
*/
public function get_blocks_for_region($region) {
$this->check_is_loaded();
$this->check_region_is_known($region);
return $this->blocksbyregion[$region];
}
/**
* Get the list of all installed blocks.
* @return array contents of the block table.
*/
public function get_installed_blocks() {
global $DB;
if (is_null($this->allblocks)) {
$this->allblocks = $DB->get_records('block');
}
return $this->allblocks;
}
/// Setter methods =============================================================
/**
@ -129,26 +209,191 @@ class block_manager {
*/
public function set_default_region($defaultregion) {
$this->check_not_yet_loaded();
if (!array_key_exists($defaultregion, $this->regions)) {
throw new coding_exception('Trying to set an unknown block region as the default.');
}
$this->check_region_is_known($defaultregion);
$this->defaultregion = $defaultregion;
}
/// Actions ====================================================================
/**
* This method actually loads the blocks for our page from the database.
*/
public function load_blocks($includeinvisible = NULL) {
global $DB;
$this->check_not_yet_loaded();
if (is_null($includeinvisible)) {
$includeinvisible = $this->page->user_is_editing();
}
if ($includeinvisible) {
$visiblecheck = 'AND (bp.visible = 1 OR bp.visible IS NULL)';
} else {
$visiblecheck = '';
}
$context = $this->page->context;
$contexttest = 'bi.contextid = :contextid2';
$parentcontextparams = array();
$parentcontextids = get_parent_contexts($context);
if ($parentcontextids) {
list($parentcontexttest, $parentcontextparams) =
$DB->get_in_or_equal($parentcontextids, SQL_PARAMS_NAMED, 'parentcontext0000');
$contexttest = "($contexttest OR (bi.showinsubcontexts = 1 AND bi.contextid $parentcontexttest))";
}
$pagetypepatterns = $this->matching_page_type_patterns($this->page->pagetype);
list($pagetypepatterntest, $pagetypepatternparams) =
$DB->get_in_or_equal($pagetypepatterns, SQL_PARAMS_NAMED, 'pagetypepatterntest0000');
$params = array(
'subpage1' => $this->page->subpage,
'subpage2' => $this->page->subpage,
'contextid1' => $context->id,
'contextid2' => $context->id,
'pagetype' => $this->page->pagetype,
);
$sql = "SELECT
bi.id,
bi.blockname,
bi.contextid,
bi.showinsubcontexts,
bi.pagetypepattern,
bi.subpagepattern,
bp.visible,
COALESCE(bp.region, bi.defaultregion) AS region,
COALESCE(bp.weight, bi.defaultweight) AS weight,
bi.configdata
FROM {block_instances} bi
JOIN {block} b ON bi.blockname = b.name
LEFT JOIN {block_positions} bp ON bp.blockinstanceid = bi.id
AND bp.contextid = :contextid1
AND bp.pagetype = :pagetype
AND bp.subpage = :subpage1
WHERE
$contexttest
AND bi.pagetypepattern $pagetypepatterntest
AND (bi.subpagepattern IS NULL OR bi.subpagepattern = :subpage2)
$visiblecheck
AND b.visible = 1
ORDER BY
COALESCE(bp.region, bi.defaultregion),
COALESCE(bp.weight, bi.defaultweight),
bi.id";
$blockinstances = $DB->get_recordset_sql($sql, $params + $parentcontextparams + $pagetypepatternparams);
$this->blocksbyregion = array();
foreach ($this->regions as $region => $notused) {
$this->blocksbyregion[$region] = array();
}
$unknown = array();
foreach ($blockinstances as $bi) {
if ($this->is_known_region($bi->region)) {
$this->blocksbyregion[$bi->region][] = $bi;
} else {
$unknown[] = $bi;
}
}
$this->blocksbyregion[$this->defaultregion] = array_merge($this->blocksbyregion[$this->defaultregion], $unknown);
}
/**
* Add a block to the current page, or related pages. The block is added to
* context $this->page->contextid. If $pagetypepattern $subpagepattern
* @param string $blockname The type of block to add.
* @param string $region the block region on this page to add the block to.
* @param integer $weight determines the order where this block appears in the region.
* @param boolean $showinsubcontexts whether this block appears in subcontexts, or just the current context.
* @param string|null $pagetypepattern which page types this block should appear on. Defaults to just the current page type.
* @param string|null $subpagepattern which subpage this block should appear on. NULL = any (the default), otherwise only the specified subpage.
*/
public function add_block($blockname, $region, $weight, $showinsubcontexts, $pagetypepattern = NULL, $subpagepattern = NULL) {
global $DB;
$this->check_known_block_type($blockname);
$this->check_region_is_known($region);
if (empty($pagetypepattern)) {
$pagetypepattern = $this->page->pagetype;
}
$blockinstance = new stdClass;
$blockinstance->blockname = $blockname;
$blockinstance->contextid = $this->page->context->id;
$blockinstance->showinsubcontexts = !empty($showinsubcontexts);
$blockinstance->pagetypepattern = $pagetypepattern;
$blockinstance->subpagepattern = $subpagepattern;
$blockinstance->defaultregion = $region;
$blockinstance->defaultweight = $weight;
$blockinstance->configdata = '';
$DB->insert_record('block_instances', $blockinstance);
}
/// Inner workings =============================================================
/**
* Given a specific page type, return all the page type patterns that might
* match it.
* @param string $pagetype for example 'course-view-weeks' or 'mod-quiz-view'.
* @return array an array of all the page type patterns that might match this page type.
*/
protected function matching_page_type_patterns($pagetype) {
$patterns = array($pagetype, '*');
$bits = explode('-', $pagetype);
if (count($bits) == 3 && $bits[0] == 'mod') {
if ($bits[2] == 'view') {
$patterns[] = 'mod-*-view';
} else if ($bits[2] == 'index') {
$patterns[] = 'mod-*-index';
}
}
while (count($bits) > 0) {
$patterns[] = implode('-', $bits) . '-*';
array_pop($bits);
}
return $patterns;
}
protected function check_not_yet_loaded() {
if ($this->loaded) {
if (!is_null($this->blocksbyregion)) {
throw new coding_exception('block_manager has already loaded the blocks, to it is too late to change things that might affect which blocks are visible.');
}
}
protected function mark_loaded() {
$this->loaded = self::STATE_BLOCKS_LOADED;
protected function check_is_loaded() {
if (is_null($this->blocksbyregion)) {
throw new coding_exception('block_manager has not yet loaded the blocks, to it is too soon to request the information you asked for.');
}
}
protected function check_known_block_type($blockname, $includeinvisible = false) {
if (!$this->is_known_block_type($blockname, $includeinvisible)) {
if ($this->is_known_block_type($blockname, true)) {
throw new coding_exception('Unknown block type ' . $blockname);
} else {
throw new coding_exception('Block type ' . $blockname . ' has been disabled by the administrator.');
}
}
}
protected function check_region_is_known($region) {
if (!$this->is_known_region($region)) {
throw new coding_exception('Trying to reference an unknown block region ' . $region);
}
}
}
//This function retrieves a method-defined property of a class WITHOUT instantiating an object
/// Helper functions for working with block classes ============================
/**
* Call a class method (one that does not requrie a block instance) on a block class.
* @param string $blockname the name of the block.
* @param string $method the method name.
* @param array $param parameters to pass to the method.
* @return mixed whatever the method returns.
*/
function block_method_result($blockname, $method, $param = NULL) {
if(!block_load_class($blockname)) {
return NULL;
@ -156,7 +401,12 @@ function block_method_result($blockname, $method, $param = NULL) {
return call_user_func(array('block_'.$blockname, $method), $param);
}
//This function creates a new object of the specified block class
/**
* Creates a new object of the specified block class.
* @param string $blockname the name of the block.
* @param $instance block_instances DB table row (optional).
* @return block_base the requested block instance.
*/
function block_instance($blockname, $instance = NULL) {
if(!block_load_class($blockname)) {
return false;
@ -169,8 +419,11 @@ function block_instance($blockname, $instance = NULL) {
return $retval;
}
//This function loads the necessary class files for a block
//Whenever you want to load a block, use this first
/**
* Load the block class for a particular type of block.
* @param string $blockname the name of the block.
* @return boolean success or failure.
*/
function block_load_class($blockname) {
global $CFG;
@ -190,26 +443,18 @@ function block_load_class($blockname) {
return class_exists($classname);
}
// This function returns an array with the IDs of any blocks that you can add to your page.
// Parameters are passed by reference for speed; they are not modified at all.
/// Functions that have been deprecated by block_manager =======================
/**
* @deprecated since Moodle 2.0 - use $page->blocks->get
* This function returns an array with the IDs of any blocks that you can add to your page.
* Parameters are passed by reference for speed; they are not modified at all.
* @param $page the page object.
* @param $pageblocks Not used.
* @return array of block type ids.
*/
function blocks_get_missing(&$page, &$pageblocks) {
$missingblocks = array();
$allblocks = blocks_get_record();
$pageformat = $page->pagetype;
if(!empty($allblocks)) {
foreach($allblocks as $block) {
if($block->visible && (!blocks_find_block($block->id, $pageblocks) || $block->multiple)) {
// And if it's applicable for display in this format...
if(blocks_name_allowed_in_format($block->name, $pageformat)) {
// ...add it to the missing blocks
$missingblocks[] = $block->id;
}
}
}
}
return $missingblocks;
return array_keys($page->blocks->get_addable_blocks());
}
function blocks_remove_inappropriate($page) {
@ -475,20 +720,22 @@ function blocks_preferred_width(&$instances) {
return $width;
}
function blocks_get_record($blockid = NULL, $invalidate = false) {
global $DB;
static $cache = NULL;
if($invalidate || empty($cache)) {
$cache = $DB->get_records('block');
/**
* Get the block record for a particulr blockid.
* @param $blockid block type id. If null, an array of all block types is returned.
* @param $notusedanymore No longer used.
* @return array|object row from block table, or all rows.
*/
function blocks_get_record($blockid = NULL, $notusedanymore = false) {
global $PAGE;
$blocks = $PAGE->blocks->get_installed_blocks();
if ($blockid === NULL) {
return $blocks;
} else if (isset($blocks[$blockid])) {
return $blocks[$blockid];
} else {
return false;
}
if($blockid === NULL) {
return $cache;
}
return (isset($cache[$blockid])? $cache[$blockid] : false);
}
function blocks_find_block($blockid, $blocksarray) {
@ -1021,7 +1268,7 @@ function blocks_get_by_page($page) {
function blocks_print_adminblock(&$page, &$pageblocks) {
global $USER;
$missingblocks = blocks_get_missing($page, $pageblocks);
$missingblocks = array_keys($page->blocks->get_addable_blocks());
if (!empty($missingblocks)) {
$strblocks = '<div class="title"><h2>';

View File

@ -88,7 +88,7 @@ class moodle_page {
protected $_pagetype = null;
protected $_subpage = null;
protected $_subpage = '';
protected $_docspath = null;
@ -328,12 +328,7 @@ class moodle_page {
}
if ($state == self::STATE_PRINTING_HEADER) {
if (!$this->_course) {
global $SITE;
$this->set_course($SITE);
}
$this->initialise_standard_body_classes();
$this->starting_output();
}
$this->_state = $state;
@ -448,7 +443,11 @@ class moodle_page {
* and pagetype, uniquely identifies this page.
*/
public function set_subpage($subpage) {
$this->_subpage = $subpage;
if (empty($subpage)) {
$this->_subpage = '';
} else {
$this->_subpage = $subpage;
}
}
/**
@ -550,6 +549,21 @@ class moodle_page {
/// Initialisation methods =====================================================
/// These set various things up in a default way.
/**
* This method is called when the page first moves out of the STATE_BEFORE_HEADER
* state. This is our last change to initialise things.
*/
protected function starting_output() {
if (!$this->_course) {
global $SITE;
$this->set_course($SITE);
}
$this->initialise_standard_body_classes();
$this->blocks->load_blocks();
}
/**
* Sets ->pagetype from the script name. For example, if the script that was
* run is mod/quiz/view.php, ->pagetype will be set to 'mod-quiz-view'.

View File

@ -40,14 +40,20 @@ require_once($CFG->libdir . '/blocklib.php');
/** Test-specific subclass to make some protected things public. */
class testable_block_manager extends block_manager {
public function mark_loaded() {
parent::mark_loaded();
$this->blocksbyregion = array();
}
public function get_loaded_blocks() {
return $this->blocksbyregion;
}
public function matching_page_type_patterns($pagetype) {
return parent::matching_page_type_patterns($pagetype);
}
}
/**
* Test functions that don't need to touch the database.
*/
class moodle_page_test extends UnitTestCase {
class moodle_block_manager_test extends UnitTestCase {
protected $testpage;
protected $blockmanager;
@ -125,6 +131,226 @@ class moodle_page_test extends UnitTestCase {
$this->blockmanager->set_default_region('too-late');
}
public function test_matching_page_type_patterns() {
$this->assert(new ArraysHaveSameValuesExpectation(
array('site-index', 'site-index-*', 'site-*', '*')),
$this->blockmanager->matching_page_type_patterns('site-index'));
$this->assert(new ArraysHaveSameValuesExpectation(
array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*')),
$this->blockmanager->matching_page_type_patterns('mod-quiz-report-overview'));
$this->assert(new ArraysHaveSameValuesExpectation(
array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*')),
$this->blockmanager->matching_page_type_patterns('mod-forum-view'));
$this->assert(new ArraysHaveSameValuesExpectation(
array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*')),
$this->blockmanager->matching_page_type_patterns('mod-forum-index'));
}
}
/**
* Test methods that load and save data from block_instances and block_positions.
*/
class moodle_block_manager_test_saving_loading extends UnitTestCaseUsingDatabase {
public function setUp() {
parent::setUp();
$this->create_test_tables(array('block', 'block_instances', 'block_positions'), 'lib');
$this->switch_to_test_db();
}
public function tearDown() {
parent::tearDown();
}
protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
$page = new moodle_page;
$page->set_context($context);
$page->set_pagetype($pagetype);
$page->set_subpage($subpage);
$blockmanager = new testable_block_manager($page);
$blockmanager->add_regions($regions);
$blockmanager->set_default_region($regions[0]);
return array($page, $blockmanager);
}
protected function get_a_known_block_type() {
global $DB;
$block = new stdClass;
$block->name = 'ablocktype';
$this->testdb->insert_record('block', $block);
return $block->name;
}
protected function assertContainsBlocksOfType($typearray, $blockarray) {
if (!$this->assertEqual(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
return;
}
$types = array_values($typearray);
$i = 0;
foreach ($blockarray as $block) {
$blocktype = $types[$i];
$this->assertEqual($blocktype, $block->blockname, "Block types do not match at postition $i %s.");
$i++;
}
}
public function test_empty_initially() {
// Set up fixture.
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
get_context_instance(CONTEXT_SYSTEM), 'page-type');
// Exercise SUT.
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_loaded_blocks();
$this->assertEqual(array('a-region' => array()), $blocks);
}
public function test_adding_and_retrieving_one_block() {
// Set up fixture.
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
get_context_instance(CONTEXT_SYSTEM), 'page-type');
// Exercise SUT.
$blockmanager->add_block($blockname, $regionname, 0, false);
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array($blockname), $blocks);
}
public function test_adding_and_retrieving_two_blocks() {
// Set up fixture.
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
get_context_instance(CONTEXT_SYSTEM), 'page-type');
// Exercise SUT.
$blockmanager->add_block($blockname, $regionname, 0, false);
$blockmanager->add_block($blockname, $regionname, 1, false);
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
}
public function test_block_not_included_in_different_context() {
// Set up fixture.
$syscontext = get_context_instance(CONTEXT_SYSTEM);
$fakecontext = new stdClass;
$fakecontext->id = $syscontext->id + 1;
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
$addbm->add_block($blockname, $regionname, 0, false);
// Exercise SUT.
$viewbm->load_blocks();
// Validate.
$blocks = $viewbm->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array(), $blocks);
}
public function test_block_included_in_sub_context() {
// Set up fixture.
$syscontext = get_context_instance(CONTEXT_SYSTEM);
$childcontext = new stdClass;
$childcontext->id = $syscontext->id + 1;
$childcontext->path = '/' . $syscontext->id . '/' . $childcontext->id;
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
$addbm->add_block($blockname, $regionname, 0, true);
// Exercise SUT.
$viewbm->load_blocks();
// Validate.
$blocks = $viewbm->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array($blockname), $blocks);
}
public function test_block_not_included_on_different_page_type() {
// Set up fixture.
$syscontext = get_context_instance(CONTEXT_SYSTEM);
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
$addbm->add_block($blockname, $regionname, 0, true);
// Exercise SUT.
$viewbm->load_blocks();
// Validate.
$blocks = $viewbm->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array(), $blocks);
}
public function test_block_not_included_on_different_sub_page() {
// Set up fixture.
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
get_context_instance(CONTEXT_SYSTEM), 'page-type', 'sub-page');
$blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
// Exercise SUT.
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array(), $blocks);
}
public function test_block_included_with_explicit_sub_page() {
// Set up fixture.
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
get_context_instance(CONTEXT_SYSTEM), 'page-type', 'sub-page');
$blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
// Exercise SUT.
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array($blockname), $blocks);
}
public function test_block_included_with_page_type_pattern() {
// Set up fixture.
$regionname = 'a-region';
$blockname = $this->get_a_known_block_type();
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
get_context_instance(CONTEXT_SYSTEM), 'page-type', 'sub-page');
$blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
// Exercise SUT.
$blockmanager->load_blocks();
// Validate.
$blocks = $blockmanager->get_blocks_for_region($regionname);
$this->assertContainsBlocksOfType(array($blockname), $blocks);
}
}
?>

View File

@ -3245,6 +3245,20 @@ function theme_setup($theme = '', $params=NULL) {
$CFG->stylesheets[] = $CFG->themewww.'/standard/rtl.css'.$paramstring;
$CFG->stylesheets[] = $CFG->themewww.'/'.$theme.'/rtl.css'.$paramstring;
}
/// Set up the block regions.
if (!empty($THEME->blockregions)) {
$PAGE->blocks->add_regions($THEME->blockregions);
} else {
// Support legacy themes by supplying a sensible default.
$PAGE->blocks->add_regions(array('side-pre', 'side-post'));
}
if (!empty($THEME->defaultblockregion)) {
$PAGE->blocks->set_default_region($THEME->defaultblockregion);
} else {
// Support legacy themes by supplying a sensible default.
$PAGE->blocks->set_default_region('side-post');
}
}

View File

@ -167,4 +167,15 @@ $THEME->custompix = false;
/// use &lt; &gt; &raquo; - these are confusing for blind users.
////////////////////////////////////////////////////////////////////////////////
$THEME->blockregions = array('side-pre', 'side-post');
$THEME->defaultblockregion = 'side-post';
/// Areas where blocks may appear on any page that uses this theme. For each
/// region you list in $THEME->blockregions you must call blocks_print_group
/// with that region id somewhere in header.html or footer.html.
/// defaultblockregion is the region where new blocks will be added, and
/// where any blocks in unrecognised regions will be shown. (Suppose someone
/// added a block when anther theme was selected).
////////////////////////////////////////////////////////////////////////////////
?>