Thứ Sáu, 30 tháng 5, 2014

The page.tpl.php File [The Theme System]

The next template file we’ll examine is the page.tpl.php file. This template file focuses on the elements that are displayed
between the <body>  and  </body> tags and  includes the HTML structure of the page, including DIV tags and  snippets of
PHP code.  Ifyou look back at the html.tpl.php template, you’ll see <?php print $page;  ?>  where the value of $page
is the contents of page.tpl.php.

This template file defines the structure of the page as it is displayed to the user.  If you look back at the example that we 
started this chapter with, all of the elements that we styled  in the Grayscale theme were elements that are rendered by the 
page.tpl.php template. In the following code you’ll see all of the elements that are rendered on the page and  the
conditional logic that drives  what  is displayed on a page and  how that page is structured. Like the html.php.tpl file, the
page.tpl.php file consistsof a mixture of HTML and  PHP snippets, where the PHP snippets include conditional logic to
determine whether a value is set and  displaying the values  associated with several variables, where variables may contain 
anything from a simple value like “42” to acomplex HTML structure including JavaScript. An example is the first 
variabl contained in the page.tpl.php file, $logo. This variable holds the HTML necessary to render the site’s logo if 
one was supplied, which is why there’s conditional logic to test to seewhether a logo was supplied.
The structure of the page.tpl.php file that resides in /modules/system is as follows:

<div  id="page-wrapper"><div  id="page">
<div  id="header"><div  class="section clearfix">
<?php if  ($logo): ?>
<a href="<?php print  $front_page; ?>" title="<?php print  t('Home'); ?>" rel="home" id="logo">
<img src="<?php print $logo; ?>" alt="<?php  print t('Home'); ?>" />
</a>
<?php endif; ?>
<?php if ($site_name || $site_slogan): ?>
<div  id="name-and-slogan">
<?php if ($site_name): ?>
<?php if ($title): ?>
<div  id="site-name"><strong>
<a href="<?php print  $front_page; ?>" title="<?php print  t('Home'); ?>" rel="home"><span>
<?php  print  $site_name; ?></span></a>
</strong></div>
<?php else: /* Use h1 when the  content title is empty */ ?>
<h1 id="site-name">
<a href="<?php print  $front_page; ?>" title="<?php print  t('Home'); ?>" rel="home">
<span><?php  print  $site_name; ?></span></a>
</h1>
<?php endif; ?>
<?php endif; ?>
<?php if ($site_slogan): ?>
<div  id="site-slogan"><?php print $site_slogan;  ?></div>
<?php endif; ?>
</div>  <!--  /#name-and-slogan -->
<?php endif; ?>
<?php print render($page['header']); ?>
</div></div> <!-- /.section, /#header   -->
<?php if ($main_menu  || $secondary_menu):  ?>
<div  id="navigation"><div class="section">
<?php print theme('links  system_main_menu',  array('links' => $main_menu, 'attributes' => array('id' => 'main-menu',   'class' => array('links', 'clearfix')), 'heading'=> t('Main   menu'))); ?>
<?php print theme('links  system_secondary_menu', array('links' => $secondary_menu, 'attributes'
=> array('id' => 'secondary-menu', 'class' => array('links', 'clearfix')), 'heading' => t('Secondary menu'))); ?
</div></div> <!-- /.section, /#navigation -->
<?php endif; ?>
<?php if ($breadcrumb):  ?>
<div  id="breadcrumb"><?php  print $breadcrumb; ?></div>
<?php endif; ?>
<?php print $messages;  ?>
<div  id="main-wrapper"><div id="main" class="clearfix">
<div  id="content"   class="column"><div  class="section">
<?php if ($page['highlighted']): ?><div  id="highlighted"><?php print render($page['highlighted']); ?>
</div><?php endif; ?>
<a id="main-content"></a>
<?php print render($title_prefix);  ?>
<?php if ($title): ?><h1 class="title" id="page-title">
<?php print  $title;?></h1><?php endif; ?>
<?php print render($title_suffix);  ?>
<?php if  ($tabs): ?><div  class="tabs"><?php  print render($tabs); ?></div><?php endif; ?>
<?php print render($page['help']);  ?>
<?php if ($action_links): ?><ul  class="action-links"><?php print render($action_links); ?></ul><?php endif; ?>
<?php print render($page['content']);  ?>
<?php print $feed_icons; ?>
</div></div> <!-- /.section, /#content -->
<?php if ($page['sidebar_first']): ?>
<div  id="sidebar-first" class="column  sidebar"><div  class="section">
<?php print render($page['sidebar_first']);  ?></div></div> <!-- /.section,  /#sidebar-first -->
<?php endif; ?>
<?php if ($page['sidebar_second']): ?>
<div  id="sidebar-second" class="column  sidebar"><div  class="section">
<?php print render($page['sidebar_second']); ?>
</div></div> <!-- /.section, /#sidebar-second -->
<?php endif; ?>
</div></div> <!--  /#main,   /#main-wrapper  -->
<div  id="footer"><div class="section">
<?php print render($page['footer']);  ?>
</div></div> <!-- /.section, /#footer -->
</div></div> <!--  /#page, /#page-wrapper  -->
The default variables that are available to the page.tpl.php file are shown in Table 9-3.

