Sunteți pe pagina 1din 15

Theming

Drupal
Content
Absolute minimal requirements for a theme   page 2
What is a themeable function and The Trick  page 7
Template files you don’t need to tell Drupal about   page 13
Template files you need to tell Drupal about  page 15
When not to use template files  page 15
PHP code style in template files  page 16
Anatomy of a page[-something].tpl.php file  page 17
Anatomy of a node[-something].tpl.php file  page 22
What does a page[-something].tpl.php file know  page 26
What does a node[-something].tpl.php file know  page 29
How does one make a *.tpl.php file more knowledgeable  page 31
Theming a ‘view’  page 34
CCK — what the hell is happening  page 36
Theming precedence — the rules  page 38
Adding regions — semantic or not  page 40
Good design — proximity and strong alignment  page 42
Browser-side theming : style.css  page 48
Printer-friendly all the way  page 56
Styling using jquery  page 57
eet
All about menus  page 58 Lean and sw
Theming the node form  page 59
1/ea » Absolute minimal requirements for a theme
Since Drupal 4.7, the default theming engine that ships with Drupal is the PHPTemplate
engine. That engine is comprised of phptemplate.engine (the engine itself, written in
php) and a collection of default template files written in XHTML with embedded php.
You can find all these files in the folder themes/engines/phptemplate. The sole require-
ment for a PHPTemplate theme to show up on the page admin/build/themes is : *

The presence of a page.tpl.php file in a folder inside the


folder themes OR
or
The presence of a style.css file in a folder inside a folder
that contains a page.tpl.php file
* It will “show up” without a preview thumbnail. To provide one, place a 150x90 png file with name
screenshot.png in your theme’s folder.
An example of a PHPTemplate theme defined by a style.css file is the minnelli theme. Its
folder is in the garland folder.

Exercise #1 how many themes do you see ?


themes each of these folders contains a page.tpl.php
file with or without a style.css file.
fuzzyland
cleancut contains a style.css file.
crushed

Answer : 3. Each theme gets its name from its folder’s name, i.e. fuzzyland, cleancut
and crushed. The theme cleancut provides no template file. However, it’s a theme in its
own right (as per our second requirement), and it uses the page.tpl.php file of the theme
fuzzyland. It’s not using the fuzzyland style.css file though ; it uses the style.css
stylesheet that’s contained in its own folder, the “cleancut” folder. Conversely, fuzzyland
is not using the stylesheet of cleancut, even if it has no style.css file of its own.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
What’s the theme we’re using now ?
The Drupal function path_to_theme(), defined in includes/theme.inc, provides us with the
relative path to our default theme, i.e. the active theme. Depending on which theme is
default, as per the last exercise, the value returned will be one of these three : themes/
fuzzyland, themes/fuzzyland/cleancut or themes/crushed. Additionnally, the global-
scope variable $theme always provides us with the name of the default theme, for example
cleancut. To print it, use <?php global $theme; print $theme; ?>

What if we want to use the style.css file of the parent theme


What if we wanted the cleancut theme to first appy the rules in the stylesheet of its
“parent” fuzzyland, and then apply its own rules as defined in its own style.css file ? We’d
do it like it’s done for the Drupal 5 minnelli theme. Open the style.css file that’s in the
folder themes/garland/minnelli. Here is what you’ll see :
minnelli is the fixed width version of the garland theme

@import "../style.css"; Here we are importing the content


going up one folder of the style.css file that’s in the
parent folder and “placing” it just
body #wrapper #container { before these 3 CSS rules:
width: 560px;
}
body.sidebars #wrapper #container {
width: 980px;
}
body.sidebar-left #wrapper #container,
body.sidebar-right #wrapper #container {
width: 770px;
}

The important thing to remember here is this : there can only be zero or one style.css file
per theme, and that stylesheet is to be found in that theme folder (and not in a subfolder).
Also, the style.css file — if it exists — will be linked automatically by typing the following
line of code in the page.tpl.php template file used by the theme :
<head> ... <?php print $styles ?> ... <head>

