Book Image

Drupal Multimedia

Book Image

Drupal Multimedia

Overview of this book

Table of Contents (16 chapters)

Advanced Theming


Because overriding the display of default content is essential in creating a professional site, we'll explore a few techniques that any serious developer or themer should keep in a toolkit. Template files are used to separate PHP code from the HTML, which is more familiar to many themers and designers. Sometimes we need to create custom regions, which also we will explore. And finally, we need to know how to override specific content at its most basic element, the theme function.

Adding a New Theme

It is certainly possible and sometimes preferable to start a new theme from scratch. However, for this book, we'll modify an existing theme to give ourselves a jumpstart.

From your FTP client, you'll need to make a copy of the Garland theme directory. You'll need to copy the entire Garland directory from /themes/garland to /sites/all/themes. Then rename the new Garland directory, for example to mytheme. This folder name will be used as the machine name of your new theme.

If you don't already have a themes directory in /sites/all, you'll need to make one first. When checking for themes, Drupal will look in the appropriate site directory such as /sites/example.com/themes. Then it will look in /sites/all/themes, and finally in the root /themes directory.

By placing contributed, custom, and overridden themes in the /sites directory, you can accomplish several things. First, it will override a theme in the root /themes directory. Secondly, if it is placed in /sites/all/themes, it will be made available to sites sharing the same codebase. (Conversely, it will only show up for a specific site if it isin something like /sites/example.com/themes.) Finally, it will be easier to update the site as Drupal evolves, since you will be able to simply update to a later version of Drupal without worrying about theme overrides in the root directory.

Note

As you may have noticed from this example, Drupal allows multiple sites to share the same codebase. In such a case, each site would need its own subdirectory within the /sites folder such as /sites/example.com for http://example.com, or /sites/mysite.com for http://mysite.com. Any further subdirectories within that folder will be made available only to that site. Additionally, multiple sites may even share the same database, assuming that they have separate database table prefixes specified in the Advanced options section during installation.

You will also need to change the garland.info file to mytheme.info (or whatever name you have chosen). Also, edit that file and change the line that reads name = Garland to read something like name = My Theme. (You will not have a .info file for your theme in Drupal 5, so this will not apply in that case.)

After creating your new folder and making the necessary changes, you will browse to Administer | Site Building | Themes (at /admin/build/themes) on your site and enable the theme. You will also make the theme the default and disable the other themes. However, you may wish to keep another theme (such as the original Garland) as the default theme during the development and instead set the new theme on your user account edit page.

Finally, you may wish to keep a different theme layout for administration pages, particularly if your theme will not lend itself to the wide tables sometimes seen on those pages. In that case, you will browse to the Administration theme settings page at Administer | Site Configuration | Administration theme (at /admin/settings/admin) and set it to something basic like Garland.

Once you have enabled your new theme, you'll be ready to begin development on it. This is largely achieved by writing template files, which are contained in the theme directory and end with .tpl.php in their filenames. We will cover the basics of this in the template files section of this chapter, and in more detail throughout the book.

Note

As the Garland theme it is installed by default on every new Drupal installation, we have chosen to use it throughout this book. But when developing a site for production, you may wish to start from another theme or even entirely from scratch. You can see many contributed themes for Drupal at http://drupal.org/project/themes. Additionally, you can see live previews of many of those themes at The Theme Garden (at http://themegarden.org/). Finally, consider the Zen theme, available at http://drupal.org/project/zen, which is meant to offer a no-frills, standards-compliant base theme. You may find its excellent documentation and growing community of developers and themers to be most suitable.

Basic Template Files

By default, Drupal uses PHPTemplate to power its themes. This flexible and powerful engine allows themers to wrap specific content in HTML snippets contained in specific files and functions. Themers can do all their work without knowing how to program, but if they are willing to explore the world of PHP, they have all the power of that scripting language to bring to bear on their themes.

Note

There are other engines available for Drupal, notably Smarty theme engine, which use Smarty Template Engine syntax. However, this book assumes you are using PHPTemplate.

At its most basic, a theme will contain a page.tpl.php file. This file will wrap all the content to be displayed in the required HTML tags to feed to the user's browser. Several PHP variables are made available for theming, which generally contain either content to be displayed or directives to tell us how to display content.

Also, a theme folder will contain one or more stylesheets such as Garland's style.css, which is the basic stylesheet to be used by that theme. The theme's .info file will contain a list of stylesheets to be included on a page. We will explore Cascading Style Sheets (CSS), which are necessary to control the output of our media.