Table 9-3. Standard Variables  Available to page.tpl.php
Variable
Description of contents
$base_path
The base  URL path of the Drupal installation; at the very least, this will always default to /.
$directory
The directory the template is located in, e.g., modules/system or themes/bartik
$is_front
TRUE if the current page is the front  page
$logged_in
TRUE if the user is registered and  signed in
$is_admin
TRUE if the user  has permission to access administration pages
$front_page
The URL of the front  page; use this instead of $base_path when linking  to the front  page.  This includes the language domain or prefix.
$logo
The path to the logo image, as defined in the theme’s configuration
$site_name
The name of the site, empty when it has been disabled in theme settings
$site_slogan
The slogan of the site, empty when it has been disabled in theme settings
$main_menu (array)
An array containing the main menu links for the site, if they have been configured
$secondary_menu (array)
An array containing the secondary menu links for the site, if they have been configured
$breadcrumb
The breadcrumb trail for the current page
$title_prefix
An array containing additional output populated by modules, intended to be displayed in front  of the main title tag that appears in the template
$title
The page title, for use in the actual HTML content
$title_suffix (array)
An array containing additional output populated by modules, intended to be displayed after the main title tag that appears in the template
$message
Status and  error messages that should be displayed prominently
$tabs (array)
Tabs linking  to any sub-pages beneath the current page
$action_links (array)
Actions local to the page,  such as “Add menu” on the menu administration interface
$feed_icons
A string of all the feed icons  for the current page
$node
The node object, if there is an automatically loaded node associated with the page,  and  the node ID is the second argument in the page’s path (e.g., node/12345 and node/12345/revisions, but not comment/reply/12345).

The variables $page['help'], $page['highlighted'], $page['content'], $page['sidebar_first'],
$page['sidebar_second'], $page['header'], and  $page['footer'] represent regions on the page.  A region represents the
physical containers that a site administrator can assign any block-level element to (e.g., the log on  form, the search block,
a node, a view, or menu). If you dont specify any regions in your theme’s .info file, you get the regions just listed  by default. I’ll show you how to create additional regions in the upcoming section that describes how to construct your
theme’s .info file.

The region.tpl.php File

This template file focuses on how regions are displayed on your site. The default region.tpl.php file is pretty simple—essentially just displaying the content that is assigned to a region.

<?php if ($content): ?>
<div  class="<?php  print $classes;  ?>">
<?php print $content; ?>
</div><?php endif; ?>

The variables available to this template file by default are as shown in Table 9-4.

