[drupal-devel] [feature] Enable multiple block regions (not just "left" and "right" sidebars)

chx drupal-devel at drupal.org
Mon May 9 20:48:09 UTC 2005

Issue status update for http://drupal.org/node/16216

 Project:      Drupal
 Version:      cvs
 Component:    block.module
 Category:     feature requests
 Priority:     normal
 Assigned to:  Anonymous
 Reported by:  paragkenia
 Updated by:   chx
 Status:       patch

Ber, Dries, do not kill me! Ber chaired the usability meeting in
Antwerp, that's all.


Previous comments:

January 26, 2005 - 12:27 : paragkenia

I read the comparision discussion between *Drupal* and *Mambo*. In
several messages it was outlined that Drupal can place blocks only in
right and left and not flexible to put them on anywhere where one want.
It will be great if this can be changed in upcoming versions.

I am no pro at PHP, so don't know how much time this task will take,
but I think it is very important.



April 15, 2005 - 03:44 : nedjo

This issue was apparently partially addressed in issue
http://drupal.org/node/19694 [1].
[1] http://drupal.org/node/19694


April 17, 2005 - 02:24 : nedjo

Attachment: http://drupal.org/files/issues/block-dynamic-regions.patch (8.17 KB)

This much-requested functionality - to have the ability to place blocks
in more than the two predefined regions - was partially addressed in
issue http://drupal.org/node/19694. [2].  But "blocks" are still
limited to the "left" and "right" sidebars (hard-coded in

This patch is a first step designed to enable multiple (eventually,
admin-definable) regions for blocks.  I've moved the existing "left"
and "right" block regions to a 'region' table (with ids of 0 and 1, as
currently used in themes).  Then all references to the regions are
drawn dynamically from the table.  This way, if further records are
added, they will appear in the list of available regions for block

Doing this actually reduces some duplicated code, since it's no longer
necessary to repeat code blocks for each of "left" and "right".

As it stands, the patch doesn't add any new functionality--but I don't
think it breaks anything either.  New functionality would need (a) new
regions defined, and (b) changes to themes.  A simple first step might
be, e.g., to add a "footer" region and then add a call in the footer
generation to append any blocks assigned to the footer region there.

I'm setting this to patch, but I'm aware that it needs some discussion
and refining before it'll be ready to apply.
[2] http://drupal.org/node/19694.


April 17, 2005 - 03:05 : nedjo

Attachment: http://drupal.org/files/issues/block_regions.png (5.65 KB)

Here's a screenshot showing the  block admin page, with drop-downs for
region placement (the options are dynamically generated based on
defined regions).


April 17, 2005 - 04:57 : adrian

The biggest problem with this is that you can have multiple themes, and
each of these themes can have different regions available.

Also, the method of defining which regions are available needs to be
standardised. Some of the work that me and Vlado are working on for the
install system would go towards solving that problem (ie: meta
information for modules, themes and styles).

This has been discussed to death, but the general consensus has been
that we _want_ to do this, but we need to solve a few other problems
properly first, the most pertinent being the interface issue. Chris
(factoryjoe) recently did a whole mess of workflows for something
related to this.


April 17, 2005 - 06:09 : syscrusher

The first paragraph of adrian [3]'s post is a point that occurred to me
also, as I read this thread.

One suggestion would be to separate the definition and configuration of
blocks, on one hand, from the placement of those blocks, on the other

In other words, Drupal core provides a mechanism defining what blocks
exist, which of these are on by default or off by default and
user-selectable vs. which are forced on for all users, and the
configuration (if applicable) of specialized blocks defined by
particular modules.

Each theme provides a standard hook function that returns an array of
region names and help/description text, e.g., array('left'=>t('This
vertical region is left of the main content area'), 'right'=>t('This
vertical region is right of the main content area'), 'footer'=>t('The
footer is below the left, right, and main content areas of the page')).

The theme part of Drupal core (i.e., theme.module itself, not the
individual themes) provides a standard UI that is displayed within
config of *each theme* (but is one physical code base within
theme.module) that allows the administrator to map blocks defined by
Drupal core into regions defined by the theme, and storing that mapping
as an theme-to-block_ID-to-region_ID (with weight) table in the
database. From there, the actual page rendering is similar to what's
being done now, but there is more of it.

I guess what I'm trying to say is that the key to solving this problem
is breaking it along its degrees of orthogonality, and there are three
-- two in Drupal core and one in the individual theme.

[3] http://drupal.org//user/1517


April 17, 2005 - 09:14 : Dries

Scott, is right.  The theme should export its available regions.  Then
the administrator's task is to assign blocks to regions (not to setup
regions).  A theme could have configurable regions, but that internal
to the theme.

To me, the real challenge is the UI and the interaction design. 
Configuring blocks could easily become a real pain (while most themes
continue to use 'left' and 'right'.) 

Of course, we can implement all the functionality, default everything
to 'left' and 'right', and worry about the UI later. This should be
fairly straightforward to implement and nedjo's patch looks like a
first step in the right direction.


April 17, 2005 - 23:09 : nedjo

I agree with the suggested approach of themes registering their regions.
 I'd see this happening when a particular theme is activiated (or
upgraded).  Regions would be an array of names (e.g., 'left', 'right',
'footer').  New records would be created in the region table only for
region names not previously registered.

Some areas I'm not clear on, or that need further work:

Table naming
Should a new table be 'region' or 'regions' (I've used 'region')?  I
don't see a convention among existing table names, some of which are
singular and others plural.
Default values
I've kept the existing '0' and '1' ids for regions (left and right,
respectively), for backward compatibility.  But this means we can't use
autoincrement for the region id (rid), since autoincrements seem to
begin with 1.  Likely we should change to autogenerated ids.
Initial records
Using the INSERT INTO statements as I've done for the initial region
entries is probably counterproductive, since sooner or later they'll
have to be dynamically generated.  I was hoping this could be a
preliminary patch, with the main work coming later, but likely we need
to solve region registration by themes before this patch is applied.  I
don't have a good idea of how region registration by themes would be
implemented (a hook on theme activation?), and invite suggestions or
Theme system changes
Besides region registration, the other change I'm seeing that would be
needed in the theme system is loading blocks by region name, rather
than region id.  This is because the ids currently used ('0' and '1')
in theory might be diffferent on a particular install.


April 17, 2005 - 23:18 : syscrusher

Instead of having themes "register" their regions, why not just add a
theme API hook called them_regions() that returns an associative array
of $region_name=>t($region_helptext)? This would be in keeping with
other similar API functions, such as those that return what permissions
apply to a module or what node types are defined by a module. Most
themes are going to define only a small number of regions (two being
the typical case now, but I could see five or six in a complex theme),
so returning a constant array will be faster than querying SQL to
obtain an array of rows.

There could be (optionally, at the discretion of whoever builds this
thing) another API hook like theme_region_properties($region_name) that
returns an associative array with detailed info for a given region, such
as extended help text with recommended usage instructions for the



April 17, 2005 - 23:19 : syscrusher



April 18, 2005 - 00:47 : adrian

Because. The most common 'theme' is a phptemplate theme. 

And there needs to be a generic method for specifying the regions
available, in a non hook_function format.. 

Themes get their names from the directory in which they are contained..
when copying the theme to another directory, there must be _no_
modifications necessary to allow normal usage. This is one of the
tenets of the new template system I designed.

You would need a standard way to define meta-information for themes,
that does not need to be modified when copied to a new directory. We
are working on this in the install system work, as you need a way
external of Drupal to define the module dependencies and some other

My approach would be to add a theme.dsc text file to the directory,
which would allow you to specify meta-information. For instance :
regions: left, right, footer, center, mountie
author: Johnny McAngstyPants


April 18, 2005 - 04:00 : syscrusher

Adrian wrote:

Themes get their names from the directory in which they are contained..
when copying the theme to another directory, there must be _no_
modifications necessary to allow normal usage. This is one of the
tenets of the new template system I designed.

A very good point. But region names don't have to be unique across
different themes, so my hook function wouldn't have to be modified. The
suggestion I made for the mapping metadata was three factors: theme ID
or name, region ID or name, and block ID (plus one non-key weight value
to order the blocks within a region, but this is not relevant here).

I'm not familiar enough with PHP template to be able to respond to your
comments on that one, so if you say it's not feasible to work with my
schema, then I'll take your word for it. :-)



April 18, 2005 - 04:03 : syscrusher

Oh, wait.....I see now what you mean! It's not the output of the
function that is the problem, but the *name* of the function.

Never mind. I concede your point.



April 18, 2005 - 09:44 : Jaza

I'm probably jumping ahead a bit here... but something that this patch
will have to eventually account for, is how to allow regions to be
defined as inline. Allowing a theme to define a region's position as
being anywhere on the edge of the page (i.e. top, left, right, bottom,
corners, etc) is relatively easy. But what about having a region that's
in the middle of a node's body, or somewhere else that's not the edge of
the page?

What I'm thinking of, is eventually allowing the custom region system
to integrate with the CCK. Like I said, I admit that I'm jumping ahead
into the future - the CCK still has a long way to go before it's ready.
But ultimately, it would be cool if a theme could define a region as
being after, say, the "rating" field in nodes of type "movie review".
This would make the region (and the blocks in it) truly inline and in
context with the actual content of the node.

This would be a huge step forward compared to the current block system,
which doesn't allow you to mix the presentation of blocks and nodes at
all. In Drupal ATM, blocks and "the rest of the page" are totally
separate, and really you have no choice but to display them as such.
The result of this is that information in blocks that really should be
displayed as part of a node, gets literally "pushed to the side", and
always seems secondary to the actual content. Often the block has
content that is just as important as the content of the node itself.

Another option (of less merit, IMO - because of the extra maintenance
work, and lack of enforced consistency) would be to have a region
filter. You could then choose where to place an inline region on a
per-node basis, by entering text such as [region:2] (example based on
image_filter syntax) into the node body.

Anyway, just thought I'd throw that idea into the open. I don't expect
it will be implemented any time soon, but it's something to think



April 18, 2005 - 10:54 : stefan nagtegaal

Attachment: http://drupal.org/files/issues/regions---possibility-1.png (1.29 KB)

Imo the 'regions' are more than you guys name here.. FOr example I
attached 2 screens which only shows you the regions.. What I think is
that it should always be possible to have free names for the regions.
No matter if i call - the region where my content appears in -
'content' or 'site items'..

See attached screens..


April 18, 2005 - 10:56 : stefan nagtegaal

Attachment: http://drupal.org/files/issues/regions---possibility-2.png (1.39 KB)

And the second...
See these links:
- http://drupal.org/files/issues/regions---possibility-1.png
- http://drupal.org/files/issues/regions---possibility-2.png


April 18, 2005 - 17:22 : nedjo

Attachment: http://drupal.org/files/issues/block-dynamic-regions2.patch (13.39 KB)

Here's a revised patch implementing some of the ideas so far.  I've used
the theme engine - rather than individual themes - to generate the list
of available regions.  I know this isn't ideal, but e.g. for xtemplate
it's at present the only option--no logic is possible in the individual

region is changed to a varchar field from the current tinyint.

I've roughed in several regions--really just for demo purposes.  More
thought and work would be needed to refine them (e.g., styling, etc.). 
But this maybe moves the conversation forward.


April 18, 2005 - 23:26 : Dries

This patch enables different regions to be used.  That is a good thing. 
The next question is: should we take into account that different themes
could assign blocks to different regions?  Lots of problems would be
solved if (i) there could only be one active theme on a website or (ii)
if all themes would have a common set of regions.

(This "let users select their own theme"-thing is a left-over from the
early days, except for WAP stuff maybe.)


April 18, 2005 - 23:37 : killes at www.drop.org

Giving up multiple theme support would be a great thing. People could
still select from multiple style sheets. WAP shoud not be a user
preference setting, but automatically detected and redirected to a
special site with a WAP theme.


April 18, 2005 - 23:48 : adrian

You would then lose the ability to make a special front page theme for
use with the sections module, for instance. 

Also, currently styles exist in the same namespace as themes, and we
would have to make more a distinction of styles vs templates (or
themes), but I do think this could help simplify things.


April 21, 2005 - 18:54 : nedjo

Attachment: http://drupal.org/files/issues/block-dynamic-regions3.patch (15.69 KB)

The main issue raised, if I'm understanding well: if a theme or theme
engine is present that offers regions other than those available in the
default theme, any blocks assigned to those regions will be invisible to
most users.

Here's a revised patch addressing the concern.  I've added a test for
each region to see whether it's also available in the current default
theme.  (Actually, I'm realizing as I write this, I've used the theme
engine--so it would need to be updated to test first if an engine is
being used.)

In any case, any regions not available by default are starred, and a
message text appears (only if necessary).

If there's support for the approach, I'd be happy to finish the patch. 
Remaining work:

* extend to work with non-engine themes
* finalize base set of regions to implement
* implement common region set in all core themes (for now I've only
done xtemplate)
* work on CSS display (how blocks in each region should look)

This last point I'm not too confident on and would look for

Screenshot to come.


April 21, 2005 - 18:56 : nedjo

Attachment: http://drupal.org/files/issues/block_regions_message.png (12.34 KB)

Screenshot showing starring of non-default regions plus message.


April 21, 2005 - 19:19 : killes at www.drop.org

I like that approach. +1


April 21, 2005 - 19:23 : resmini

My two cents.

If this has to be done (and it should), better get rid of spatial
definitions for areas such as left, right, top, bottom, etc.
Use semantic names related to content and let the theme take care of
their positioning interely.
Also note that there in an ongoing debate in IA trying to build up a
standard naming convention for page regions in a way that is
semantically (and logically) correct. Just for the sake of it, you can


with follow-ups, including Eric Meyer's.  There are more substantial
contributes in the AIfIA web site, but I can't seem to find them now.
I'll post a link or an abstract if I manage to.


vector at exea dot it


April 21, 2005 - 20:15 : nedjo

Good points, useful references.  The default regions I'm thinking of

       'banner' => t('banner'),
       'left' => t('left sidebar'),
       'right' => t('right sidebar'),
       'body_top' => t('body top'),
       'body_bottom' => t('body bottom'),
       'footer' => t('footer')

Perhaps "body" would be better as "content"?  It would be easy enough
to add in more regions, e.g., within the content (after title, after
help, etc.)  One issue is that many of these regions will already have
rendered content.  Should the blocks come before or after that other
content?  I've assumed after for banner and footer, while giving both
options in body.

In any case, refinements or suggestions would be great.


April 21, 2005 - 20:56 : resmini


       'banner' => t('banner'),
       'left' => t('left sidebar'),
       'right' => t('right sidebar'),
       'body_top' => t('body top'),
       'body_bottom' => t('body bottom'),
       'footer' => t('footer')

The classic (as far as classic goes for something Web related) scheme
comprises 5 spatial regions, much like stefan's
http://drupal.org/files/issues/regions---possibility-1.png with a left
area mirroring the one called 'blocks'. Call them top, left, center,
right, bottom.
Variants usually exclude one or more of these, layout-wise.

If we talk content (semantic) instead, things get a bit more
complicated, as these spatial regions normally include more than one
content-area. The top, for example, could include ad banners and the
site's header, or the main menu. But these merge seamlessly with CSS
definitions, which are definitely something that should get properly
standardized (most of the errors / inconsistencies I'm encountering
with Drupal today are related to this), but this is out of scope in
this thread.

What I somewhat object to the definitions above is that it mixes the
two approaches.
'banner' is not spatial, is content, as it is the distinction between
body top and bottom. If 'banner' goes there, it is 'top', whatever that
might be. I designed a couple of web sites which had
headers/logos/banners at the bottom of the page, and I'm not exactly
the wildest designer you'll probably meet.
And if we include body_top and _bottom, we should also add
'navigation', or 'menu'  and some other content-related semantic region
(impressum, or company_data, or whatever).

I suggest that either we go along

       'top' => t('banner'),
       'left' => t('left sidebar'),
       'center' => t('body'),
       'right' => t('right sidebar'),
       'bottom' => t('footer')

or we dedicate some time to detailing what could possibly fit there
semantically, which is perfectly possible without limiting design
freedom or whatever, since the vocabulary is not infinite, but not
something you do out of the blue. 

Please note that I understand t('something') to be an example, since
such a layout only defines regions on the page, not semantic regions.
My main content could fit nicely in the bottom region.

As for the names for the regions, they are not important, as much as
they are coherent and enforced.


April 21, 2005 - 23:16 : stefan nagtegaal

Attachment: http://drupal.org/files/issues/regions-final.png (2.39 KB)

Maybe something like this???

But, I have to say that I _really_ liked the solution to split the
'content'-region into the 'content' and 'beneath content'.. I love


April 22, 2005 - 00:20 : resmini

Stefan, yes.

That's basically what you can build if you stick with spatial, and this
layout can generate quite an amount of (sane) layout variations even if
you interpret it strictly (suppose a default) as

<div id="header">
<div id="left-bar">
<div id="content">
<div id="right-bar">
<div id="footer">

What you can do with this is left basically to the theme designers and
their use of CSS, CSS-P or tables (brrr), but this could be an easy and
proper way to identify macro-regions in which more accurate positioning
happens at a more specific level.
I'm all in favour of subsequent identification of sub-areas (top and
bottom in body), but I don't think it would be a good idea to mix the
different approaches I mentioned in my previous post.
A site with lots of things going on or which is not just blogging
surely has the need to use its content area in a wiser manner than just
putting there 'content', the number of modules doing precisely this is
more than proof, but that falls more in a 'Drupal definitive guide to
semantics', in which CSS selectors are used or suggested strategically
for such a scope.