And as for themes based on an alternate style.css file, like the minnelli theme, nothing
special has to be done : we just have to place that stylesheet in a subfolder and we’re done.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
The variable $styles and CSS preprocessing
You may wonder where the variable $styles come from, what it contains, and in which
template files it can be used. The variable is set at line 221 of the file phptemplate.engine :
'styles' => drupal_get_css(),

Open that file and look up the function that includes that code. That function is :
phptemplate_page($content, $show_blocks = TRUE). This is the function that calls a
template file of the form : page[-something].tpl.php, and passes to it all variables needed
to build a Drupal page. In that function, the phptemplate engine is preparing an array
of values to pass to the appropriate page template. Look at all the variables it’s preparing
for that page template, besides $styles. Try and understand what’s going on here :
$styles is made available to any template file of the form page[-something].tpl.php. So,
if we created any of these templates : page.tpl.php, page-node.tpl.php, page-front.tpl.php
and page-node-45.tpl.php, the variable would be available to all four files. Later on, we’ll
see how these other page template files, such as page-front.tpl.php, can serve us. For now,
remember this : we are only required to provide a page.tpl.php file, or a style.css file if a
parent theme exists with a page.tpl.php file. Any other template file is extra.
The drupal_get_css() function is defined in includes/common.inc, at line 1448. How does
it work ? It returns the XHTML that links in all stylesheets used by activated modules,
as well as the default theme’s style.css file. Take a moment to consult the Drupal API.
The function is said to return a “themed representation of all stylesheets that should
be attached to the page. It loads the CSS in order, with ‘core’ CSS first, then ‘module’
CSS, then ‘theme’ CSS files. This ensures proper cascading of styles for easy overriding
in modules and themes.” The expression themed representation here means XHTML.
Theming is nothing else than writing XHTML.
What the API description is not saying though is that in Drupal 5 the function may serve
cached CSS, an “aggregation” of CSS
rules from many different *.css files,
served in one block, from a file.
While we’re creating a theme, we
really want to disable that. For as
long as we’re making modifications
to our style.css file, we cannot use
any cached version of it. To disable
that caching feature (or enable it), go
to admin/settings/performance.

Did you know that you cannot use CSS compression


load. It is recommended to only turn this option on when your
site is in production, as it can interfere with theme development.
This option is disabled if you have not set up your files directory,
or if your download method is set to private.
when your download method is set to private ?

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
Exercise #2 Let’s create a theme right now With no style.css file!
Create a brand spanking new page.tpl.php file and save it to a folder inside your themes
folder. Chose a funky name for that new folder as that will become the name of your
theme. We won’t worry about layout until much later, for now we’ll just print some con-
tent. Here is what you’ll copy into the file. It is safe to copy & paste this code to your file.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.


w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print
$language ?>" lang="<?php print $language ?>">
Like most variables that are printed
on this page, this one is passed to
<head> our template through the func-
<title><?php print $head_title ?></title> tion _phptemplate_render($file,
$variables) in phptemplate.engine.
<?php print $head ?>
<?php print $styles ?> Even if we haven’t created a style.css file
<?php print $scripts ?> (yet) for our theme, we want to use ‘core’
</head> CSS and link in our activated modules
*.css files. We want to look half decent!
is a special variable that is available
in all templates, not just page-x.tpl.php. Look

<body> On a typical “edit” page,


<div id="navigation"> this will link in a chunk of
<?php if ($breadcrumb): print $breadcrumb; endif; ?> javascript files : jquery.js,
drupal.js, autocomplete.js,
up line 122 in phptemplate.engine.

</div>
collapse.js and textarea.js!
<div id="main_content">
<p>Welcome to my new theme which is in <?php print $directory ?>.
<?php if ($layout == 'left' or $layout == 'both') : print 'We have some
blocks to show on the left.'; endif; ?></p>
<?php if ($title) : print '<h1>'. $title .'</h1>'; endif; ?>
$is_front

<?php if ($tabs) : print $tabs; endif; ?>