Table 9-4. Standard Variables  Available to region.tpl.php
Variable
Description of contents
$content
The content for this region, typically blocks
$classes
A string  of classes that can be used to style contextually through CSS; it can be manipulated through the variable $classes array from preprocess functions. The default values  can be one or more of the following regions.
The current template type, i.e., theming  hook
region-[name]: The name of the region with underscores replaced with dashes; for example, the page_top region would have a region-page-top class.
$region
The name of the region variable as defined in the theme’s .info file
$classes
Array of HTML class attribute values; it is flattened into a string within the variable $classes.
$is_admin
Flags TRUE when the current user is an administrator
$is_front
Flags TRUE when presented in the front  page
$logged_in
Flags true  when the current user  is a logged-in member

The node.tpl.php File


This template file defines how individual nodes are displayed on your site. The default node.tpl.php file can be found in
the modules/node directory on your site. In the following listing,  you’ll see elements that are similar to the other templatefiles discussedpreviously; predominantly HTML and  PHP snippets that perform conditional logic an printing the value
assigned to variables. In node.tpl.php you’ll also see that the template prints out the value assigned to the variable
$contentwhich in this case is an individual node. You’ll also note that the template uses “hide” to remove two
elements that would normally be shown on the page when a node is rendered—the comments and  links associated with a node. The template accomplishes this throughhide($content['comments']) and hide($content['links']). The reason the
template does this is that we typically want  to control where comments and  links are rendered when a node is displayed
by hiding them and  then later displaying them (using print render($content['comments']) and  print render($content
['links'])). You can use this approach to hide  any element of anything that would normally be displayed using the hide()
function, and  if you want  to later show  that element, you can use the printrender() function.
The default node.tpl.php file is as follows.
<div  id="node-<?php print  $node->nid; ?>" class="<?php  print $classes;  ?> clearfix"
<?php print $attributes;  ?>>
<?php print $user_picture; ?>
<?php print render($title_prefix);  ?>
<?php if (!$page): ?>
<h2<?php  print $title_attributes;  ?>><a href="<?php print  $node_url; ?>">
<?php  print $title; ?></a></h2>
<?php endif; ?>
<?php print render($title_suffix);  ?>
<?php if ($display_submitted): ?>
<div  class="submitted">
<?php print t('Submitted by !username  on !datetime', array('!username' => $name, '!datetime' => $date));?
</div>
<?php endif; ?>
<div  class="content"<?php print $content_attributes; ?>>
<?php
// We  hide  the  comments and links now so  that   we can  render  them later.
hide($content['comments']); hide($content['links']); print render($content);?>
</div>
<?php print render($content['links']);  ?>
<?php print  render($content['comments']); ?>
</div>
The variables that are available by default in the node.tpl.php file include those shown in Table 9-5.

Table 9-5. Standard Variables  Available to node.tpl.php
Variable
Description of contents
$title
The (sanitized) version of the title
$content (array)
An array of the elements that make up the node being displayed; if you want to display the entire node, use render($content), or as explained previously with the hide() and  show() functions, you can display individual elements of a node object.
$user_picture
The node author’s picture from user-picture.tpl.php
$date
Formatted creation date;  preprocess functions can reformat it by calling format_date() with the desired parameters on the $created variable.
$name
Themed username of node author output from theme_username()
$node_url
Direct  URL of the current node
$display_submitted
A flag (TRUE or FALSE) that specifies whether submission information should be displayed
$classes
String of classes that can be used to style contextually through CSS; it can be manipulated through the variable $classes_array from preprocess functions. The default values can be one or more of the following:

node: The current template type, i.e., theming hook

node-[type]: The current node type. For example, if the node is a Blog entry” it would result in node-blog.  Note that the machine name will often be in a short form of the human-readable label.

node-teaser: Nodes in teaser form

node-preview: Nodes in preview mode

The following are controlled through the node publishing options.

node-promoted: Nodes promoted to the front  page

node-sticky: Nodes ordered above other non-sticky nodes in teaser listings