>From this point of view and for the sake of this thread, any unique
area / div (#name) could (should?) be a target for blocks, and this in
my opinion (*) would be the perfect solution, but I do not know if and
how this is even remotely possible in the current Drupal.

(*) It's quite late, local time, and it was a looong working day.


April 22, 2005 - 00:38 : resmini

Attachment: http://drupal.org/files/issues/regions-final-variation.png (1.9 KB)

Just to be clear, I add a variation of stefan's scheme that shows how
this is *not* by any means positional, but spatial, or better
relational. Use your CSS imagination to take out regions, reduce them
to empty containers, enlarge them, make them taller, shorter, whatever.
5 regions, do what you like.


April 22, 2005 - 00:44 : resmini

Sorry, I forgot.
And this is also why I'm not too keen on calling anything 'content'. If
I enlarge my right region enough, why not put my content there?
Shouldn't this be a theme-level concern?
It's nothing serious, but if my center area is called 'center' (or
something similar and more sexy), I won't confuse anybody.
This is left, center, right: do with them what you prefer. Content in
the bottom? Show me.
If I call something 'content', I'm more than suggesting that content
goes there, and only there.


April 22, 2005 - 10:17 : stefan nagtegaal

Resmini, maybe it is only me but I think that you are making a mistake
in your way of thinking..