<?php if (isset($tabs2)) : print $tabs2; endif; ?>
<?php if ($messages) : print $messages; endif; ?>
<?php if ($is_front) : ?>
<p>This is my front page.</p> Drupal can tell us if something
goes wrong (or right) through
<?php endif; ?>
drupal_set_message(), etc.
<?php print $content ?>

</div> How did phptemplate.engine get all these variables ? What do these variables stand
for? Look at the function phptemplate_page($content, $show_blocks = TRUE).
</body> We’ll explain it all later in the section “what does page[-something].tpl.php know”.
</html>
http://www.11heavens.com/theming-drupal © 2007 Caroline Hill
page 
Backing up your database and phpMyAdmin
Before you make your new theme your default theme in q=admin/build/themes, you should
backup your Drupal database. Let’s say you’ve forgotten to record that snapshot of your
database, and things go very wrong, for example you get the infamous “php blank screen of
death”, and you are unable to fix the error and you want to go back in time. In that case,
PhpMyAdmin becomes your best friend. In the database table {system}, two entries get a
status = 1 for a default phpTemplate theme :
themes/engines/phptemplate/phptemplate.engine and
For the theme funky
themes/funky/page.tpl.php

If your theme happens to be a style.css file, such as for the minnelli theme, then you get
these three entries instead :
themes/engines/phptemplate/phptemplate.engine and
For the theme funkier, which
themes/funky/page.tpl.php and uses the page.tpl.php file of its
themes/funky/funkier/style.css ‘parent’ theme.
Change the status of either themes/funky/page.tpl.php, or themes/funky/page.
tpl.php and themes/funky/funkier/style.css to 0, then choose an alternate page
template that you know work, such as themes/garland/page.tpl.php, and make that
other theme your new default theme by changing the status of its page template to 1. Then
refresh your web page.
In an ideal world, when things go wrong, you should be able to debug and fix the error
OR revert your database to its last saved version.

Default template files and page.tpl.php


The theme we quickly put together on the last page does not rely solely on a page template,
but on other templates, such as node.tpl.php. The PHPTemplate engine provides default
templates, that may be used, or not, by our theme. You’ll find these files in themes/engines/
phptemplate : block.tpl.php, box.tpl.php, comment.tpl.php, default.tpl.php, node.tpl.php and
the phptemplate.engine.
An important template is missing here : page.tpl.php. We have to provide such template
ourseleves whenever we create a new theme — or, as we said before, we can put together an
alternate style.css file, place it in a subfolder of a theme that contains a page.tpl.php file, and,
by doing so, we’ve created a new theme. In that situation, the new theme will use the page
template of its parent theme.
If we don’t want the PHPTemplate engine to use the default node template, then we make
a copy of the default node.tpl.php file to our theme folder and edit that file to our liking. The
engine will use that file, rather than the default, if we’re providing such file in our theme folder.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
2/ea » What is a themeable function and The Trick
We said before that “Theming is nothing other than writing XHTML”. In order to gain
ultimate control over what markup is sent to the browser, every Drupal function that
wants to output something to screen should be themeable. Say what ? Let’s define
themeable within the context of the Drupal’s theming system. We’ll begin by examining
what a themeable function looks like :
function theme_some_data ($arg1, $arg2, ...) {

$output = ...; /* some XHTML markup is stored in $output */

return $output;

}
A themeable function takes one or several arguments, that store the beef of what has to
be output to screen, that is, Drupal objects, content, raw data. And it returns a string. That
string is XHTML ready to be sent back to the browser, i.e. it’s delicatessen. It’s a themed
representation of some content. The name of the function must — always — start
with theme_ followed by a word or a sequence of words separated by an underscore, that
describe what it is that we’re theming.
The theming system defines a chunk of themeable functions, and all modules that output
content to screen define their own share as well. Themeable functions are defined
pretty much everywhere, in core and in contributed modules. If you search for the string
“function theme_” in includes/theme.inc, you’ll find 25 themeable functions, among
which we have theme_page($content) and theme_node($node, $teaser = FALSE, $page =
FALSE).
function theme_page ($content) {
...
return $output;
}

function theme_node ($node, $teaser = FALSE, $page = FALSE) {


...
return $output;
}