node-unpublished: Unpublished nodes visible only to administrators
$title_prefix (array)
An array containing additional output populated by modules, intended to be displayed in front  of the main title tag that appears in the template
$title_suffix (array)
An array containing additional output populated by modules, intended to be displayed immediately after the main title tag that appears in the template
$node
The full node object
$type
Node  type, i.e., story, page,  blog, etc.
$comment_count
Number of comments attached to a node
$uid
The UID of the node’s author
$created
Time the node was published in Unix timestamp format
$classes_array
Array of HTML class attribute values;  it is flattened into a string with the variable
$classes.
$zebra
Outputs either “even” or “odd”;  useful for zebra striping in teaser listings
$id
Position of the node; increments each  time  it’s output
$view_mode
View mode, e.g., “full” or “teaser”
$page
Flag for the full page state (TRUE or FALSE)
$promote
Flag for front  page promotion state (TRUE or FALSE)
$sticky
Flags for sticky post  setting
$status
Flag for published status
$comment
State of comment settings for the node
$readmore
Flag that is set to TRUE if the teaser content of the node cannot hold the main body content
$is_front
Flag that is set to TRUE when the content is presented on the front  page of the site
$logged_in
Flag that is set to TRUE when the current user is a logged-in member
$is_admin
Flag that is set to TRUE when the current user is an administrator

The field.tpl.php File


This template file is used for theming fields and, unlike the previous templates, isn’t automatically called by Drupal when
rendering fields. If you wish to use this template, you’ll need to copy it from /modules/fields/templates into your theme’s directory.

<div  class="<?php  print $classes;  ?> clearfix"<?php print $attributes;  ?>>
<?php if (!$label_hidden) : ?>
<div  class="field-label"<?php print $title_attributes; ?>>
<?php print  $label  ?>:&nbsp;</div>
<?php endif; ?>
<div  class="field-items"<?php print  $content_attributes;  ?>>
<?php foreach   ($items as  $delta => $item)   : ?>
<div  class="field-item <?php print $delta %    2  ?  'odd' : 'even'; ?>"
<?php print $item_attributes[$delta];  ?>>
<?php print  render($item);  ?></div>
<?php endforeach; ?>
</div></div>

The variables that are available by default to the field.tpl.php file are shown in Table 9-6.

Table 9-6. Standard Variables  Available to field.tpl.php
Variable
Description of contents
$items
An array of field values;  use render() to output them.
$label
The item’s label
$label_hidden
A flag (TRUE or FALSE) that can be used to set whether the label should be displayed
$classes
A string  of classes that can be used to style contextually through CSS; it can be manipulated through CSS. It can be manipulated through the variable $classes array from preprocess functions. The default values can be one or more of the following:

field: The current template type, i.e., “theming hook”

field-name-[field_name]: The current fieldname; for example, if the fieldname is field_description”, it would result in field-name- field-description”.

field-type-[field_type]: The current field type; for example, if the field type is text”, it would result in field-type-text”.

field-label-[label_display]: The current label position; for example, if the label position is above, it would result in field-label-above”.
$element['#object']
The entity that the field is attached to
$element['#view_mode']
The view mode of the entity that the field is attached to, e.g., “full” or “teaser”
$element['#field_name']
The field name
$element['#field_type']
The field type
$element['#field_language']
The field language
$element['#field_translatable']
Whether the field is translatable
$element['#label_display']
Position of label display: inline, above, or hidden
$field_name_css
The CSS-compatible fieldname
$field_type_css
The CSS-compatible field type
$classes_array
Array of HTML class attribute values;  it is flattened into a string witin the variable $classes.


The block.tpl.php 
File


The block-level theming template, block.tpl.php, can be found in the modules/block directory. By this point,
you should be seeing a definitive pattern of how template files are constructed.

<div  id="<?php print  $block_html_id; ?>" class="<?php  print $classes;  ?>"<?php  print $attributes; ?>>
<?php print render($title_prefix);  ?>
<?php if ($block->subject): ?>
<h2<?php  print $title_attributes;  ?>><?php  print  $block->subject ?></h2>
<?php endif;?>
<?php print render($title_suffix);  ?>
<div  class="content"<?php print $content_attributes; ?>>
<?php print  $content ?>
</div>
</div>
The variables that are available by default to the block.tpl.php file are shown in Table 9-7.

