fromMarch 2012
Feature:

What's That PHP Doing In My Theme?

An Introduction to PHP and How it Applies to Drupal Theming
1

Simple themes typically only have a few tpl.php files, CSS and maybe some Javascript. The more complex your themes, the more PHP you will need to know. This article is a sneak preview of the hugely expanded 2nd edition of Front End Drupal. Find out more at http://www.frontenddrupal.com

Variables

In PHP you store data in named variables. Variables are little PHP storage units. When looking at code you can spot a variable because it begins with a dollar sign ("$"). For example: $muppet. PHP variables are a little bit like the HTML attributes that you see in tags. An HTML attribute has the structure: name="value". A PHP variable has the structure: $name = "Value";. Note: variables always begin with the symbol $ (and no, this doesn't change based on your currency). A line of PHP must always end with a semi-colon, and blocks of PHP code need to be surrounded by an opening "<?php" tag and a closing "?>" tag.

You may create your own storage unit with the following code:

<?php $name_of_my_new_variable = 'Value of my new variable'; ?>

You can change the value stored in a variable. There's no way to know for sure what's in a variable name by just looking at the name of the variable.

<?php
$muppet = 'Kermit';
$muppet = 'Miss Piggy';
?>

Give it a try!

We're going to enable a very dangerous module, PHP Filter, that allows you to put executable PHP code into nodes and blocks on your site. It's appropriate to use this filter on private web sites (sometimes called "sandboxes" because they're used for playing in), not public or live web sites.

In your Drupal sandbox site:

  1. Enable the module PHP filter.
  2. Ensure you have permission to use the PHP filter (People > Permissions).
  3. Using the content type "Basic page", create a new node and change the body field text format to PHP.
  4. Add the following PHP snippet to the body field:
    <?php
      // Create your variables
         $muppet = 'Kermit';
         $question = 'Question: Which $muppet sings: It\'s not easy being green.';
         $answer = "Answer: $muppet";
    ?>
  5. Save the new node. The variables will store information until you give the command to do something else with them. When you save the node, your page will appear blank even though you typed some stuff into the body field. Using a simple PHP function, print, let's make these variables appear.
  6. Edit your node and add the following snippet after the first one:
    <?php
      // Print your variable contents to the page:
       print $question;
       print $answer;
    ?>
  7. Save your node again.

Your muppets now appear on the page! Note what happens when you use 'single quotes' vs. "double quotes" -- variables don't get expanded when placed within single quotes.

Arrays

Variables can also contain a collection of values. These collections are referred to as arrays of data. (There are other types of collections, but we'll just be working with arrays for now.)
An unsorted array is created as follows. Note the function name, array, and the round brackets. Items are separated by a comma.

$muppets = array('Kermit', 'Miss Piggy');

To print all items in the array use the special PHP function print_r().

print_r($muppets);

Arrays can contain arrays. For example:

$muppets = array(
  array('Kermit', 'Miss Piggy', 'Camilla the Chicken'),
  array('Janice', 'Scooter', 'Swedish Chef', 'Dr. Teeth'),
  array('Foo Foo', 'Rowlf the Dog'), // terminating comma is okay here
);

Muppets Array

To access each item in the array you would need to memorize the order the data was entered and then retrieve it by position. This is very inefficient. Fortunately arrays have a second way to store data: with keys. The key allows you to access an array element with a name instead of a location within the array.
For example:

$muppets = array(
  'animal' => 'Kermit',
  'human' => 'Janice',
  'dog' => 'Foo Foo',
);
print $muppets['animal']; // displays Kermit
print $muppets['human']; // displays Janice
print $muppets['dog']; // displays Foo Foo

Muppets Array Keys

To change the values stored in an array you can target specific items by using the square brackets in the assignment. For example, let's say we wanted to store Miss Piggy, instead of Kermit, for the animal item of the array:

$muppets['animal'] = 'Miss Piggy';

Printing Formatted Output

If you have the special helper module Devel installed you can use the function dsm() instead of print_r() to reveal the structure of a variable. This is a great way to do "forensics" on Drupal theme variables.

Drupal Themes

When you peek inside the Bartik template file page.tpl.php, you'll be able to spot the variable $page. This variable contains all of the regions for the theme. The region names (also listed in the theme's .info file) are the keys for the array. For example: the page.tpl.php variables $page['header'] and $page['sidebar_first'] are represented in the theme's info file as regions[header] = Header and regions[sidebar_first] = Sidebar first.
Let's build up a more complicated array. Take a close look at this snippet and see if you can spot the nested arrays in the new variable $my_menu_links.

$my_menu_links = array(
  'links' => $main_menu,
  'attributes' => array(
    'id' => 'main-menu-links', // adds id='main-menu-links'
    'class' => array('links', 'inline'), // adds class='links inline'
    ),
  'heading' => array( // adds <h2 class='element-invisible'>Main menu</h2>
    'text' => t('Main menu'),
    'level' => 'h2',
    'class' => array('element-invisible'),
    ),
);

Menu Links

Did you spot all five array()s? The variable $my_menu_links is an array containing three items (links, attributes, heading). Two of these items (attributes and heading) are themselves arrays and each contain an array of their own.

Using Functions

If you've looked inside a Drupal theme template file, you have probably bumped into some PHP functions. Functions store a group of commands that will be reused. You can recognize a function by its round brackets. The items inside the round brackets are the parameters the function will use to execute its code—passing a function different parameters is what makes code reusable.
In additional to all of PHP's built in functions, Drupal creates its own functions to deal with the specific tasks it needs to accomplish. In themes you will typically find the following functions:

Function name Purpose
array() Creates a new array. This is a PHP function.
hide() Prevents a nested variable within an array from being rendered. (The opposite of show()). This is a Drupal function.
print() Prints the subsequent statement to the file. This is a PHP function.
render() Prepares the HTML version of a given variable. This is a Drupal function.
show() Unhides a variable that was explicitly hidden so that it can be rendered. (The opposite of hide()). This is a Drupal function.
t() Exposes a snippet of text to Drupal translators. This is a Drupal function.
theme() Generates HTMLified "themed" output. This is a Drupal function.
unset() Destroys the specified variables. This is a PHP function.

Let's take a closer look at the the Drupal function, theme. (Remember our fully loaded array? Watch for it in this next snippet.)

theme('links', $my_menu_links);

In the theme function, the first parameter accepted is the name of the theme hook (links); the second parameter is the data to be themed (our fully loaded array, $my_menu_links). Once Drupal has done its business it returns a snippet of HTML that you can print to the page. In theme files you will typically see something to the effect of: print theme($hook, $variables). The variables $hook and $variables will, of course, be replaced by actual data.
Functions are very powerful, but in your theme's tpl.php files they are typically restricted to assembling and printing data. It is a lot more common to see PHP conditional statements in your theme’s tpl.php files.

Conditional Statements

The code displayed in your theme's template files might not actually be used some of the time. For example: if in administrative settings page for your theme you disabled the breadcrumbs, they will never appear on your site even though there's code to print out the variable in the template. Crazy, right? This is due to the power of the conditional statement.
In PHP you can create "conditions" (or "ultimatums" if you prefer) for your code to run. Your conditions are essentially a series of tests that can be answered with a "yes" or "no" answer. For example: IF you are displaying the teaser for this node, THEN print only the fields I specified in the Manage Display tab for this particular view mode.
To create your tests you will use one of the following:

Symbol Test
== if left is equal to right
!= if left is not equal to right
=== if left is equal to Boolean value on right (TRUE, FALSE, NULL)
!== if left is not equal to Boolean value on right
isset() if a specific variable exists and has a value
empty() if a specific variable exists but does not have a value
in_array() if a value is in the array you are testing
&& combine two tests; both must be true
|| combine two tests; at least one must be true

One of my favorite mistakes is to use a single = (instead of double) when trying to compare two items. The single = will reset the value of the first variable and the condition will always be true. Whoops!
With the basics of how to build tests you can now create appropriate wrappers around the code you want to run for each of your special conditions. The basic structure is as follows:

if ( your condition ) {
 // code to execute if the condition passes
}

It can also be written with the following syntax, using words instead of brackets:

if ( your condition ):
 // code to execute if the condition passes
endif;

Specifically:

if ($muppet == "Kermit") {
     // code to execute if the muppet is Kermit
}

In a theming context, a conditional statement looks like this:

<?php if (isset($breadcrumb)): ?>
  <div id="breadcrumb"><?php print $breadcrumb; ?></div>
<?php endif; ?>

There are further shortcuts, of course, because programmers love to be lazy! If you were to look at the file page.tpl.php in Bartik you would see the function isset is implied and the snippet is actually:

<?php if ($breadcrumb): ?>
  <div id="breadcrumb"><?php print $breadcrumb; ?></div>
<?php endif; ?>

Armed with knowledge of variables, arrays, functions and conditional statements you are ready to tackle the customization of your favourite theme!

Learning More

With this basic understanding of what a variable is take a look at the variables that are available in the default page and node templates:
http://api.drupal.org/api/drupal/modules--system--page.tpl.php/7
http://api.drupal.org/api/drupal/modules--node--node.tpl.php/7
To your reference file add a list of the variables that are created by Drupal. You may also want to create a new file to store this list of variables.
There are two main references for PHP information:
http://php.net/docs.php
http://api.drupal.org
Treat them as a dictionary and search for the word you're trying to understand.

Comments

Appreciated. Thanks.