You’ll also find 3 functions that make the theming system work : theme_get_
function($function), theme_get_settings($key = NULL), and theme_get_setting($setting_
name, $refresh = FALSE). Although all themeable functions begin with theme_, not all
functions that begin with theme_ are themeable functions.
Using The Trick, which we’ll describe shortly, we’ll be able to determine what themeable
function is responsible for what markup on the web page. With that knowledge, we’ll be
able to determine which themeable function we need to override.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
A themeable function can be overriden
A themeable function can be called directly — or we can let the theming system decide
whether to call that function or an alternate override for it. Since our theme will likely
override at least several of these themeable functions, and we’ll see how in a bit, it’s easier
for us to always leave it up to the theming system to determine what function to call : the
base theme function or an override, if one is defined. The theming system will handle this
quite efficiently for us if we always call a themeable function theme_some_data($arg1,
$arg2, ...) that way :

print theme('some_data', $arg1, $arg2, ...);

The first argument is called the hook in phptemplate engine “speak”. Keep that in mind.

To be fair, there may be a situation where it becomes useful to call the base theme
function directly. One situation in which we are defining an override for that function, and
want to output the same XHTML generated by the base function minus some change. A
situation in which we want to use the php function preg_replace, for example. Say we
have a themeable function that ouputs the XHTML for a table with an id attribute that has
the value discography, and let’s say that we dislike that value and want to replace it with
disk-data. We may define our override function this way (please do not worry about how
to override themeable functions for now, we will cover all of this shortly) :

function phptemplate_disks($arg1) {
$output = theme_disks($arg1);
return preg_replace('/discography/', '/disk-data/', $output);
}

Instead of copying all the code of the base function in the overriding function, and
modifying ONE line in it, we call the base function and using regular expressions we modify
its output to our liking. Although this solution may result in less code lines, and hence less
memory allocated to PHP, it doesn’t improve performance. Note : To override a function,
we have to understand what’s going on in the base theme function. If the function is
way too complex, or it’s not possible to edit the code to achieve what we want, we may
instead modify the resulting XHTML with regular expressions, the way we’ve just seen.

The PHPTemplate engine is NOT the theming system


We will now start to talk about Drupal’s theming system. That system is defined in the
php file includes/theme.inc. The main purpose of the theming system is to issue calls
to the appropriate theme engine — or to the appropriate theme that does not rely on any
engine. We should not confuse the theming system with the phpTemplate engine. The
later is in themes/engines/phptemplate.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
The theming system and its router function theme()
The theme() function is called with a hook and some data to theme — and possibly a few
boolean values that will tell us something about the context in which the content is to
be themed. The hook is a word or many_words that describe what is being themed. The
theme() function has to make a decision as to what function it should call with the data.
It will check whether three functions are defined in a particular order. As it runs through
its check list of functions, as soon as it discovers one function that’s defined, it stops there
and calls that function — and that’s The End. Let’s imagine that the name of our default
theme is funky, and that the function theme() is called with the hook dream_entry :

print theme('dream_entry', $dream_content);