Table 9-7. Standard Variables  Available to block.tpl.php
Variable
Description of contents
$block->subject
The block title
$content
The block’s content
$block->module
The module that generated the block
$block->delta
An ID for the block, unique within each  module
$block->region
The block region embedding the current block
$classes
A string  of classes that can be used to style contextually through CSS; it can be manipulated through the variable $classes array from preprocess functions. The default values can be one or more of the following:

block: The current template type, i.e., “theming hook”

block-[module]: The module generating the block; for example, the user module is responsible for handling the default user  navigation block. In that case, the class would be block-user”.
$title_prefix (array)
An array containing additional output populated by modules, intended to be displayed in front  of the main title tag that appears in the template
$title_suffix (array)
An array containing additional output populated by modules, intended to be displayed after the main title tag that appears in the template
#classes_array (array)
An array of HTML class attribute values; it is flattened into a string within the variable $classes.
$block_zebra
Outputs “odd”  and  “even dependent on each  block region
$block_id
Dependent on each  block region
$id
Same output as $block_id  but independent of any block region
$is_front
A flag (TRUE or FALSE) that indicates whether the current page is the home page of the site
$logged_in
A flag (TRUE or FALSE) that indicates whether the visitor is logged  in
$is_admin
A flag (TRUE or FALSE) that indicates whether the visitor is logged  in as an admin user
$block_html_id
A valid HTML ID that is guaranteed unique


Overriding Template Files


There will likely come a time  where you need to change how page.tpl.php, node.tpl.php, or any of the other standard template

files display elements on your site. Let’s step  back to our Grayscale theme that we created at the beginning of the chapter and 

customize the page.tpl.php file so that when a visitor is on the front  page of the site, a welcome message is displayed. If the visitor isn’t on the front  page,  we won’t display the welcome message. To begin the process, copy the page.tpl.php file from the

modules/system directory into the sites/all/themes/grayscale/templates directory. By copying the file into our theme’s directory, Drupal will now use that version of page.tpl.php rather than the one in the modules/system directory.


The modification that well make is relatively simple. We’ll use the $is_front variable that is exposed to the page template, and usinga conditional phrase, check  to see if the visitor is on the front page.  If so, we will display a Welcome to My Site” message at thetop of the page.  Open the file and  look for the following line:


<div  id="content"   class="column"><div  class="section">


Immediately after that line, insert the following line of code,  which uses the $is_front variable to see if the visitor is on the front page of your site, and  if so, prints out a welcome message.

<?php

if  ($is_front): ?><div  id="welcome_message">

<?php print "Welcome  to  My  Site!";  ?></div>

<?php endif; ?>


The result is that “Welcome to My Site!” is printed right under the secondary menu. It is nothing spectacular, but it demonstrates theconcept of leveraging the standard page.tpl.php file and customizing.


You can also create custom .tpl files for specific pages of your site; for example, you could copy page.tpl.php and  create a

page--front.tpl.php file. This new template would be applied only to the front  page of your site. You can also do the same thing with node.tpl.php. Let’s say you want  to theme articles differently than other node types, like a basic  page.  You can copy

node.tpl.php from the modules/node directory to your theme directory and  rename that file to node--article.tpl.php.

This newtemplate file will override the standard node.tpl.php file for any node that is an article. For additional details, visit the

theming guid on Drupal.org at http://drupal.org/documentation/theme.

Other Template Files


You will find several other template files as you browse through the module and  theme directories of your site. For example, the

comment module uses comment.tpl.php for rendering comments. The comment module creates a number of variables and exposes those variables to the comment.tpl.php file. The designation of the comment.tpl.php file as the template file for comments is

made through a call to hook_theme() by passing 'template' => 'comment'  as one of the values in the array (see the following

code). There’s  no need to specify the .tpl.php file extension as Drupal assumes that’s  what  you mean. I’ll cover additional detailson how to create and  expose variables to your template in a bit.

/**

*  Implements hook_theme().

*/