I get the feeling that you're mixing the 'regions' and 'divs'.. the
'regioins' should have meaningfull sentences, but the divs
As an example:
$region_name => $content_body

here we go:
'header' => $logo
'left sidebar' => theme('blocks', 'left')
'right sidebar' => theme('blocks', 'right')
'content' => $content
'footer' => $footer.

So, $region_name does not have to be equal to the id or class of the


April 22, 2005 - 11:27 : resmini


>So, $region_name does not have to be equal to the id or class of the

Yes, absolutely. I probably didn't make myself very clear: what I'm
trying to point out is that in   

       'header' => $logo
       'left sidebar' => theme('blocks', 'left')
       'right sidebar' => theme('blocks', 'right')
       'content' => $content
       'footer' => $footer.

there is no reason at all to call 'content' the region that  holds

nedjo asked in #24

       'body_top' => t('body top'),
       'body_bottom' => t('body bottom'),

if /Perhaps "body" would be better as "content"?/ and all my reasoning
is simply that no, that is not content, or it shouldn't be (or better:
it may happen that main content is elsewhere). As a matter of fact,
even the connotation 'sidebar' doesn't fit very well logically.

To make it short: Today's method works, but has limits. Mambo, which
paragkenia quotes at the beginning, handles more 'user regions' but in
pure Mambo style conventions are so loose that they are hardly useful.
If we define regions, as in nedjo's example, in my opinion these
regions shouldn't imply informational layouting, only relational
positioning (that is, where they stay in the browser viewport).
I know it may look like overdesigning, but Drupal constantly enforces
conventions and coding guidelines everywhere: this is one of the best
aspects of the project and I think it should carry to the layout.