Our first stop will be to ask : does the function funky_dream_entry exists ? Bingo, let’s
use that function and we’re done. Or nope, it doesn’t. Ohhh-kaaay, second stop : does the
function phptemplate_dream_entry exists ? Yes ? Let’s use it. (That function would be
defined either in phptemplate.engine or in our theme template.php file.) Or no, it doesn’t
exist. If it doesn’t, we move on to our third and last chance terminus : is there a function
with name theme_dream_entry ? (That would the base theme function.) Yes. Finally.
Now, let’s look at the code. Open up includes/theme.inc at line 161 and follow along.
You’ll have noticed that the function theme() can be invoked with any number of
arguments, one or ten. To define a function that may be called with any number of
arguments of any type, we use empty parenthesis in the definition and invoke the php
function func_get_args() to retrieve the arguments and store them in an array :
function theme() {
static $functions;
$args = func_get_args();
For your information, the php keyword static is used to define a variable whose value does
not die when the function terminates, but survives (and is modifiable, of course) “over”
several calls to the function — until index.php with its truck load of included files is totally
parsed to its last shed of blood. Here, the static variable $functions will be an array that
stores function names. For each hook, there is one function to call, and $functions[hook]
will give us the name of that function. The very first time the theme() function will be
called, $functions will know nothing. With each call, we’ll teach it a new trick, and as we call
it more and more, it’ll become increasingly knowledgeable. Let’s retrieve our hook :
$function = array_shift($args);

Let’s pretend there has been a call to theme('page', $content). At this point, $function
should be equal to page and $args should contain only one element left : $content.
We’d like to know which function to call with that hook (page) and that data ($content).

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 
Does our monkey $functions know which function to call, or is it the first time it’s being
asked ? In the case of crass ignorance, we teach our monkey a new trick :
if (!isset($functions[$function])) {

$functions[$function] = theme_get_function($function);

The function theme_get_function(hook) is The Router. Running through its check


list, as fast as it can — with the aid of php function function_exists() —, the Router
determines which function should be called for a particular hook. Then it tells the monkey.
And our monkey remembers that information for the next time theme() is called with the
same hook. We’re talking efficiency. Remember : our monkey will remember because it’s
static — and, because it’s static it will remember until index.php is completely parsed and
a HTML document is sent back to the browser. Then it will die.
Let’s jump into The Router. To the function theme_get_function($function), we’ll pass the
value ‘page’, that is, our hook. To follow along, know that $theme and $engine are global-
scope variables that provide us with the name of the default theme and the name of its
theme engine, respectively. We’ll skip a few lines of code to cut to the decision making :
if (($theme != '') && function_exists($theme .'_'. $function)) {
// call theme function If a theme exists, and the function funky_page
return $theme . '_' . $function; has been defined then we’ve got what we want and
we’re out of here.
}
elseif (($theme != '') && isset($theme_engine) && function_exists($theme_
engine . '_' . $function)) { If a theme exists and it’s powered by a theme
// call engine function engine, then we’ll call the function that starts
return $theme_engine .'_'. $function;
with the engine’s name as in : phptemplate_page,
and we’re done.
}
elseif (function_exists('theme_'. $function)){
// call Drupal function We are left with no other alternative than to
call the blah themeable function defined in the
return 'theme_' . $function;
blah module, i.e. the theme base function called
} theme_page.
Finally, back to Stillwaters, we get to actually call the function that will return themed
content, i.e. XHTML to ship to the browser. (Line 172).
$output = call_user_func_array($functions[$function], $args);

That’s a very cool The function to be called, for The parameters to be passed
php function ! example “phptemplate_page” to that function as an in-
dexed array, i.e. the beef!

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 10
The page example : from index.php to an XHTML document
There’s one function call that generates all the XHTML that’s sent to the browser. That
function call is in index.php on line 33 :
print theme('page', $return);

That call is issued to our Router, the function theme(hook, ...).


Funky
Core PHPTemplate engine Theme
Theming system page.tpl.php
phptemplate.engine
theme.inc

function theme()
_phptemplate_render($file, $variables)
We start here ->
[+ style.css, templates
+ default template files and template.php]

no Do I have a theme ? Yes.

What is my theme ? Funky.


If it had been defined for
Has the function funky_page been defined ?
our phptemplate theme, it
would be in template.php.
YES then EXECUTE funky_page($return)
NO

no Am I using a theme engine ? Yes.

What is my theme engine ? PHPTemplate. If it had been defined for our phptemplate
theme, it’d be either in phptemplate.engine
Has the function phptemplate_page been defined ? or in our theme’s template.php file.

YES then EXECUTE phptemplate_page($return)

You will find a phptemplate_page function in phptemplate.engine and that function calls
NO in the page[-something].tpl.php file, in this instance the page.tpl.php file of our theme.
theme_page() is defined
Then call the base theme function theme_page($return) in includes/theme.inc

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 11
How and where to override themeable functions
Given that we want to override the themeable function theme_book_
navigation($node), defined in modules/book/book.module. Our hook is “book_
navigation” and our data to be themed is $node, i.e. a node object. Given that our
default theme is a PHPTemplate theme with name funky, we may override our
themeable function in one of these three ways :
 Define a funky_book_navigation($node) function in our theme’s template.php file.
We have to create such file if it doesn’t exist already — right inside our theme folder.
We are often recommended against using such method because it prevents us to later
re-use our theme’s template.php file if another theme is created based on our theme.
 Define a phptemplate_book_navigation($node) function in our theme’s template.
php file. We have to create such file if it doesn’t exist already — in our theme’s folder.
 Create a template file (of the form __.tpl.php) for our book navigation and let the
PHPTemplate engine know about it. This method will be described in details in the
section ‘Template files you need to tell Drupal about’.

How to know which function to override : The Trick


If we want to know which themeable function outputs what on the page, we can hack the
core temporarily so that HTML comments are written throughout the page to indicate to
us what function generates what markup. It’s very handy. Open the file includes/theme.inc
in your text editor. Around line 169, modify the function theme() from this :
if ($functions[$function]) {
return call_user_func_array($functions[$function], $args);
}
To that :
if ($functions[$function]) {
// Modified by {YOUR_NAME}
// return call_user_func_array($functions[$function], $args);
$output = call_user_func_array($functions[$function], $args);
if (trim($output)) { // After removing white space, do we have something?
return "<!-- BEGIN:". $functions[$function] . "-->\n" . $output .
"\n<!-- END:" . $functions[$function] ."-->\n";
}
}

Don’t forget to eventually undo this change as it makes the web page heavier to download.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 12
3/ea » Template files you don’t need to tell Drupal about
We don’t need to tell Drupal about the existence of template files that the PHPTemplate
engine looks for automatically, in “phptemplate_” overrides. The engine will look for a
template of the form page[-something].tpl.php in the theme folder ; whenever a node is
displayed, it will also look for a node[-something].tpl.php template in either our theme
folder, or the engine’s folder (in the latter case, that would be node.tpl.php). It will also
search for the appropriate block[-something].tpl.php file when a block is output to screen.
Finally, it will use our versions of box.tpl.php and comment.tpl.php if we have them, or rely
on its own default templates, to render content-in-a-box and comments. For example,
when theming a comment with that call to the Router theme() function :
print theme('comment', $comment, $links);

The theming system finds that an override is defined in phptemplate.engine on line 303, and
that override indicates that a template file has to be used with a list of variables :
function phptemplate_comment($comment, $links = 0) { .... }

Page templates you don’t need to tell Drupal about


The PHPTemplate engine has changed from Drupal 4.7 to Drupal 5 in how it looks for
page templates. The engine now builds a list of suggested templates to look for, and does
so dynamically, using the internal path to display. The engine looks for a file with a name
provided within an array of suggested names, a list ordered by specificity and which items
depend on what page is displayed. The process is described in the function phptemplate_
page() in phptemplate.engine, right before the code segment that builds the “suggestions”.
For example, let’s say that we have to display the node with identifier 43 on a dedicated
page. The internal path is node/43. The engine will look for these files in that order :
If node/43 is the front page, it will look for page-front.tpl.php. The front page always gets
more specificity. If the engine doesn’t find such template file, or if we aren’t showing the
front page, the engine will then look for :
page-node-43.tpl.php and if it doesn’t find such template file, it will look for...
page-node.tpl.php and if it doesn’t find such template file, it will look for...
page.tpl.php and it will find that one as this template is required for a theme.
If admin/logs is the page to display, it will look for page-admin-logs.tpl.php, and if it does
not find it, it will look for page-admin.tpl.php. As last resort, it will fall back on page.tpl.php.
Take some time to go through the code that builds the suggestions on lines 241-252 of
phptemplate.engine, and do so with actual paths. An internal path is constructed like this :
arg(0)/arg(1)/arg(2)/arg(3) — and remember : the URL alias, if one is used, is not
the internal path, and the Drupal function arg() retrieves the different segments of the path.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 13
Node templates you don’t need to tell Drupal about
In Drupal 4.7 and 5, the PHPTemplate engine looks for these files in that particular order to
display, for example, a node of node type story :
node-story.tpl.php and if it doesn’t find that file, it will look for...
node.tpl.php in the theme folder, and, if it’s not there, it will
look in the engine folder for the default template.
The node type name is the “type” value you’ll find in the database table {node}.

Block templates you don’t need to tell Drupal about


In Drupal 5, the PHPTemplate engine will look for these files in that order to display a
block created by the views module to display the view popular_alltime in the left sidebar :
block-views-popular_alltime.tpl.php and if it doesn’t find that file, it will look for...
block-views.tpl.php and if it doesn’t find that file, it will look for...
block-left.tpl.php and if it doesn’t find that file, it will look for...
block.tpl.php in the theme folder, and, if it’s not there, it will
look in the phptemplate engine folder.
Notes
 In Drupal 4.7, the PHPTemplate engine only knows the block template block.tpl.php.
But we may inform the engine about templates it doesn’t know, and we will explain
how in the next section, ‘Template files you need to tell Drupal about’.
 To summarize, in Drupal 5, to theme a block created with a module with name module,
and with delta value delta, to show in the region region, the engine will look for
these files in that order : block-module-delta.tpl.php, then block-module.tpl.php, and
then block-region.tpl.php, and finally, as last resort, it will use block.tpl.php.
 Regions for blocks are defined in the phptemplate.engine file, by the function
phptemplate_regions(). However, these regions can be changed in the theme’s
template.php file, and we will see how in the section ‘Adding regions — semantic or
not’. If these regions are left as they are, we have : left, right, content, header, footer.
 When you are in doubt about any of these values : module, delta, region, look in
your database table {blocks} and try and find the block you want to give special theming
treatment to. If it’s active, its “status” will be equal to 1 for your theme.
 For your information, custom blocks created on the page admin/build/block/add fall
under the responsibility of the core module block.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 14
4/ea » Template files you need to tell Drupal about
We need to tell the PHPTemplate engine about any template it doesn’t know about. In the
last section, we gave names — file names — to all templates the engine will likely be on the
watch for. Any other template we’ll cover here.

Overriding a themeable function in a template : how


The value returned by phptemplate_page() and phptemplate_node(), in phptemplate.engine,
gives us a clue as to how we can let the engine know about a template file :
return _phptemplate_callback('page', $variables, $suggestions);

return _phptemplate_callback('node', $variables, array('node-'.$node->type));

What the hell, judging from how _phptemplate_callback() is called here, we can even offer
suggestions to the theme engine as to what files it can use with a third (optional) argument.
Say we want to override the themeable function theme_poll_results() defined by the (core)
poll module. And suppose that our default theme is funky. We would like to use a template
with name poll_results.tpl.php to generate the XHTML of the poll results.
Open your theme template.php file in a text editor. If such files doesn’t exist, create one. In it,
create the shell of your phptemplate override. That’s a piece of cake : copy and paste the shell
of the base theme function and change the word theme for phptemplate :
function phptemplate_poll_results($title, $results, $votes, $links, $block, $nid, $vote) {}

Within the brackets of the function’s definition, use the same return statement as the one
used in phptemplate_page() — but don’t provide $suggestions. Then change the first
argument from page to poll_results :
return _phptemplate_callback('poll_results', $variables);
The _phptemplate_callback function expects an associative array as 2nd argument, containing
all the variables to expose to the template with the file name specified as 1st argument.
Here’s our chance to pass more information, a few extra variables besides these received by
phptemplate_poll_results(). I am out of ideas now, so let’s stick to the variables we have. The
full-fledged function definition becomes :
function phptemplate_poll_results($title, $results, $votes, $links, $block,
$nid, $vote) {
return _phptemplate_callback('poll_results', array('title' => $title,
'results' => $results, 'votes' => $votes, 'links' => $links,
'block' => $block, 'nid' => $nid, 'vote' => $vote);
}
Finally, create a poll_results.tpl.php file in your theme folder and go nuts : write XHTML and
embed your variables using php. You can use all these : $title, $results, $votes, $links, etc.

http://www.11heavens.com/theming-drupal © 2007 Caroline Hill


page 15

S-ar putea să vă placă și