Theming - Reference Model

povertywhyInternet and Web Development

Nov 18, 2013 (4 years and 1 month ago)

164 views







2008


Byelex Multimedia B.V.


Johnny van de Laar


[
DRUPAL BEST
PRACTICES
]

This document contains a number of

best practices
for the

Drupal Content Management System
,
version
5
,

this document
focuses

on
best practices
for theming websites
.

P a g e

|
2



Table of content

Introduction

................................
................................
................................
................................
................................
...
4

Setting up your Drupal environment

................................
................................
................................
.......................
5

Installing and configuring Drupal, Apache, PHP and MySQL

................................
................................
.........
5

How to use .htaccess

................................
................................
................................
................................
..............
5

Clean URLS

................................
................................
................................
................................
...............................
5

The white screen of death
................................
................................
................................
................................
.....
5

Them
ing

................................
................................
................................
................................
................................
..........
6

Installing a Drupal theme

................................
................................
................................
................................
.......
6

Node theming

................................
................................
................................
................................
...........................
6

Variable reference

................................
................................
................................
................................
............

15

Sending additional variables to the node template

................................
................................
..................

16

A different template file for a specific node

................................
................................
..............................

21

Theming a CCK Content type

................................
................................
................................
......................

23

Page theming

................................
................................
................................
................................
..........................

31

Variable
reference

................................
................................
................................
................................
............

37

Regions

................................
................................
................................
................................
...............................

39

Menu theming

................................
................................
................................
................................
...................

40

Breadcrumbs theming

................................
................................
................................
................................
.....

40

Search box theming

................................
................................
................................
................................
.........

40

A different template file based on a specific URL
alias

................................
................................
...........

40

Views theming

................................
................................
................................
................................
.......................

40

Forms theming

................................
................................
................................
................................
.......................

41

Module theming

................................
................................
................................
................................
....................

41

Security

................................
................................
................................
................................
................................
........

42

Website performance

................................
................................
................................
................................
..............

43

Reasons for performance updates

................................
................................
................................
....................

44

Client side optimizations

................................
................................
................................
................................
....

45

Decrease the amount of HTTP requests

................................
................................
................................
...

46

Decrease the amount of data that has to be downloaded

................................
................................
.....

59

Server side optimalisaties

................................
................................
................................
................................
...

62

Server side caching

................................
................................
................................
................................
..........

64

Opcode cache

................................
................................
................................
................................
...................

71

Throttling

................................
................................
................................
................................
...........................

75

P a g e

|
3


Search Engine Optimization

................................
................................
................................
................................
....

76

Redirects

................................
................................
................................
......

Error! Bookmark not defined.

Tips and tricks

................................
................................
................................
................................
............................

98

Sources

................................
................................
................................
................................
................................
........

99




P a g e

|
4



Introduction

This document discusses a number of techniques that should
help with

developing and designing
Drupal websites. To understand the concepts of this document the reader is required to have a
decent understanding of HTML
,
a
basic understanding of PHP and
a basic understanding of
th
e
concepts of Drupal
.

If you don’t know that a

Node or a Taxonomy is then you should look on the
Drupal handbook pages mentioned below. If you don’t know what an
if

statement is or what
print
'hello world'
;

does then you should read the PHP tutorial named below.

Most of the PHP functions
,

used in thi
s document will be described

in more detail,

but in case the
user
does not

understand
certain functions,

more information
about these functions can be found on
the following

websites:



http://www.php.net



officia
l
PHP

website
.



http://api.drupal.org



official documentation website of the PHP code in
Drupal
.

Please be aware that PHP specific functions
can be found

on the official PHP website and Drupal
specific functions
can be foun
d
on the Drupal documentation website.

More information about the
Content Management Syst
em Drupal
can

be found here
:



http://www.drupal.org



official

Drupal

website
.



http://
drupal.org/handbooks



official Drupal ha
ndbook website
.

Tutorials on PHP, HTML, CSS, etcetera can be found here
:



http://www.w3schools.com



website co
ntaining tutorials on various web languages
.

This document
discusses Drupal version 5
.
Reason for discussing version 5 instead of version 6 is
that most websites are still
being
built on Drupal 5. Most of the concepts still apply for Drupal
version 6.

In this document it’s assumed that the user uses

a new, unmodif
ied Drupal version 5 installation with

the standard Garland theme and the PHPTemplate Drupal
template

engine. Most concepts will also
work for other themes

based on the PHPTemplate engine
.
Most of t
he concepts will
not

work for
the Smarty or XTemplate engi
ne
,

which

also
are
available for
usage in
Drupal.

The document is divided in separate sections:

1.

Setting up your Drupal environment

2.

Theming

3.

Security

4.

Search engine optimization

5.

Website performance

6.

Tips and tricks

These 6 sections will describe the basics
behind building a Drupal website.


P a g e

|
5



Setting up your Drupal environment

Installing and configuring
Drupal, Apache, PHP

and

MySQL



http://drupal.org/getting
-
started/5

How to use
.htaccess


Clean URLS


The
white screen of death



P a g e

|
6



Theming

Creating

a

Drupal theme

More information about installing Dru
pal can be found
in the Installing and configuring Drupal,
Apache, PHP and MySQL chapter.


After installation the standard Garland theme will be used
by Drupal.
T
his theme can be found
in
your Drupal installation directory,
on this path

/themes/garland

(path is relative to the Drupal
installation path)
.
To make themin
g easier it i
s recommended to copy the Garland theme
inside

the

websites directory in the

/sites

directory
. For example
/sites/
company
x
.com
.
Inside this
sites

directory
a
themes

directory should be
created in which the theme will be put
, for example
/sites/companyx.com/themes/companyx
.

Where the
companyx

folder will contain the theme.

This makes the
theme only available to
the

website

in which it is placed
,
thus
in the example above
this means
the company
x.
com

site.
This concept has a number of advantages
:



If there is a new minor release of Drupal, for example drupal 5.0 is updated to 5.1, th
e
Drupal instance can be updated by uploading the
entire
content of the Drupal archive and
running
update.php
. The theme will not be overwritten by this action
,
while
this would
happen if you are using the Garland theme without copying it,

and therefore the theme
doesn’t have to be updated/changed after an update
.



In
a

Multi site
installation
,
an installation where multiple
Drupal
web
sites
use the same
Drupal installation
,
the
theme
will only be available for the website in which the theme
is
placed, for example the
http://companyx.com

website
.


In
situations where company

x has multiple websites sharing a layout one might want to
share the