function comment_theme() { return  array('comment_block'  => array( 'variables' => array(),),

'comment_preview'  => array('variables' => array('comment'  => NULL),),'comment'  => array( 'template' => 'comment',

'render element' => 'elements',),'comment_post_forbidden' => array( 'variables' => array('node' => NULL),),

'comment_wrapper' => array( 'template' => 'comment-wrapper', 'render element' => 'content',),);}


Introducing the theme() Function


When  Drupal wants to generate some HTML output for a them able item  (like a node, a block, a breadcrumb trail, a comment, or user signature), it looks for a theme function or template file that will generate HTML for that item.  Almost all parts of Drupal are

them able, which means you can override the actual HTML that is generated for that item.  We’ll look at some examples soon.


An Overview of How theme() Works


Here’s a high-level overview of what  happens when a simple node page,  such as http://example.com/?q=node/3, is displayed:


1.       Drupal’s menu system receives the request and  hands off control to the node module.


2.       After building the node data structure, theme('node', $variables) is called. This finds the correct theme function or template

file, defines variables that the template may use, and  applies the template, resulting in finished HTML for the node. (If multiple

nodes are being displayed, as happens with a blog, this process happens for each  node.)


3.       An HTML structure is returned (you can see it as the $return variable in index.php)

and  passed to the theme() function again as theme('page', $return).


4.       Before processing the page template, Drupal does  some preprocessing, such as discovering which regions are available and

which blocks  should be shown in each  region. Each block is turned into HTML by calling  theme('blocks', $region), which

defines variables and  applies a block template. You should be starting to see a pattern here.

5.       Finally, Drupal defines variables for the page template to use and  applies the page template.


You should be able to discern from the preceding list that the theme() function is very important to Drupal. It is in charge of

running preprocessing functions to set variables that will be used in templates and  dispatching a theme call to the correct function ofinding the appropriate template file. The result is HTML. We will take an in-depth look at how this function works later.

Right now, it is enough to understand that when Drupal wants to turn a node into HTML, theme('node', $variables = array()) is

called.  Depending on which theme is enabled, the theme_node() function will generate the HTML or a template file named

node.tpl.php will do itThis process can be overridden at many levels. For example, themes can override built-in theme

functions, so when theme('node', $variables = array()) is called,  a function called  grayscale_node() might handle it instead of theme_node(). Template files have naming conventions that we’ll explore later too, so that a node--story.tpl.php

template file would target only nodes of type story.


Overriding Themable Items


As you’ve seen, themable items are identifiable by their function names, which all begin with theme_or by the presence of a