April 22, 2005 - 11:32 : stefan nagtegaal

While I think that 'body_*' is not as self explaining as 'content_*' I
vote for using 'content_*'..


April 25, 2005 - 19:48 : chx

Let's get back to the code. If my understanding is correct the big
discussion is about how to name potiental rectangular areas _after_
this is commited. So, first get this committed. What's need to make
that happen?


April 25, 2005 - 20:56 : chx

I spoke with Moshe, Steven, JonBob and the result is: keys shall be
numbers, and themes shall define the values. We will make region zero
and one required. There will be a define('REGION_CONTENT', 0) and a
define('REGION_SIDEBAR', 1); so you can have readable code still.
Either wait for me to code it or feel to do it yourself, just drop me a
mail via the contact form if you are doing it.


April 27, 2005 - 18:14 : nedjo

Károly, it's great if you're willing to take on finishing this.  I
tried to summarize remaining work in update 20, above [4].

The numerical keys look fine to me.

In terms of an initial default set of regions, one quirk is this: for
now, so far as I can see (and assuming the approach I sketched in),
available regions can be defined only in (a) theme engines and (b)
individual themes that don't use an engine.  So, for instance, an
individual xtemplate based theme can't define its own custom regions;
they need to be defined in the theme engine.  (Unless and until the
whole theme system should switch to the sort of configuration file
adrian suggested above [5].)