Nodes are generally displayed using special template files in the themes folder. In addition to the default node.tpl.php, each node type may have its own template file, which will be used to wrap node content when provided. These are named by appending the node's machine-readable name to the filename. For instance, we might have a node-image.tpl.php file to wrap Image nodes, node-external_video.tpl.php for a custom External Video node type, and node-article.tpl.php for the Article content type we created earlier.

The template.php file contains functions made available to the theme, many of which are used to provide files to override the default theme functions offered by Drupal modules. This is an important concept that will be explained soon.

Other template files may be created in this folder to override how content is displayed. For instance, block.tpl.php and comment.tpl.php will respectively wrap blocks and comments with HTML. Any theme function available in Drupal may be overridden in this fashion, although some more obscure functions will require more of an understanding on how content is created in Drupal. Fortunately, there are tools available such as the Theme Developer Module (which we'll see in Images for Themers, chapter 4) to make this task easier.

Custom Regions

So you've created a new theme as outlined in the Themes section earlier. You've explored the files there, and are ready to begin overriding your theme.

One of your first tasks might be creating custom regions for blocks. Let's say you want a new block above the main content where you'll highlight articles and videos on the front page.

By default, you already have a content region. However, any blocks you activate in this region will be displayed below the page's main content.

This requires that you override your theme's region. To do this, you will need to edit the theme's .info file, in our case mytheme.info.

You will need to redefine all your regions, and enter your new region(s) by adding the following to the file:

	regions[left] = Left sidebar
	regions[right] = Right sidebar
	regions[upper] = Upper
	regions[content] = Content
	regions[header] = Header
	regions[footer] = Footer

In order to register this change (or any change in the info file), you will need to visit Administer | Site building | Themes (at /admin/build/themes). Also note that you must enter all the desired regions when adding a new one even if the defaults are not listed originally in the file, as an override to the regions will remove the defaults entirely. For instance, if we were only to add regions[upper] = Upper, then only that region and the content would appear on a page with none of the other desired regions.

Note

As themes in Drupal 5 don't have an info file, you would need to invoke the region's hook for the theme, in this case by creating a mytheme_regions function. See http://drupal.org/node/29139 for more information.

This will make any new regions available to Drupal, in our case creating an additional region labeled upper. The keys on the left of the array ('upper', 'right', and so on) define the variable names for the regions in your page.tpl.php file. The values on the right side Upper, Right sidebar, and so on will be the names for the regions as displayed on the Blocks administration page.

Once you have defined your regions in the template.php file, you need to also make sure that any new regions are displayed in the page.tpl.php file. You'll be able to display a region simply by printing its associated variable (as defined in the region array). For instance, our new upper region will be displayed by printing the $upper variable.

If you are following this example and have overridden the Garland theme, then next you will find the text <?php if ($breadcrumb): print $breadcrumb; endif; ?> in the file. Now add the following just below it:

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

This will ensure that the upper region is displayed only if there is a value in that variable, which will only be true if you set blocks to display in that region. It will further enclose this region in a unique HTML div that may be customized using the CSS stylesheets.

You will be able to add blocks into this region from Administer | Site building | Blocks (at /admin/build/block). This new region will appear below the breadcrumb on a page, but before any help messages, titles, content, and so on:

Note

You may notice the combination of PHP code within <?php ?> and HTML (such as <div></div>). This is one of the strengths of PHPTemplate. It allows a themer to work with the familiar markup of HTML to easily insert useful snippets of code or to print PHP variables within the markup. Within the template (.tpl.php) files, you need to ensure that all PHP code is contained within <?php ?>.

Theme Function Overrides

Any content provided by modules in Drupal may be overridden in the theme. If you know in general what theme function is creating the content, you will also know the template file or function to create.

For instance, if you want to display individual comments with reply/edit/delete links just below the comment's title rather than after its content, you would edit comment.tpl.php in /sites/all/themes/mytheme to move the code printing the links to just below the title line, so it reads:

	<h3><?php print $title ?></h3>
	<?php if ($links): ?>
	        <div class="links"><?php print $links ?></div>
	<?php endif; ?>

Often you may wish to override a theme that is not provided as a file in the default theme. In these cases, you will need to find the function in the code, and either create a template file (tpl.php) for the markup or create a theme function override in template.php. In some cases, especially for a short snippet of code, it may be easier to create the theme function override. If you make it available as a tpl.php file, this may be easier for themers to work with, particularly if they don't have much coding experience. Also, some theme functions may be more suitable in that format such as when they create a lot of markup in their output.

This is suitable for a theme function override and, in fact, is already available in Garland's template.php. The code for this follows after first searching the Internet to see that the HTML character code for» is &raquo;. Simply rewrite the included function as follows:

	function phptemplate_breadcrumb($breadcrumb) 
	{
	    if (!empty($breadcrumb)) 
	    {
	      return '<div class="breadcrumb">'. implode(' &raquo; ', $breadcrumb) .'</div>';
	    }
	}

Note

The» character is officially known as a guillemet, or right angle quote. It is used to demarcate quotes in French and other languages.

Our next request is to change the text that reads Comment viewing options above comments to read Comment Controls. (Comment viewing options are set by browsing to Administer | Content management | Content typesadmin/content/types and selecting the content type to configure. In Drupal 5, they're set globally at Administer | Content management | Comments| Settingsadmin/content/types

Garland has no built-in override for comment controls, so we'll need to hunt through our code to find this. We know that comments are displayed using the comment module, which is found in the /modules/comment directory. So we open the comment.module file in our editor. Searching for the text Comment viewing options, we see the output is generated with the theme_comment_controls function.

To override a theme function, we simply rewrite our new function in template.php, replacing the theme_ in the function name with phptemplate_. So for this example, we will copy the code from the function, place it in template.php in our new theme directory, and make our changes:

function phptemplate_comment_controls($form) {$output = '<div class="container-inline">';
$output .= drupal_render($form);
$output .= '</div>';
$output .= '<div class="description">'. t('Select your preferred way to display the comments and click "Save settings" to activate your changes.') .'</div>';
return theme('box', t('Super-Duper Comment Controls'), $output);
}

Note

Important note: When overriding theme functions, you must register new changes in the database (as of Drupal 6). To do so, you will either need to clear your cache (the easiest method being to install the Devel module from http://drupal.org/project/devel and use its provided links) or run the drupal_rebuild_theme_registry() function. While developing a theme, you may choose to add that function to the top of the template.php file, so it is run every time a page is loaded. However, if you do this, make certain to remove it before moving the site into production.

You could also have named this function something like mytheme_comment_controls. In fact, though the Garland theme doesn't follow this advice, the official policy is to do that and avoid conflicts when using sub-themes. However, there is also a strong case for using a phptemplate_ prefix. Using the phptemplate_ prefix makes your theme more portable. So if you later change the name of the theme or copy it to another directory for further development, you won't need to change all your mytheme_ references to newtheme_.

Note

A useful online reference is the Drupal API found at http://api.drupal.org. From here, we can find definitions for all core functions, as well as topics of specific interest such as http://api.drupal.org/api/group/themeable/6.

Template Files Revisited

Some theme functions lend themselves well to being overridden using a template (.tpl.php) file. Our emboldened editor now asks us to make some overrides to the forum page, so that the link that says Post new Forum topic is repeated at the bottom of the screen.

All modules (as of Drupal 6) must register their themeable functions using a hook_theme function. This means that you can scan that function to quickly find themes that may be overridden.

Thus, we read the forum_theme function at http://api.drupal.org/api/function/forum_theme/6 and see the following:

'forums' => array('template' => 'forums',
'arguments' => array('forums' => NULL, 'topics' => NULL, 'parents' => NULL, 'tid' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL),
),

This looks promising, so we look up theme_forums at the Drupal API. However, it turns up nothing, so we double-check by searching for that function in the forum module. No luck!

It turns out that modules (starting with Drupal 6) may also define their own template files. Knowing this, we scan the forum module directory at /modules/forum and discover several template files there, including forums.tpl.php.

Note

Note that if you're using Drupal 5, you would actually need to override theme_forum_display, which turns out to be a trickier business involving the use of the obsolete _phptemplate_callback in template.php. See http://drupal.org/node/11811 for more information.

Finally, we copy forums.tpl.php to our theme directory and override it as follows, duplicating our links:

<?php if ($forums_defined): ?><div id="forum">
<?php print theme('links', $links); ?>
<?php print $forums; ?>
<?php print $topics; ?>
<?php print theme('links', $links); ?>
</div>
<?php endif; ?>