template file (see http://api.drupal.org/api/group/themeable/7 for a list of all standard themable items). This naming convention

givesDrupal the ability to create a function-override mechanism for all themable functions. Designers can instruct Drupal to

execute an alternative function, which takes precedence over the theme functions that module developers expose or over

Drupal’s default templatefiles. For example, let’s examine how this process works when building the site’s breadcrumb trail.

Open includes/theme.inc, and  examine the functions inside that file. Many functions in there begin with theme_, which is the tell

tale sign that they can be overridden. In particular, let’s examine theme_breadcrumb():

/**

*   Returns  HTML   for  a  breadcrumb  trail.

*

*   @param  $variables

*         An  associative array  containing:

*         - breadcrumb: An  array  containing the  breadcrumb  links.

*/

function  theme_breadcrumb($variables) {

$breadcrumb = $variables['breadcrumb'];

if (!empty($breadcrumb)) {

// Provide  a  navigational heading  to  give   context for  breadcrumb  links to

// screen-reader users.  Make  the  heading  invisible with  .element-invisible.

$output  = '<h2  class="element-invisible">' . t('You   are  here') . '</h2>';

$output  .=  '<div class="breadcrumb">'  . implode(' »  ', $breadcrumb) . '</div>'; return  $output;

}}


This function controls the HTML for the breadcrumb navigation within Drupal. Currently, it adds a right-pointing double-arrow separator between eac item  of the trail. Suppose you want  to change the div tag to a span and  use an asterisk (*) in steaof double arrow. How should you go about it? One solution would be to edit this function within theme.inc, save it, and

call it good (No! No! Do not do this!) There are better ways.


Have you ever seen how these theme functions are invoked within core? You’ll never see theme_breadcrumb() called  directly.

Instead, it’s always wrapped inside the theme() helper function. You’d expect the function to be called  as follows:

theme_breadcrumb($variables)

But it’s not.  Instead, you’ll see developers use the following invocation:

theme('breadcrumb', $variables);

This generic theme() function is responsible for initializing the theme layer and  dispatching function calls to the appropriate places, bringing us to the more elegant solution to our problem. The call to theme() instructs Drupal to look for the breadcrumbfunctions

in the following order. Assuming the theme you’re using is Grayscale, which is a PHPTemplate based theme, Drupal would look for the following (we’ll ignore breadcrumb.tpl.php for a moment):

grayscale_breadcrumb() sites/all/themes/grayscale/breadcrumb.tpl.php theme_breadcrumb()

Easy—your theme’s template.php file is the place  to override Drupal’s default theme functions, and intercept and  create

custom variables to pass along  to template files.


To tweak the Drupal breadcrumbs, create (or update if you created one in the previous example on setting theme options) a sites/all/themes/grayscale/template.php file, and  copy and  paste the theme_breadcrumb() function in there from theme.inc. Besure to

include the starting <?php tag. Also, rename the function from theme_breadcrumb to grayscale_breadcrumb.

Next, click the Modules link in thmenu at the top of the page to rebuild the theme registry so Drupal will detect your new

function.

<?php

/**

*   Returns  HTML   for  a  breadcrumb  trail.

*

*   @param  $variables

*         An  associative array  containing:

*         - breadcrumb: An  array  containing the  breadcrumb  links.

*/

function  grayscale_breadcrumb($variables) {

$breadcrumb = $variables['breadcrumb'];

if (!empty($breadcrumb)) {

// Provide  a  navigational heading  to  give   context for  breadcrumb  links to

// screen-reader users.  Make  the  heading  invisible with  .element-invisible.

$output  = '<h2  class="element-invisible">' t('You   are  here') '</h2>';

$output  .=  '<div class="breadcrumb">'  implode(' *  ', $breadcrumb) '</div>'; return  $output;}}

Next, if youre using the Grayscale theme, add  the following CSS to css/style.css.

.breadcrumb {

margin-top:10px; clear:both; height:  15px;

background-color: #fff; width:  960px;

margin-right: auto; margin-left:  auto;

}

The next time  Drupal is asked to format the breadcrumb trail, it’ll find your function first and  use iinstead of the default theme_breadcrumb() function, and  breadcrumbs will contain your asterisks instead of Drupal’s double arrows. Pretty  slick, eh? By passingall theme function calls through the theme() function, Drupal will always check if the current theme has overridden any of the

theme_ functions and call those instead.


Overriding with Template Files


If you’re working with a designer, telling  him or her to “just go in the code  and  find the themable functions to override” is out of the question. Fortunately, there’s another way to make this more accessible to designer types. You can instead mapthemable items to their own template files. I’ll demonstrate with our handy breadcrumb example.

Before we begin, make sure that no theme function is overriding theme_breadcrumb(). So if you created a grayscale_

breadcrumb() function in your theme’s template.php file in the preceding section, comment it out. Then,  create a file atsites/all/

themes/grayscale/breadcrumb.tpl.php. This is the new template file for breadcrumbs. Because we wanted to change the <div> tagto a <span> tag, go ahead and populate the file with the following:

<?php if (!empty($breadcrumb)): ?>

<span class="breadcrumb"><?php  print  implode(' ! ', $breadcrumb) ?></span>
<?php endif; ?>

That’s easy enough for a designer to edit. Now you need to let Drupal know to call this template file when looking to render its
breadcrumbs. To do that, rebuild the theme registry by clearing the site’s cache files. To clear the cache, visitadmin/config/development/performance and  click the Clear all caches” button. While rebuilding the theme registry, Drupal will discover your
breadcrumb.tpl.php file and  map the breadcrumb themable item  to that template file. Now you know how to override any them
able item in Drupal in a way that will make your designers happy.

Adding and  Manipulating Template Variables

In this example, we’ll look at manipulating or adding variables that are being passed into page and  node templates. Let’s continue
with our example of using  the breadcrumb trail. First, let’s modify sites/all/themes/grayscale/breadcrumb.tpl.php to use
avariable called  $breadcrumb_delimiter for the breadcrumb delimiter:
<?php if (!empty($breadcrumb)): ?>
<span class="breadcrumb">
<?php print  implode(' '. $breadcrumb_delimiter  .' ', $breadcrumb) ?>
</span>
<?php endif; ?>

To set the value of $breadcrumb_delimiter, one option would be in a module. We could create sites/all/modules/crumbpicker.
info:
name  = Breadcrumb  Picker
description  = Provide  a  character  for  the  breadcrumb  trail  delimiter.
package = Pro  Drupal  Development core  = 7.x
The module at sites/all/modules/crumbpicker.module would be tiny:
<?php
/**
*   @file
*   Provide  a  character  for  the  breadcrumb  trail  delimiter.
*/
/**
*   Implements  $modulename_preprocess_$hook().
*/
function  crumbpicker_preprocess_breadcrumb(&$variables)  {
$variables['breadcrumb_delimiter']  = '/';}
After enabling the module, your breadcrumb trail should look like Home  / Administer  / Site  building.
The preceding example illustrates a module setting a variable for a template file to use. But there must be an easier way than
creating a module every time  a variable needs to be set. Sure enough, it’s template.php to the rescue. Let’s write a function to
set the breadcrumb delimiter. Add the following tyour theme’s template.php file:
/**
*   Implements  $themeenginename_preprocess_$hook().
*   Variables  we  set here  will  be available  to  the  breadcrumb  template  file.
*/
function  grayscale_preprocess_breadcrumb(&$variables)  {
$variables['breadcrumb_delimiter']  = '#';
}
Thats easier than creating a module, and  frankly, the module approach is usually best for existing modules to provide variables to
templates; modules are not generally written solely for this purpose. Now, we have a module providing a variable and  a function
itemplate.php providing a variable. Which one will actually be used
Actually, a whole  hierarchy of preprocess functions run in a certain order, each  one with the potential to overwrite variables that
have been defined by previous preprocess functions. In the preceding example, the breadcrumb delimiter will be # because
phptemplate_preprocess_breadcrumb() will be executed after crumbpicker_preprocess_breadcrumb(), and  thus its variable
assignment will override any previous variable assignment for $breadcrumb_delimiterFor the theming of a breadcrumb trail using the Grayscale theme, the actual order of precedence (from first called  to last called) would be:

template_preprocess() template_preprocess_breadcrumb() crumbpicker_preprocess() crumbpicker_preprocess_breadcrumb() phptemplate_preprocess()phptemplate_preprocess_breadcrumb() grayscale_preprocess() grayscale_preprocess_breadcrumb() template_process()

Thus grayscale_preprocess_breadcrumb() can override any variable that has been set; it’s called  last before the variables are
handed to the template file. Calling all those functions when only some of them are implemented may seem to you like a waste
of time.  If so, you are correct, and  when the theme registry is built,  Drupal determines which functions are implemented and  callsonly those.

Using the Theme Developer Module

An invaluable resource for working with Drupal themes is the theme developer module. It is part  of devel.module and  can be
downloaded at http://drupal.org/project/devel_themer. The theme developer module lets you point to an element on a page and
discover which templates or theme functions were involved in creating that element as well as the variables (and their values)
available to that element.

Summary

After reading this chapter, you should be able to

     Create template files.

     Override theme functions.

     Manipulate template variables.

     Create new page regions for blocks.

For additional details about theming in Drupal 7, please check the theme handbook page at http://drupal.org/documentation/theme.

Không có nhận xét nào:

Đăng nhận xét