Which is to say that, under this approach, we'll be defining a set of
regions for each engine, and then all themes using that engine should
try to implement those regions.  (Otherwise, if a site admin selects a
region defined in the engine but not implemented in the default theme,
the content won't appear.)

Please let me know if there's anything in what I've done that isn't
clear, or if you want to pass some or all of this back.

[4] http://www.drupal.org/node/16216#comment-27398
[5] http://www.drupal.org/node/16216#comment-27052


May 9, 2005 - 22:36 : chx

I had a "short" discussion with the UI team leader ie. Ber Kessels. The
outcoming is that we will change hook_block so that it uses callbacks a
bit like menu system. Here's an example:

function module_block() {
    $items = array();
    $items['module_header'] = array('callback' => 'mymodule_page',
'weight' => -50, 'region' => 'content' , 'cache' => TRUE, 'pages' =>
    return $items;

Please note that we are allowing caching the themed output of each
block independently.

The theme system will execute hook_block as it does now and it'll
execute the callbacks defined in module_block as well. Of course if the
callback is cacheable and in the cache, it'll print it from cache. If
it's themeable and not in the cache, it'll cache it before printing.

Pages contains a string (could be PHP code!) which can be overriden in
the block configuration screen.

Callbacks defined in hook_menu will have lot less functionality after
this, they will be used for non-themed pages mainly.


May 9, 2005 - 22:45 : chx

More explanation is requested for the example.

module_header is the unqiue name of the block.
pages define on which pages the block is visible. ('pages' in the block
configuration screen.) Maybe I'll implement 'visibility' from the same
screen as well.
callback, weight are well known Drupal terms.
cache is a boolean which defines whether given output is cacheable or

More information about the drupal-devel mailing list