Update: appparently, today was the day to write about this. Nedjo Rogers submitted a handbook page that shows a different method of achieving the same end.
For the most part, Drupal 4.7's block system is underutilized. This is a shame; with the proper templating, drupal's block system can become a valuable workhorse. In this tutorial, you will learn:
By the end of this tutorial, you will have the ability to place blocks into node's like a so:
:
As with every tutorial in Extreme PHPtemplate theming, you must be working with drupal 4.7, and some background in PHP. If you have no background in PHP, than I suggest you just play along. You may, god forbid, begin to learn.
<?php function phptemplate_regions() { return array( 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer') );}?>
Observe the above code. It generates the regions that allow you to place blocks in the header, content, left sidebar, right sidebar, and footer. In order to create our "article blocks" region, we need to first override this default function in template.php. As some of you may have already noted, this function already contains a "phptemplate_" prefix. Obviously, in order to override this function, we therefore cannot use our normal method of adding that prefix. Luckily, the work around is super easy, and intuitive. Simply replace the phptemplate_ prefix with the name of your theme. This tutorials theme is named "xtreme_theming1", thus our template.php file will look like this:
<?php function xtreme_theming1_regions() { return array( // We'll want to return the default regions 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer'), // !!Here's our new region "article blocks"!! 'article_blocks' => t('article blocks') );}?>
Note that this same method can be used to override any function in phptemplate.engine. Thus, phptemplate_comment($comment, $links = 0), becomes xtreme_theming1_comment($comment, $links = 0). And so forth.
First, Go to administer->blocks, "admin/block". Assuming you followed step one correctly, you have a new region called "article blocks", available to send blocks to. Enable "recent blog entries", and put it into the "article blocks" region.
Second, go to template.php. Call the "theme_blocks($region)" function, and send the output to node.tpl.php. Below is the proper way to do that:
<?php function _phptemplate_variables($hook, $vars) { /* in this case, a hook refers to the beginning of tpl.php file Thus, case 'page' affects page.tpl.php. 'node' affects node.tpl.php, and case 'block' would affect block.tpl.php */ switch($hook) { case 'node' : /* $vars['article_blocks'] is $article blocks in node.tpl.php */ $vars['article_blocks']= theme_blocks('article_blocks'); break; } return $vars;}?>
The final step is to print the variable in the node.tpl.php file. I recommend that you place the following code directly above the "node" div
<?php /* LOOK! */ if ($article_blocks) { ?> <div id="article_blocks"> <?php print $article_blocks;?> </div> <?php } ?> <div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>"> ...
Now, click save, and see your new node.tpl.php block region in all its glory:
We have two problems. One we don't want to show the article_blocks region, unless you're viewing the entire node. Second, our article block... to be frank.... looks like crap.
Below, we've gone ahead and taken care of problem one by instructing phptemplate to only return "$article_blocks" when $page doesn't equal zero ($page equals zero when you are not view full nodes). Here's the full template.php file for this tutorial below:
<?php function xtreme_theming1_regions() { return array( // We'll want to return the default regions 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer'), // !!Here's our new region "article blocks"!! 'article_blocks' => t('article blocks') );}function _phptemplate_variables($hook, $vars) { /* in this case, a hook refers to the beginning of tpl.php file Thus, case 'page' affects page.tpl.php. 'node' affects node.tpl.php, and case 'block' would affect block.tpl.php */ switch($hook) { case 'node' : /* $vars['article_blocks'] is $article blocks in node.tpl.php */ if ($vars['page'] /* the equivolent of $page in node.tpl.php */ != 0) { $vars['article_blocks']= theme_blocks('article_blocks'); } break; } return $vars;}?>
The following CSS rules will make your block look like they do in the opening screenshot:
/* CSS Document */#article_blocks { float:right; width:300px; font-size:0.9em; border:1px solid #cccccc; margin:0 12px 12px 12px;}#article_blocks .block { width:100%; margin:6px;}#article_blocks ul li {width:100%;}
Comments
Region placement, question
How does the region 'know' where it should be displayed?
I have a Theme with a primary links menu partway down. Not at the very top like the default.
I want it to use Nice Menus, so I guess I have to make a new region for it. It will be seen on every page (not just in particular nodes) so I guess I use page.tpl.php.
I see how to create the region, and have a Nice Menus block use it, and have that block inherit from primary links, but I don't see how it gets the information about the *style/location* of the primary links. Which I guess means, the name of the div containing the primary links. Of course that's in style.css, but how does that info get to the Admin/Block section?
Thank you.
Support / Questions...
Thank you for a great website. I wish you had done all documentation on drupal ;-)
First of all I am new to php and havnt done this region- yet.
I need to have following regions (to small regions in the bottom) on all my content pages:
...........
. .
. content .
. .
. .
...........
. R1 . R2 .
...........
These small regions in the bottom is for inserting blocks/views.
I need to be able to tell each block on which sites it should go into (just as standard in drupal). As I read your splented documentation, I'll just get a new region to place my block into and I thereby assume that I will have the same functionallity how to place the block.
My question is therefor:
1) Is this the right/smartest way of getting my regions on all nodes + books?
2) How do I get the two regions besides each other and not in a row (php/css)?
Might be simple basic, but as mentioned I am new to php and have only done some little css
Thank you in advance.
Jakob
Answer to 1. If you you've
Answer to 1.
If you you've declared your regions in phptemplate, and put them in a page.tpl.php file, than they will always be there (unless you hide them in admin/build/block). What's different here is that we are putting it in a node.tpl.php... so the blocks will never show unless a node is being viewed in page view. (jesus, I feel like I might as well be speaking klingon at this point....)
Answer to 2.
This is relatively easy. But don't listen to my nonsense, here's a quality resource to teach you how divs sitting on top of each other become side by side: Floattutorial. I encourage you to study these examples as they will provide more than an answer to this specific question...
nick, u rock!
thanks a lot, nick, i love this code snippet, keep going,
A litte problem
Hi Nick
I added a new region following the steps from your tutorials. Its very much there in the placement combobox but cannot see the region. Can you help..
bantei
Think I get crazy
<?phpfunction _phptemplate_variables($hook, $vars) { $vars_return=array(); switch($hook) { case 'node' : if (arg(1) != "add" || arg(2) != "edit")) { // Seems here's one ')' too much... if ($vars['page'] != 0) { $vars_return['article_blocks']= theme('blocks', 'article_blocks'); } } break; } return $vars_return;}?>Well, except that closing bracket, things seems fine here. Except one thing: I have to disable the inner "if ($vars... != 0) {" condition or I would get a blank screen. I do a print_r($vars['page']); in the line above the switch and it prints nicely. but when I use it in that conditional statement, a blank page results. Is there a hidden thing in PHP? I'm new to it, but spent some years coding with C, C++, Java, JavaScript and somme more, so I can't believe there's voodoo happening -- but it seems so. Any ideas? Thanks, Norbert (Drupal 4.7.3, PHP 5.1.4)Disregard Previous Message
I don't know what I did to fix it but it works now. I started from a clean template copy. I think it must have been something I did wrong in a previous tutorial.
Matthew PareFirst Tutorial I have had trouble with, could you please help.
Nick I read several different portions of your site and have enjoyed your work. You are a valuable asset to everyone. Your presence is posted in countless articles. I just want to say thank you now and thank you for tomorrow.
Now to my question. I am sure that I am missing something very simple. The problem that I am experiencing is not limited to this tutorial but only discovered when I assigned my block to the article blocks. After saving blocks nothing displays. I can manually go back and I receive the following error.
warning: Cannot modify header information - headers already sent by (output started at /long_path/themes/bluemarine/template.php:17) in /long_path/includes/common.inc on line 266.Now this problem only occurs when I send the blocks to node.tpl.php. When I copy the code from step 2 into my template.php file. I have found that either from your drop down menu tutorial or your user login, I'm not sure which at the moment, but I discovered that I had a problem while doing this tutorial.
<?phpfunction _phptemplate_variables($hook, $vars) { /* in this case, a hook refers to the beginning of tpl.php file Thus, case 'page' affects page.tpl.php. 'node' affects node.tpl.php, and case 'block' would affect block.tpl.php */ switch($hook) { case 'node' : /* $vars['article_blocks'] is $article blocks in node.tpl.php */ if ($vars['page'] /* the equivolent of $page in node.tpl.php */ != 0) { $vars['article_blocks']= theme_blocks('article_blocks'); } break; } return $vars;}?>I appreciate your help. Sorry that I was not concise.
-Mattgah so much cyborg reading
I’m not sure I see how
buggy?
<?phpfunction _phptemplate_variables($hook, $vars) { $vars_return=array(); switch($hook) { case 'node' : if ($vars['page'] != 0) { $vars_return['article_blocks']= theme('blocks', 'article_blocks'); } break; } return $vars_return;}?>Try this: <?phpfunction
Try this:
<?phpfunction _phptemplate_variables($hook, $vars) { $vars_return=array(); switch($hook) { case 'node' : if (arg(1) != "add" || arg(2) != "edit")) { if ($vars['page'] != 0) { $vars_return['article_blocks']= theme('blocks', 'article_blocks'); } } break; } return $vars_return;}?>Hey Nick great
True previously implemented
Thanks a lot!
+1
I’ve learned more here in
The load problem
How does this compare load-wise with
Its half a matter of taste