theme, instead of having a copy of the theme in 2 folders.
This i
s possible if you
place the theme in the
all

directory.
The theme should be placed in a directory like this:
/sites/all/themes/
company
x
.

Node

theming

Drupals most important building
b
lock is the
node
.
Most of t
he content of Drupal is stored in
node
s
,
for
example a

p
age,
s
tor
y
,
event
, etcetera

will be stored as a node
. This chapter discusses how
node
s
can be themed.
Some of t
he concepts of
node

theming can be reused in other parts of Drupal
theming
like page theming. Therefore
reading this chapter is crucia
l for a good understanding of the

basics behind

Drupal
s

theming methods.

The easiest way to theme a

node

is to go inside the theme folder and modify
th
e
node
.tpl.php

file
.

Modifying this file will change the appearance of all
node
s throughout the system, t
his means for
node
s of every content type existing in the system.

Nodes can be made for specific purposes, these
specific purposes are called content types. A content type can be a story, page, event, etc. Each
content type can have individual settings, fi
elds ,etcetera.



P a g e

|
7


In case
you want to modify the layout of only one content type,
a copy of the
node
.tpl.php

file
should be made
and rename
d

to include the name of the content type
.
For example if the user wants
to modify
the appearance of the
p
age content type then th
e user should copy the

node
.tpl.php

file

in
to
node
-
page.tpl.php
.
The

node
-
page.tpl.php

file will only be used for
node
s
of the
p
age
content type
while all other content types will still use the
node
.tpl.php

file
.

Later in this chapter a
method to theme an individual
node

will be described.

Inside the

node
.tpl.php

file you can find the following
PHP/HTML code
:


<?php phptemplate_comment_wrapper(NULL, $
node
-
>type); ?>


<div id="
node
-
<?php print $
node
-
>nid; ?>" class="
node
<?php if ($sticky) { print ' sticky'; } ?><?php
if (!$status) { print '
node
-
unpublished'; } ?>">



<?php print $picture ?
>



<?php if ($page == 0): ?>



<h2>


<a href="<?php print $
node
_url ?>" title="<?php print $title ?>">


<?php print $title ?>


</a>


</h2>


<?php endif; ?>



<?php if ($submitted): ?>


<span class="submitted">


<?php print

t('!date
-

!username', array('!username' => theme('username', $
node
), '!date' =>
format_date($
node
-
>created))); ?>


</span>


<?php endif; ?>



<div class="content">


<?php print $content ?>


</div>



<div class="clear
-
block clear">


<
div class="meta">



<?php if ($taxonomy): ?>




<div class="terms"><?php print $terms ?></div>



<?php endif;?>


</div>



<?php if ($links): ?>


<div class="links"><?php print $links; ?></div>


<?php endif; ?>


</div>


</div>

</
div>

P a g e

|
8


The code on the first line
:
phptemplate_comment_wrapper(NULL, $
node
-
>type);

should be
ignored
,

as this is only used for setting a number of variables for the comment fields. This code itself
doesn’t display anything. The rest of the file can be modified without any problems.

The following line
:

<div id="
node
-
<?php print $
node
-
>nid; ?>" class="
node
<
?php if ($sticky) { print '
sticky'; } ?><?php if (!$status) { print '
node
-
unpublished'; } ?>">

i
s used for wrapping
a

div
container
around the
node
.
Inside this code snippet

you
will

find a
number of interesting things.

T
he following part of the
above sn
ippet
:

<?php print $
node
-
>nid; ?>

contains the
print

function
.

The
print

function is used in PHP to output a value

to the browser
. This value can be a variable, the
result of a feature call or
the result of
a calculation. In this situation the
print

statement outputs the
value of a variable (
nid
) that is inside an Object (
$
node
). If
nid

has the value 12 the

result of this
action will be
that
<div id="
node
-
<?php print $
node
-
>nid; ?>"
is replaced by

<div id=”
node
-
12
.


$
node

is
an

O
bject
, Objects are structures that contain variables and functions
,

inside Drupal
version
5
Objects
a
lmost never
contain
functions.

Inside Drupal Objects are only used for storing data, this
design pattern is also known as Data Transfer Objects
(DTO’s).


To
retrieve

the contents of
a
$
node

Object
,

the
print_r

function can be used.
T
he
print

statement

displays a single
value, the
print
_r

function can print the contents of an entire
Object (the r in

print_r
stands for recursive).


The
drawback

of using the
print_r

function
, as in the snippet above,

is that it can gene
rate a lot of
unformatted output.
There are two ways to handle this.

Outputting the contents as a

HTML

comment:

Outputting the contents inside
pre
-
tags:

The
htmlspecialchars

function will translate HTML tags inside the
$node

Object to characters that
can be shown on the webpage. Without this function HTML tags inside the
$node

Object will be
rendered to the screen, by which the output of
the page can become messy
.


<?php
print_r($node);

?>

<!
--
<?php
htmlspecialchars(print_r(
$node
, TRUE), ENT_QUOTES);

?>
--
>

<pre>
<?php
htmlspecialchars(print_r(
$node
, TRUE), ENT_QUOTES);

?>
</pre>

P a g e

|
9


The output of
the
print_r

function

will look like this:

stdClas
s Object

(


[nid] => 26


[vid] => 26


[type] => page


[status] => 1


[comment] => 0


[promote] => 0


[sticky] => 0


[title] => Test123


[body] => <
p
>test</
p
>


[format] => 1


[uid] => 1


[name] => admin


[picture] =>


[path] => content/test123


[files] => Array

()


[field_image] => Array

(


[0] => Array (


[fid] => 1


[title] => Photo 19.jpg


[alt] => Photo 19.jpg


[nid] =>

26


[filename] => Photo 19.jpg


[filepath] => sites/default/files/Photo 19.jpg


[filemime] => image/jpeg


[filesize] => 64112


[
view
] =>


)



)


[taxonomy] => Array (


[12] => stdClass Object (


[tid] => 12


[vid] => 6


[name] => type a


[description] =>


[weight] => 0



)


)


[readmore] =>


[content] => Array (


[field_image] => Array (


[#access] => 1


[#value] =>


[#weight] => 0


[#printed] => 1


)


[body] => Array (


[#weight] => 0


[#value] => <
p
>test</
p
>


[#printed] => 1


)


[#children] => <
p
>test</
p
>


[#printed] => 1


)


[links] =>

Array ()


)

P a g e

|
10


The first line immediately displays a crucial
piece

of information:
“Object”.
This is crucial information
for the user to determine how the variables inside the Object can be accessed. To

access a variable
inside an Object the

-
>

operator

should be used
.
For example to access the
node

identifier,
nid
,
$
node
-
>nid

should be used
.

At the end of the
variable

print
out

the following statement can be found
:
[field_image] => Array
.
Instead of “Obj
ect” the word
“Array “
is used here. This tells
the user
that the variable
field_image

is of type Array. Describing the difference between Arrays and Objects isn’t within the scope of this
document. More information can be found on the PHP website
,

m
ore
information on Arrays can be
found here:

http://php.net/manual/en/book.array.php

and more information on Objects can be found
here
:
http:
//
php.net/manual/en/book.classobj.php
.

A variable inside an Array cannot be accessed
by

the
-
>
operator. It should be called by wrapping
the variable name with

[
'

and

'
]
.

In the
variable printout

on the previous page the
field_image

variable is a
CCK
field

containing an image. The
field_image

variable contains a number of variables,
for example the
file identifier,
fid
.
The

fid

variable
can be accessed
via

the
$
node

variable,
in this
$node

variable by
getting the
field_image

and within the
field_image

you can access
the

fid

variable.
Which ends up as
this statement
:
$
node
-
>field_image[
'
fid
'
]
.

Besides the
$
node

Object
also other variables are used in this line
:

<div id="
node
-
<?php print $
node
-
>nid; ?>" class="
node
<?php if ($sticky) { print '
sticky'; } ?
><?php if (!$status) { print '
node
-
unpublished'; } ?>">

F
or example the

$sticky

variable
.

T
he earlier printed
$
node

O
bject
al
so contained this
variable
(
$
node
-
>sticky
).
This is due to the different ways
in which
variables are offered to the

Drupal
template

engine.
There does not
exist a guide
line
on

how to offer variables to the templat
e
engine, but
for the user
it
doesn’t matter a lot whether
$
node
-
>sticky

or
$sticky

is used.

To
ge
t

an over
view

o
f all variables inside a certain scope the
get_defined_vars

PHP function can be
used

like this:

This
snippet
will output all the variables that are active in the current scope

as a HTML comment
. If
this snippet is used in a
node
.tpl
.php

file, or a variation of this file for a specific content type, then
the current scope is the
node
.tpl.php

file.

<!
--
<?php
htmlspecialchars(print_r(
get_defined_vars()
, TRUE), ENT_QUOTES);

?>
--
>

P a g e

|
11


This will result in the same kind of
variable printout

as
contents of the
$
node

Object
.

S
ome variables
Array(


[file] => sites/default/themes/garland/
node
-
page.tpl.php


[variables] => Array (


[nid] => 26


[vid]

=> 26


[type] => page


[status] => 1


[comment] => 0


[promote] => 0


[sticky] => 0


[title] => Test123


[body] => <
p
>test</
p
>


[format] => 1


[uid] => 1



[name] => <
a

href
=
"/nl/user/1"
title
=
"
View

user profile."
>admin</
a
>


[picture] =>


[path] => content/test123


[files] => Array()


[field_image] => Array(


[0] => Array (


[fid] => 1


[title] => Photo 19.jpg


[alt] => Photo 19.jpg


[nid] => 26


[filename] => Photo 19.jpg


[filepath] => sites/default/files/Photo 19.jpg


[filemime] => image/jpeg


[filesize] => 64112


[
view
] =>


)



)


[taxonomy] => Array (


[taxonomy_term_12] => Array (


[title] => type a


[href] => taxonomy/term/12


[attributes] => Array (



[rel] => tag


[title] =>


)


)


)


[readmore] =>


[content] => <
p
>test</
p
>


[links] =>



[date] => Sat, 01/01/2000
-

01:00


[
node
] => stdClass Object
(


[nid] => 26


[vid] => 26


[type] => page


[status] => 1


[comment] => 0


[promote] => 0


[sticky] => 0


[title] => Test123


[body] => <
p
>test</
p
>


P a g e

|
12


are left out

of this printout
to reduce the size
.

Again a lot of variables are shown multiple times (if you lo
ok at the complete print
out then you’ll find
some variables even more times).

You

wi
ll
also
find a number of interesting variables by looking at
t
h
e printout.
For example the
$name

variable:

[name] => <a href="/nl/user/1" title="
View

user
profile.">admin</a>

T
his variable contains a link to

the user profile of the author of
this
node
.
This way all variables that are availabl
e to the current
theme can be found and it becomes a lot easier to theme the
current
node
.
The
contents of the
$name

variable can be
shown

by using the snippet on th
e right.

If you want to print the
$title

of the current
node

then multiple methods can be used.
Below two
methods

are
shown
, but
more
methods

are
possible:




Below the previously mentioned code snippet
,

in
node
.tpl.php
,

you can find this section:


<?php if

($page == 0): ?>



<h2>


<a href="<?php print $
node
_url ?>" title="<?php print $title ?>">


<?php print $title ?>


</a>


</h2>


<?php endif; ?>


The
$page

variable here contains a Boolean (true or false variable) that defines whether the currently
displayed
node

is shown on a
node

page (true), a page that you usually access with an URL like
/
node
/1234
, or when the
node

is embedded in for example a
View

(fal
se).

In the snippet above if the
$page == 0

is true then it means that the currently displayed
node

is
not

shown in a
node

page, thus
it’s shown in something like a
View
. When the
node

is shown in a
node

page the templating engine
itself will provide the l
ink with a title. The snippet above will print the title of the
node

(can be found
in the
$title

variable) and this title will be a link to the
node

page (the URL can be found in the
$
node
_url
variable).

Below the
$page

check part you can find this code sn
ippet

that prints out the username of the
author and the creation date
:


<?php if ($submitted): ?>



<span class="submitted">


<?php print t('!date


!username', array('!username' => theme('username',
$
node
), '!date' => format_date($
node
-
>
created))); ?>


</span>


<?php endif; ?>


<?php
print $name;

?>

<?php
print $node
-
>title;

?>

<?php
print $title;

?>

P a g e

|
13


This snippet checks whether the
node

is already submitted

to the database
, the
node

can also be
shown

in the pre
view

mode. If the
node

is submitted then the snippet

becomes true and it will print
the current da
te and username.


P a g e

|
14


Printing the data and t
he username is done on different way as mentioned before.
The content that
will be shown is first processed b
y the
t

function.
The
t

function is used for
translation of

its first
parameter

into another language
.

The
t

function will look up the parameter inside t
he translation
database and will search for a translation in the current language. If there isn’t a translation for the
current language then the
first
parameter
will be used. Otherwise the parameter will be replaced by
the database version, in the current language.

For example the snippet on the right. In case there is a
translation for the word “Hello” then the translation will be
shown.
Otherwise “Hello” will be

shown.

Then snippet in
node
.tpl.php

w
orks as follows
:

The
A
rray that is the second parameter contains a number o
f variables.
The
t

function will
iterate
over this Array and will
try to replace every occurrence of t
he label in the Array with the associated

value.
The labels in the array in the snippet are
'
!date
'

a
nd
'
!username
'
.

Thus in the first parameter

'!date


!username'

the strings
!date

and
!username

will be replaced

by respectively the date of
when the node was created and the username of the creator of the node
.

The ! character has a s
pecial meaning. It means that the !date string will be replaced without any
modifications.
There are 3 different characters that defi
ne how the string s
hould be replaced:

1.

!
-
variable: replace the string without modifying the replacing variable.

2.

@
-
variable: replace the string and remove all HTML conten
t from the replacing variable.

Important for security, read more about this in the
security chapter.

3.

%
-
variable: replace the string and wrap the replacing variable with
em
-
tags, to highlight the
value.

Sometimes variables will be a
lready translated and the
t

function isn’t needed. There is no standard
for this so you’ll have to find out

whether a string is already sent to the theme translated

by trial and
error.

Below this snippet you can find the block that displays the taxonomy terms:


<div class="meta">



<?php if ($taxonomy): ?>




<div class="terms"><?php print $terms ?><
/div>



<?php endif;?>


</div>


The
$terms

variable contains links to all terms
, which are placed inside

a
<ul>
, given that the
$taxonomy

variable isn’t empty
.


<?php
print t(
'
Hello
'
);

?>

P a g e

|
15



Variable reference

The following list contains a reference of variables that can be
used

in
node
.tpl.php

with a
description what value they contain/feature they represent.

This isn’t a complete list as additional
modules can add more variables to this

list
.
This list is based on the list that can be found here:
http://drupal.org/
node
/11816
.

$content

node

content, teaser if it is a summary.

$date

Formatted date

containing the creation date of the
node
.

$directory

The directory the theme is located in, e.g.
themes/garland

or
themes/garland/minelli
.

$id

The sequential index in a list. On a
node

page this will probably be 1 but in a
View

this
number will represent the index in the list
.

$is_front

True if the front page is currently being displayed.

$links

node

links
, e.g. a read more link
.

$name

Link

to the author profile page
.

$
node

(object)

The
node

object.

$
node
_url

URL

to
the
node
.

$page

True if the
node

is being displayed by itself as a page.

$picture

HTML for user picture, if enabled.

$sticky

True if the
node

is sticky.

$submitted

Author and create date information, if the
node

info display is enabled for this
node

type.

$taxonomy (array)

array of HTML links for taxonomy terms.

$teaser

Boolean to indicate whether to return the teaser rather than the full
node

text.

$terms

HTML for t
axonomy terms.

$title

Title of
node
.


$zebra

Alternates between odd/even in a list.


$
readmore

True if the node is in a teaser view and there should be a read more link
.



P a g e

|
16



Sending additional variables to the
node

template

If the available variables in the template aren’t sufficient then it is possible to send additional variables
to the
node

template. Of course it’s also possible to use PHP in the template file itself but there are a
number of reasons why you shouldn’t do t
his:

1.

By placing

the code is in a more

central position, the code can be reused by other
node
s.

2.

It’s easier to maintain the code afterwards if all code is placed on a central place, instead of
placing parts in the database, other parts in a template file an
d other parts in the
template.php as you don’t have to search for the code.

3.

By placing the
code in functions it becomes easier to reuse the code for other websites.

4.

Template files will be smaller and only contain the code that is used to display the
variables,
which will make the files easier to modify.

There exist several methods
for
send
ing

additional variables to a
node

this chapter will describe the
easiest one
, which is
not always the most powerful
and

the most efficient method
.

For this modification you will need to modify your
template.php

file. This file can be found inside
your theme directory (for example
/sites/
companyx.com
/themes/companyx
).
There are a number
of functions in
template.php
. One of them is the
_phptemplate_var
iables

function
. The function
will look as follows, if this in an unmodified Garland theme (certain modules require you to modify
the
_phptemplate_variables

file
:

As the comment on the top of this function implies, this function is used for sending variabl
es into
templates. The function as it comes with Garland only provides additional variables to page
templates. Therefore this function should be adapted for node templates.

/**


* Overrid
e or insert PHPTemplate variables into the templates.


*/

function _phptemplate_variables($hook, $vars) {


if ($hook == 'page') {



if ($secondary = menu_secondary_local_tasks()) {


$output = '<span class="clear"></span>';


$output .= "<ul cl
ass=
\
"tabs secondary
\
">
\
n". $secondary ."</ul>
\
n";


$vars['tabs2'] = $output;


}



// Hook into color.module


if (module_exists('color')) {


_color_page_alter($vars);


}


return $vars;


}


return array();

}

P a g e

|
17




P a g e

|
18


This function will be called a number of times per page view. And every time the
$hook

variable will
have a different value (e.g. page, node, block, etc). Therefore it is possible to make a separate block
of code per
hook

type. For the node
hook

you would have to add a section underneath the if
statement for the page template.

If for example you would like to have a variable in your template that adds a link to the node edit
page then the function would look lik
e this:

Be aware that you can have only
one

_phptemplate_variables

function in your Drupal instance.
Having two functions with the same name will result in an error, for more information about Drupal
errors see the white page of death chapter. You should a
lways modify your already existing
_phptemplate_variables

function

by adding the code snippets that contain the needed
functionality
.

The code that sends the extra variable to the templating engine creates a new item in the
$vars

Array. This Array contains

all variables that will be sent to the templating engine. This new item is
labeled with
'
node_edit_url
'

and receives the return value of the
l

function as value.

The
l

function creates a
HTML link to another page
. The first argument is the label for the link, in
the snippet above this becomes the translated version of the string ‘Edit’. The second argument is the
URL to which the link will point. If the second argument is a URL inside the same Drupal instance,
the
n Drupal will translate this URL to the generated path alias. Therefore you should always send
/**


* Override or insert PHPTemplate variables into the templates.


*/

function _phptemplate_variables($hook, $vars) {


if ($hook == 'page') {



if ($secondary = menu_secondary_local_tasks()) {


$output = '<span class="clear"></span>';


$output .
= "<ul class=
\
"tabs secondary
\
">
\
n". $secondary ."</ul>
\
n";


$vars['tabs2'] = $output;


}



// Hook into color.module


if (module_exists('color')) {


_color_page_alter($vars);


}


return $vars;


}


elseif ($hook ==
'
node
'
) {


$vars['node_edit_url'] = l(t('Edit'),'node/'.$vars['nid'].'/edit'
, array()
);


return $vars;


}


return array();

}

P a g e

|
19


URL’s in the original URL format (e.g.
node/123
, etcetera) and not the aliased path. Reason for this is
that an aliased path can change and therefore this method

could lead to broken links.



P a g e

|
20


The third argument is optional. In the example above this argument contains an empty Array.
Elements can be added to this Array and then these elements would appear as attributes in the link.
If for example the following arra
y would be used as third argument:

array(
'
class
'

=>
'
node
-
edit
-
link
'
)


Then the generated
a
-
tag would have ‘node
-
edit
-
link’ as
class
.

Other attributes are possible as well
(e.g.
id
,
rel
,
target
)

Additional variables
for the node template
can be added in
the same

way.

This value can be used in
the node template file via the
$node_edit_url

variable.

It is also possible to modify

existing variables
by using the

same

_phptemplate_variables

function
.

If for example you would want to modify the
$
name

variable to
point to an overview of all posts
made by this ruler, instead of a li
nk to the users profile, the following modification should be made
:

This snippet
above

uses the
$vars['node']
-
>name

variable, that contains the account name of the
author, and
$vars['node']
-
>uid
, that contains the user identifier of the author.



/**


* Override or insert PHPTemplate variables into the templates.


*/

function _phptemplate_variables($hook, $vars) {


if ($hook == 'page') {



if ($secondary = menu_secondary_local_tasks()) {


$output = '<span class="clear"></span>';


$output
.= "<ul class=
\
"tabs secondary
\
">
\
n". $secondary ."</ul>
\
n";


$vars['tabs2'] = $output;


}



// Hook into color.module


if (module_exists('color')) {


_color_page_alter($vars);


}


return $vars;


}


elseif ($hook ==
'
node
'
) {



$vars
[
'
name
'] = l(
$vars[
'
node
'
]
-
>name
,'
user
-
posts
/'.$vars['n
ode
']
-
>uid, array()
);


return $vars;


}


return array();

}

P a g e

|
21



A
different template file for a specific node

With the
node
-
page.tpl.php

naming scheme of files it is possible to create a separate template file
for a particular content type. In case you would want a separate template for a specific node then
you have to m
odify your
template.php

file by modifying your
_phptemplate_variables

function.

If for example you would want a specific template fo
r the node with node identifier 28 then you
should make a copy of your
node.tpl.php

and name it
node
-
28.tpl.php
. Inside your
template.php

you should make a modification to the
_phptemplate_variables

function. If you
didn’t modify your
_phptemplate_variable
s

yet then this will look as follows
:

The snippet above will change the
selection method by

which template files are picked as follows:

1.

node
-
[nid]
.tpl.php

(where
[nid]

is replaced by the node identifier)

2.

node
-
[content
-
type].
tpl.php

(where
[
content
-
type
]

is replaced by the node content
type)

3.

node.tpl.php

(used i
f no other template file is found)

Meaning that the
template
e
ngine will first look for a template file with the pattern

node
-
[nid]
.tpl.php

and will then proceed down the list, until it finds a mat
ching template file.



/**


* Override or insert PHPTemplate variables into the templates.


*/

function _phptemplate_variables($hook, $vars) {


if ($hook == 'page') {



if ($secondary = menu_s
econdary_local_tasks()) {


$output = '<span class="clear"></span>';


$output .= "<ul class=
\
"tabs secondary
\
">
\
n". $secondary ."</ul>
\
n";


$vars['tabs2'] = $output;


}



// Hook into color.module


if (module_exists('color')) {



_color_page_alter($vars);


}


}


$vars['template_files'] = isset($vars['template_files']) ? $vars['template_files'] : array();


$vars['template_files'][] = 'node
-
'. $vars['nid'];


return $vars;

}

P a g e

|
22


It is also possible to create template files based on the created path alias. This can be done by the
following snippet:

The snippet above will change the selection method by which
template files are picked as follows:

1.

node
-
[
path
]
.tpl.php

(where
[
path
]

is replaced by the path alias of this node)

2.

node
-
[content
-
type].
tpl.php

(where
[
content
-
type
]

is replaced by the node content
type)

3.

node.tpl.php

(used i
f no other template file is foun
d)

In case the path alias consists of a number of directories (i.e. products/shoe) then the snippet above
will also use this directory structure. This would result in the template engine first attempting to find
node
-
products
-
shoe.tpl.php

and then
node
-
pro
ducts.tpl.php
.


/**


* Override or insert PHPTemplate variables into the templates.


*/

function _phptemplate_variables($hook, $vars) {


if ($hook == 'page') {



if ($secondary = menu_secondary_local_tasks()) {


$output = '<span class="c
lear"></span>';


$output .= "<ul class=
\
"tabs secondary
\
">
\
n". $secondary ."</ul>
\
n";


$vars['tabs2'] = $output;


}



// Hook into color.module


if (module_exists('color')) {


_color_page_alter($vars);


}


}


$vars['template_fi
les'] = isset($vars['template_files']) ? $vars['template_files'] : array();


if (module_exists('path')) {


if (isset($vars['path'])) {// if the path variable is already known


$alias = $vars['path'];


}


else {// otherwise attempt to get the alias


$alias = drupal_get_path_alias('node/'. $vars['nid']);


}


$add_path = '';


foreach (explode('/', $alias) as $path_part) {


$add_path .= !empty($path_part) ? $path_part : '';


$vars['
template_files'][] = 'node
-
'. $add_path;


}


}


return $vars;

}

P a g e

|
23



Theming a CCK Content type

The CCK module (Content Construction Kit) provides functionality to add additional fields to a
node. For example an additional text field with which you can add extra information like an address.

Theming a node m
odified by CCK can be done in a number of ways. The easiest way is
by using
only
CSS but this method is limited

in the way the layout can be changed
. Another way is modifying the
node template files, this approach takes some extra effort but
provides more
possibilities then CSS
theming.

In the example
used in this paragraph
a node with the following fields

will be used
:


These settings can be found on the following page:
http://drupal/admin/content/types/page/fields

(URL
will be different for your installation but this should give an indication about where to find this page).

The Address a
nd Image fields are CCK fields.

The Address field
is

made with
a
normal CCK text
fiel
d. The image field is made with the Image Field module. The Image Field module works together
with the Imagecache module. Image Field provides functionality to upload and display the image, the
Imagecache module provides functionality to process the image
by scaling, rotating, cropping,
etcetera the image. Within Imagecache it is possible to set multiple profiles for Imagecache. Each
profile contains a different set of actions that are executed on the image and for each image all
profiles can be applied. Th
e profiles will only be applied on the

image when the profile is used.


P a g e

|
24


You can set the Imagecache profile to use, and other

settings related to displaying CCK fields, on the
following page:


The page can be found on this URL:
http://drupal/admin/content/types/page/display

(the URL is just an
indication of where to find the page, the URL will be different in your own installation).

The
dropdown lists under “Label”, “Teaser” and “Full” describe
how the CCK field should be displayed.
By changing these values the output of the CCK fields will be modified.

The
content of the
CCK fields are accessible via the
$node

Object
. Accessing these variables
can be
done
via

a number of
different
methods.

T
he
$node
-
>field_address

and
$node
-
>field_image

variables

c
ontain the
values that where entered in the
CCK field
s
.

If the CCK field was left empty then these variables will not exist. Therefore checking whether these
variables exist is a good method for checki
ng whether the field was empty.

By using the
print_r
function
on the

$node
-
>field_address

variable
the
following
variable
printout is created
:







The
field_address

variable is an Array that contains another Array that is labeled with “0”.
Th
is
is
caused by the “multiple values” functionality of CCK. With CCK it is possible to reuse the same
CCK field a couple of times. For example to list multipl
e addre
sses or multiple images.



[field_address] => Array (


[0] => Array

(


[value] =>
street 1


[view] => street 1


)

)


P a g e

|
25


Within a single entry of the
field_address

Array you can find the
value

and the
view

variables.
The
view

variable contains the value how the CCK module would display this CCK field, every CCK
field type contains this value. The
v
alue

variable contains the unprocessed data of the CCK field.
The
value

variable can be used to process the output of this CCK field manually. The
value

variable
isn’t available in every CCK field type.

The
field_image

variable
and the CCK field itself are
created by using the Image Field module. By
printing out
the
$node
-
>
field_image

variable the following output is generated:


This Array contains t
he
view

variable is available
, just like it was for the address field
. This
view

variable displays the image inside an
img
-
tag.
In the
variable print
out above
,

the
I
magecache pro
file
that is used was the thumbs profile.



[field_image] => Array (


[0] => Array

(


[fid] => 1


[title] => Photo 19.jpg


[alt] => Photo 19.jpg


[nid] => 26


[filename] => Photo 19.jpg


[filepath] => sites/default/files/Photo 19.jpg


[filemime] => image/jpeg


[filesize] => 64112


[view] => <
img

src
=
"http://drupa
l/sites/default/files/imagecache/
thumbs
/sites/default/files/Pho
to 19.jpg"
alt
=
"Photo 19.jpg"
title
=
"Photo 19.jpg"
/
>


)

)

P a g e

|
26


The values of all the view variables of the CCK fields are also placed inside the
$node
-
>content

Array. The content of this Array is as follows:

The
field_image
,
field_address

and
body

variables contain the order in which the fields should be
printed (
#weight
), whether the field should be printed (
#printed
)
, whether the current user has
access to this field (
#access
)

and the value of the field (
#value
)
. These fields are formatted as
configured with the content type settings. The
#children

variable contains all fields combined.

To display the content of the CCK fields you could use the
$content
,
$body

or the
$node
-
>body

variables. T
he content of
all

CCK fields are merged together

in these variables together

with

the
content of the body field. Thus by displaying the
$content

variable the CCK fields will be shown

together with the body field.

If
you want to modify the appearance of one CCK field the
$c
ontent
,
$body

and
$node
-
>body

variables should not be used anymore in the template
.

Instead all fields should be shown separately,
by which each field can be modified individually.


[content] => Array (


[field_image] => Array

(


[#access] => 1


[#value] => <
div

class
=
"field field
-
type
-
image field
-
field
-
image"
><
div

class
=
"field
-
label"
>Image:&
nbsp;
</
div
><
div

class
=
"field
-
items"
><
div

class
=
"field
-
item"
><
img

src
=
"http://drupal/sites/default/files/imagecache/
thumbs
/sites/default/files/Photo 19.jpg"
alt
=
"Photo
19.jpg"
title
=
"Photo 19.jpg"
/
></
div
></
div
></
div
>


[#weight] => 0


[#printed] => 1


)


[field_address] => Array

(


[#access] => 1


[#value] => <
div

class
=
"field field
-
type
-
text field
-
field
-
address"
><
div

class
=
"field
-
label"
>Address:&
nbsp;
</
div
><
div

class
=
"field
-
items"
><
div

class
=
"field
-
item"
>
Street 1
</
div
></
div
></
div
>


[#weight] => 0


[#printed] => 1


)


[body] => Array

(


[#weight] => 0


[#value] => <
p
>
body
</
p
>


[#printed] => 1


)


[#children] => <
div

class
=
"field field
-
type
-
image field
-
field
-
image"
><
div

class
=
"field
-
label"
>Image:&
nbsp;
</
div
><
div

class
=
"field
-
items"
><
div

class
=
"field
-
item"
><
img

src
=
"http://drupal/sites/default/files/imagecache/
thumbs
/sites/default/files/Photo 19.jpg"
alt
=
"Photo
19.jpg"
title
=
"Photo 19.jpg"
/
></
div
></
div
></
div
><
div

class
=
"field field
-
type
-
text field
-
field
-
address"
><
div

class
=
"field
-
label"
>Address:&
nbsp;
</
div
><
di
v

class
=
"field
-
items"
><
div

class
=
"field
-
item"
>
Street 1
</
div
></
div
></
div
><
p
>
body
</
p
>


[#printed] => 1

)

P a g e

|
27


The following code snippet will show an example of a node template with all fields printed out
separately.

<?php phptemplate_comment_wrapper(NULL, $node
-
>type); //print_r(get_def
ined_vars()); ?>


<div id="node
-
<?php print $node
-
>nid; ?>" class="node<?php if ($sticky) { print ' sticky'; } ?><?php
if (!$status) { print ' node
-
unpublished'; } ?>">



<?php print $picture ?>



<?php if ($page == 0): ?>



<h2>


<a href="<?php
print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a>


</h2>


<?php endif; ?>



<?php if ($submitted): ?>


<span class="submitted">


<?php print t('!date


!username', array('!username' => theme('username', $node), '!date
' =>
format_date($node
-
>created))); ?>


</span>


<?php endif; ?>



<div class="address">


<?php print $node
-
>content['field_address']['#value']; ?>


</div>



<div class="image">


<?php print $node
-
>content['field_image']['#value']; ?>


</div>



<div class="content">


<?php print $node
-
>content['body']['#value']; ?>


</div>



<div class="clear
-
block clear">


<div class="meta">



<?php if ($taxonomy): ?>




<div class="terms"><?php print phptemplate_print_terms($node
-
>nid); ?><
/div>



<?php endif;?>



</div>




<?php if ($links): ?>


<div class="links"><?php print $links; ?></div>



<?php endif; ?>


</div>


</div>

P a g e

|
28


T
he snippet above
shows
the three fields
individually and
wrapped by a
div
-
tag.


P a g e

|
29


The code snippet on the previous page has one drawback and that is that the
2

CCK
fields will
already
contain

some theming
,

done by the CCK module

itself
. For exam
ple the

$node
-
>content['field_address']['#value']

variable
contains the following
value
:

<
div

class
=
"field field
-
type
-
text field
-
field
-
address"
>


<
div

class
=
"field
-
label"
>


Address:&
nbsp;


</
div
>


<
div

class
=
"field
-
items"
>


<
div

class
=
"field
-
item"
>


Street 1


</
div
>


</
div
>

</
div
>


The snippet already contains a

title
(
Address
)
and a number of
div
-
tags.

If you just want to use the content that the user typed in
,

while creating/editing the node
,

then you
need to
replace the following code:


<div class="address">


<?php print $node
-
>content['field_address']['#value']; ?>


</div>



<div class="image">


<?php print $node
-
>content['field_image']['#value']; ?>


</div>


by this code
:


<div class="address">


<?php print $node
-
>
field_address
[0]
['
view
']; ?>


</div>



<div class="image">


<?php print $node
-
>
field_image[0]
['
view
']; ?>


</div>


Note that the variable u
sed is

the

view

variable
and not
the
value

variable
. Reason for this is that
the
value

variable contains the da
ta exactly as it is typed in
, unfiltered
. The user could for example
enter

the following
javascript code
in
to

the address field:

<script type="text/java
script">alert('test');</script>


If you would have used the
value

variable instead of the
view

variable then the above javascript code
would have been executed on every page
containing this CCK field.

M
eaning that there would
appear

an alert window on
all these pages
.

By using the
view

variable CCK will automatically filter the
content of this fiel
d. More information about
this security

functionality can be found in the Security
chapter.



P a g e

|
30



The
$node
-
>
field
_image

variable contains
the
view

variable that points to a particular Imagecache
profile that was set on one of the content type configuration pages.
If you would want to display a
different Imagecache profile the following code can be used:

The
theme

function is a function that will call another function. This other function is indicated by the
first parameter,
imagecache

in this case. The other parameters will be forwarded to this
imagecache

function.

The return value of theme functions is HTML code,

in this case an
img
-
tag.

In the Imagecache module you will find a function named
theme_imagecache
. This is the function that
will be called by the above code snippet. The reason why the
theme

function is used, instead of
calling the
theme_imagecache

funct
ion directly, is that it is possible to overwrite the
theme_imagecache

function in the
template.php

file. If you place a
companyx_imagecache

function
in the
template.php

file, then the
theme_imagecache

function will be overwritten by the
companyx_imagecach
e

function.

The snippet shown above takes 5 parameters:

1.

medium



indicating the Imagecache profile that should be used

2.

$node
-
>field_image[0]['filepath']



i
ndicating the path to the original image file

3.

$node
-
>title



the value o
f the alt attribute

4.

$node
-
>
title



the value o
f the title attribute

5.

array('class' => 'medium_image')



a
rray containing additional attributes that should be
placed in the
img
-
tag

If you would want to overwrite the
theme_imagecache

function then you should place
, and modify,

the following code snippet in your
template.php

file (change the
companyx

string by the name of
your theme):



<?php
echo theme('imagecache', '
medium
', $node
-
>field_
image
[0]['filepath'], $node
-
>title,
$node
-
>title, array('
class
' => '
medium_image'));
?>

function
companyx
_imagecache($namespace, $path, $alt = '', $title = '', $attributes = NULL) {


$attr
ibutes = drupal_attributes($attributes);


$imagecache_path = file_create_url(file_directory_path() .'/imagecache/'. $namespace .'/'. $path);


return '<img src="'. $imagecache_path .'" alt="'. check_plain($alt) .'" title="'. check_plain($title)
.'" '. $at
tributes .' />';

}

P a g e

|
31


T
he following statement:

return '<img src="'. $imagecache_path .'" alt="'. check_plain($alt) .'" title="'.
check_plain($title) .'" '. $attributes .' />';


contains

the return value of the function. The return value is the result that you receive after calling
the function.

'<img s
rc="'. $imagecache_path

means that the f
irst piece of code,
'<img src="'
,
is merged with the contents of the
$imagecache_path

variable.

This means that the
$imagecache_path

variable will print the path to the image inside the
src

attribute. You could easil
y
wrap the
img
-
tag with a
div
-
tag just by adding these tags to this return statement. But be aware that
you should put the
div
-
tags between the quotation marks like the statement below:

return '
<div>
<img src="'. $imagecache_path .'" alt="'.
check_plain($alt) .'"
title="'. check_plain($title) .'" '. $attributes .' />
</div>
';

Page theming

Page theming generally works the same as Node theming.

If you want to modify a certain page, for
example
the page on which a node is shown. Then
the original
URL

of the page, the URL as it would
be without path aliases,

in this example
http://yourpage.com/node/123
,
determines how the
template file should be named
.
You make a copy of your
page.tpl.php

file and you nam
e it

page
-
node.tpl.php

if the theme should apply to all pages th
at contain
node

as a directory
in their
URL.
If you want the page theme only to apply for this node then you should also add the node
identifier in the file path:
page
-
node
-
123.tpl.php
.
The same strategy works for user profiles, etc.
Theming the page of all user profiles can be done with the file
page
-
user.tpl.php

and for one
specific user with the file
page
-
user
-
1.tpl.php
.

The frontpage (
http://yourpag
e.com
) is a special case. This page can be themed via

page
-
front.tpl.php
.

The standard Garland
page.tp
l.php

file contains the code

shown on the following pages. The
<!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 ?>">


<head>


<title><?php print $head_title ?></title>


<?php print $head ?>


<?php print $styles ?>


<?php print $scripts ?>


<style type="text/css" media="print">


@import "<?php print base_
path() . path_to_theme() ?>/print.css";


</style>


<!
--
[if lt IE 7]>


<style type="text/css" media="all">


@import "<?php print base_path() . path_to_theme() ?>/fix
-
ie.css";


</style>


<![endif]
--
>


</head>

P a g e

|
32


interesting parts of the
code
are
divided in multiple sections,
that

will be discussed separately
:


P a g e

|
33


The code
on the previous page
shows the head section of the page template. The head section p
rints
the page title (in the
$head_title

variable), the
$head

variable containing additional head tags (i.e.
meta tags, favicons, Internet Explorer specific javascript files), stylesheets (in the
$styles

variable),
javascript
code and files
(in the
$scripts

variable) and a separate stylesheet for printers and legacy
Internet Explorer browsers.

To add a stylesheet or some javascript to the page, you could modify the
template.php

file

and use
a special function that adds these files to the page
.

The ad
vantage of using this approach over using
HTML in the page template directly is that Drupal will be able to cache the javascript and the
stylesheets.

If you would want to add a stylesheet named
rounded
-
corners.css

and a javascript file named
liveclock.js

a
nd these files are placed in your themes directory

then
you should add the following

function
to your
template.php

(replace companyx with the name of your theme)
:

The following 4

functions where used:

1.

drupal_add_js
: adds a javascript to the page template
.

2.

drupal_add_css
: adds a stylesheet to the page template

3.

path_to_theme
: returns the path to the theme directory

4.

phptemplate_page
:

creates the variables
that are
used in page.tpl.php

The
'
theme
'

parameter used for the
drupal_add_js

and
drupal_add_css

functions, describes that
the javascript or stylesheet that is added, is a file and that it is a file

specific to the theme
. The files
are ordered based on this
'
theme
'

parameter. This is important because files with the
'
theme
'

parameter will overwrite f
iles with the
'
module
'

parameter, if they have the same name.

More
information about these functions can be found in the chapter about performance improvements.

For the
drupal_add_js

function the
'
theme
'

parameter could also be replaced by the
'
inline
'

parameter. The path to the javascript file can then be replace
d by a piece of javascript code. B
elow
is
an example
, note that the javascript is not wrapped by a
script
-
tag
:


function
companyx
_page($content, $show_blocks = TRUE) {


drupal_add_js
(path_to_theme().
'
/
liveclock.js
'
,

'
theme
'
,

'
header
'
);


drupal_add_
css(path_to_theme().
'
/rounded
-
corners.css
'
,

'
theme
'
,

'
all
'
);


return phptemplate_page($content, $show_blocks);

}

$js = "
if (Drupal.jsEnabled) {
$('p').addClass('paragraph');}

drupal_add_js($js,

'
inline
'
,

'
h
eader
'
);


P a g e

|
34


The following snippet, from
page.tpl.php
, prints the site logo and the site title:

In the example above the PHP code
first creates an Array. This Array contains the site name and the
site slogan. This statement:
$site_fields = array();

creates an Array.

This statement:
$site_fields[] = check_plain($site_name);

adds a
n element to the Array. The
if($site_name)

statement ch
ecks whether the
$site_name

variable contains a value
.

The
check_plain

function will remove all HTML tags from the parameter, this is important for the
sites security, read the security chapter for more details.

Text entered by a user should always be
chec
ked with this function.

By using the
implode

function PHP will merge all elements of the Array back together into one string
and will put a space between each Array element. So in case the
$site_name
variable contains the
value
“Company x”

and the
$site_sl
ogan
variable contains the value
“best service in town”
.
Then the result of the first implode function will be:
“Company x best service in town”
.

$site_fields[0] = '<span>'. $site_fields[0] .'</span>';
modifies the first element of the
A
rray and wraps this element with a
span
-
tag. The result of the second implode function will be:
“<span>Company x</span> best service in town”
.

The
check_url

function checks an URL on a number of security issues. URL’s entered by a user
should always be che
cked by this function.




<div id="logo
-
floater">


<?php


// Prepare header


$site_fields = array();


if ($site_name) {


$site_fields[] = check_plain($site_name);



}


if ($site_slogan) {


$site_fields[] = check_plain($site_slogan);


}


$site_title = implode(' ', $site_fields);


$site_fields[0] = '<span>'. $site_fields[0] .'</span>';


$site_html = implode(' ', $site_fields);



if ($logo || $site_title) {


print '<h1><a href="'. check_url($base_path) .'" title="'. $site_title .'">';


if ($logo) {


print '<img src="'. check_url($logo)
.'" alt="'. $site_title .'" id="logo" />';


}


print $site_html .'</a></h1>';


}


?>


</div>

P a g e

|
35


The following snippet contains the primary and secondary links. More information about menu
theming can be found further on in this chapter

in the menu theming paragraph
.

The following s
nippet prints the left sidebar, but
also checks if the left sidebar should be printed (if
the bar isn’t empty). If the sidebar isn’t empty, thus the sidebar is printed, then the snippet will also
check if the search box should be printed and if necessary
the snippet will print this box.

More below in the
page.tpl.php

file you can find a similar code snippet for the right sidebar:

The snippet again checks whether the search box should be printed. This check also verifies whether
the left s
idebar was printed, to make sure the search box is not printed twice.

More information about how the search box can be themed
, can be found in the search box theming
paragraph.



<?php if (isset($primary_links)) : ?>


<?php print theme('links', $primary_links, array('class' => 'links primary
-
links')) ?>

<?php endif; ?>

<?php if (isset($secondary_links)) : ?>


<?php print theme('links', $secondary_links
, array('class' => 'links secondary
-
links')) ?>

<?php endif; ?>

<?php if
($sidebar_left): ?>


<div id="sidebar
-
left" class="sidebar">


<?php if ($search_box): ?>


<div class="block block
-
theme"><?php print $search_box ?></div>


<?php endif; ?>


<?php print $sidebar_left ?>


</div>

<?php endif; ?>

<?php if ($sidebar_right): ?>


<div id="sidebar
-
right" class="sidebar">


<?php if (!$sidebar_left && $search_box): ?>


<div class="block block
-
theme"><?php print $search_box ?></div>


<?php endif; ?>


<?ph
p print $sidebar_right ?>


</div>

<?php endif; ?>

P a g e

|
36


The following snippet prints out the center section

of the page