404 lines
14 KiB
Plaintext
404 lines
14 KiB
Plaintext
<?php
|
|
// $Id$
|
|
|
|
/**
|
|
* @file
|
|
* Handles integration of templates written in pure php with the Drupal theme system.
|
|
*/
|
|
|
|
function phptemplate_init($template) {
|
|
$file = dirname($template->filename) . '/template.php';
|
|
if (file_exists($file)) {
|
|
include_once "./$file";
|
|
}
|
|
}
|
|
|
|
function phptemplate_templates($directory = 'themes') {
|
|
return drupal_system_listing('^page\.tpl\.php$', $directory, 'filename');
|
|
}
|
|
|
|
/**
|
|
* Declare the available regions implemented by this engine.
|
|
*
|
|
* @return
|
|
* An array of regions. The first array element will be used as the default region for themes.
|
|
*/
|
|
function phptemplate_regions() {
|
|
return array(
|
|
'left' => t('left sidebar'),
|
|
'right' => t('right sidebar'),
|
|
'content' => t('content'),
|
|
'header' => t('header'),
|
|
'footer' => t('footer')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Execute a template engine call.
|
|
*
|
|
* Each call to the template engine has two parts. Namely preparing
|
|
* the variables, and then doing something with them.
|
|
*
|
|
* The first step is done by all template engines / themes, the second
|
|
* step is dependent on the engine used.
|
|
*
|
|
* @param $hook
|
|
* The name of the theme function being executed.
|
|
* @param $variables
|
|
* A sequential array of variables passed to the theme function.
|
|
* @param $suggestions
|
|
* An array of suggested template files to use. If none of the files are found, the
|
|
* default $hook.tpl.php will be used.
|
|
* @return
|
|
* The HTML generated by the template system.
|
|
*/
|
|
function _phptemplate_callback($hook, $variables = array(), $suggestions = array()) {
|
|
global $theme_engine;
|
|
|
|
$variables = array_merge($variables, _phptemplate_default_variables($hook, $variables));
|
|
|
|
// Allow specified variables to be overridden
|
|
$variables_function = '_'. $theme_engine .'_variables';
|
|
if (function_exists($variables_function)) {
|
|
$variables = array_merge($variables, call_user_func($variables_function, $hook, $variables));
|
|
}
|
|
|
|
if (is_array($variables['template_files'])) {
|
|
$suggestions = array_merge($suggestions, $variables['template_files']);
|
|
}
|
|
|
|
if (isset($variables['template_file'])) {
|
|
$suggestions[] = $variables['template_file'];
|
|
}
|
|
|
|
$hook_function = '_'. $theme_engine .'_'. $hook;
|
|
$default_function = '_'. $theme_engine .'_default';
|
|
if (function_exists($hook_function)) {
|
|
return call_user_func($hook_function, $variables, $suggestions);
|
|
}
|
|
elseif (function_exists($default_function)) {
|
|
return call_user_func($default_function, $hook, $variables, $suggestions);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Adds additional helper variables to all templates.
|
|
*
|
|
* Counts how many times certain hooks have been called. Sidebar left / right are special cases.
|
|
*
|
|
* @param $hook
|
|
* The name of the theme function being executed.
|
|
* @param $variables
|
|
* A sequential array of variables passed to the theme function.
|
|
*/
|
|
function _phptemplate_default_variables($hook, $variables) {
|
|
global $theme, $sidebar_indicator;
|
|
static $count = array();
|
|
|
|
$count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
|
|
$variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
|
|
$variables['id'] = $count[$hook]++;
|
|
|
|
if ($hook == 'block') {
|
|
$count['block_counter'][$sidebar_indicator] = isset($count['block_counter'][$sidebar_indicator]) && is_int($count['block_counter'][$sidebar_indicator]) ? $count['block_counter'][$sidebar_indicator] : 1;
|
|
$variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
|
|
$variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
|
|
}
|
|
elseif ($hook == 'page') {
|
|
$regions = system_region_list($theme);
|
|
// Load all region content assigned via blocks.
|
|
foreach (array_keys($regions) as $region) {
|
|
// Skip blocks in this region that have already been loaded.
|
|
// This pre-loading is necessary because phptemplate uses variable names different from
|
|
// the region names, e.g., 'sidebar_left' instead of 'left'.
|
|
if (!in_array($region, array('left', 'right', 'footer'))) {
|
|
isset($variables[$region]) ? $variables[$region] .= theme('blocks', $region) : $variables[$region] = theme('blocks', $region);
|
|
}
|
|
}
|
|
}
|
|
// Tell all templates where they are located.
|
|
$variables['directory'] = path_to_theme();
|
|
$variables['is_front'] = drupal_is_front_page();
|
|
|
|
return $variables;
|
|
}
|
|
|
|
/**
|
|
* @return
|
|
* Array of template features
|
|
*/
|
|
function phptemplate_features() {
|
|
return array(
|
|
'toggle_logo',
|
|
'toggle_comment_user_picture',
|
|
'toggle_favicon',
|
|
'toggle_mission',
|
|
'toggle_name',
|
|
'toggle_node_user_picture',
|
|
'toggle_search',
|
|
'toggle_slogan'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Prepare the values passed to the theme_page function to be passed
|
|
* into a pluggable template engine. Uses the arg() function to
|
|
* generate a series of page template files suggestions based on the
|
|
* current path. If none are found, the default page.tpl.php is used.
|
|
*/
|
|
function phptemplate_page($content, $show_blocks = TRUE) {
|
|
|
|
/* Set title and breadcrumb to declared values */
|
|
if (drupal_is_front_page()) {
|
|
$mission = filter_xss_admin(theme_get_setting('mission'));
|
|
}
|
|
|
|
/* Add favicon */
|
|
if (theme_get_setting('toggle_favicon')) {
|
|
drupal_set_html_head('<link rel="shortcut icon" href="'. check_url(theme_get_setting('favicon')) .'" type="image/x-icon" />');
|
|
}
|
|
|
|
/**
|
|
* Populate sidebars.
|
|
*/
|
|
if ($show_blocks) {
|
|
global $sidebar_indicator;
|
|
/**
|
|
* Sidebar_indicator tells the block counting code to count sidebars separately.
|
|
*/
|
|
$sidebar_indicator = 'left';
|
|
$sidebar_left = theme('blocks', 'left');
|
|
if ($sidebar_left != '') {
|
|
$layout = 'left';
|
|
}
|
|
|
|
$sidebar_indicator = 'right';
|
|
$sidebar_right = theme('blocks', 'right');
|
|
if ($sidebar_right != '') {
|
|
$layout = ($layout == 'left') ? 'both' : 'right';
|
|
}
|
|
$sidebar_indicator = NULL;
|
|
}
|
|
else {
|
|
$layout = 'none';
|
|
}
|
|
|
|
// Construct page title
|
|
if (drupal_get_title()) {
|
|
$head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
|
|
}
|
|
else {
|
|
$head_title = array(variable_get('site_name', 'drupal'));
|
|
if (variable_get('site_slogan', '')) {
|
|
$head_title[] = variable_get('site_slogan', '');
|
|
}
|
|
}
|
|
|
|
$variables = array(
|
|
'base_path' => base_path(),
|
|
'breadcrumb' => theme('breadcrumb', drupal_get_breadcrumb()),
|
|
'closure' => theme('closure'),
|
|
'content' => '<!-- begin content -->' . $content . '<!-- end content -->',
|
|
'feed_icons' => drupal_get_feeds(),
|
|
'footer_message' => filter_xss_admin(variable_get('site_footer', FALSE)) . "\n" . theme('blocks', 'footer'),
|
|
'head' => drupal_get_html_head(),
|
|
'head_title' => implode(' | ', $head_title),
|
|
'help' => theme('help'),
|
|
'language' => $GLOBALS['locale'],
|
|
'layout' => $layout,
|
|
'logo' => theme_get_setting('logo'),
|
|
'messages' => theme('status_messages'),
|
|
'mission' => isset($mission) ? $mission : '',
|
|
'primary_links' => menu_primary_links(),
|
|
'search_box' => (theme_get_setting('toggle_search') ? drupal_get_form('search_theme_form') : ''),
|
|
'secondary_links' => menu_secondary_links(),
|
|
'sidebar_left' => $sidebar_left,
|
|
'sidebar_right' => $sidebar_right,
|
|
'site_name' => (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''),
|
|
'site_slogan' => (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''),
|
|
'css' => drupal_add_css(),
|
|
'styles' => drupal_get_css(),
|
|
'scripts' => drupal_get_js(),
|
|
'tabs' => theme('menu_local_tasks'),
|
|
'title' => drupal_get_title()
|
|
);
|
|
|
|
if ((arg(0) == 'node') && is_numeric(arg(1))) {
|
|
$variables['node'] = node_load(arg(1));
|
|
}
|
|
|
|
// Build a list of suggested template files in order of specificity. One
|
|
// suggestion is made for every element of the current path, though
|
|
// numeric elements are not carried to subsequent suggestions. For example,
|
|
// http://www.example.com/node/1/edit would result in the following
|
|
// suggestions:
|
|
//
|
|
// page-node-edit.tpl.php
|
|
// page-node-1.tpl.php
|
|
// page-node.tpl.php
|
|
// page.tpl.php
|
|
$i = 0;
|
|
$suggestion = 'page';
|
|
$suggestions = array($suggestion);
|
|
while ($arg = arg($i++)) {
|
|
$suggestions[] = $suggestion . '-' . $arg;
|
|
if (!is_numeric($arg)) {
|
|
$suggestion .= '-' . $arg;
|
|
}
|
|
}
|
|
if (drupal_is_front_page()) {
|
|
$suggestions[] = 'page-front';
|
|
}
|
|
|
|
return _phptemplate_callback('page', $variables, $suggestions);
|
|
}
|
|
|
|
/*
|
|
* Prepare the values passed to the theme_node function to be passed
|
|
* into a pluggable template engine.
|
|
*/
|
|
function phptemplate_node($node, $teaser = 0, $page = 0) {
|
|
if (module_exists('taxonomy')) {
|
|
$taxonomy = taxonomy_link('taxonomy terms', $node);
|
|
}
|
|
else {
|
|
$taxonomy = array();
|
|
}
|
|
|
|
$variables = array(
|
|
'content' => ($teaser && $node->teaser) ? $node->teaser : $node->body,
|
|
'date' => format_date($node->created),
|
|
'links' => $node->links ? theme('links', $node->links, array('class' => 'links inline')) : '',
|
|
'name' => theme('username', $node),
|
|
'node' => $node, // we pass the actual node to allow more customization
|
|
'node_url' => url('node/'. $node->nid),
|
|
'page' => $page,
|
|
'taxonomy' => $taxonomy,
|
|
'teaser' => $teaser,
|
|
'terms' => theme('links', $taxonomy, array('class' => 'links inline')),
|
|
'title' => check_plain($node->title)
|
|
);
|
|
|
|
// Flatten the node object's member fields.
|
|
$variables = array_merge((array)$node, $variables);
|
|
|
|
// Display info only on certain node types.
|
|
if (theme_get_setting('toggle_node_info_' . $node->type)) {
|
|
$variables['submitted'] = t('Submitted by !a on @b.', array('!a' => theme('username', $node), '@b' => format_date($node->created)));
|
|
$variables['picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', $node) : '';
|
|
}
|
|
else {
|
|
$variables['submitted'] = '';
|
|
$variables['picture'] = '';
|
|
}
|
|
|
|
return _phptemplate_callback('node', $variables, array('node-' . $node->type));
|
|
}
|
|
|
|
/**
|
|
* Prepare the values passed to the theme_comment function to be passed
|
|
* into a pluggable template engine.
|
|
*/
|
|
function phptemplate_comment($comment, $links = 0) {
|
|
return _phptemplate_callback('comment', array(
|
|
'author' => theme('username', $comment),
|
|
'comment' => $comment,
|
|
'content' => $comment->comment,
|
|
'date' => format_date($comment->timestamp),
|
|
'links' => isset($links) ? theme('links', $links) : '',
|
|
'new' => $comment->new ? t('new') : '',
|
|
'picture' => theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '',
|
|
'submitted' => t('Submitted by !a on @b.',
|
|
array('!a' => theme('username', $comment),
|
|
'@b' => format_date($comment->timestamp))),
|
|
'title' => l($comment->subject, $_GET['q'], NULL, NULL, "comment-$comment->cid")
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Prepare the values passed to the theme_block function to be passed
|
|
* into a pluggable template engine. Uses block properties to generate a
|
|
* series of template file suggestions. If none are found, the default
|
|
* block.tpl.php is used.
|
|
*/
|
|
function phptemplate_block($block) {
|
|
$suggestions[] = 'block';
|
|
$suggestions[] = 'block-' . $block->region;
|
|
$suggestions[] = 'block-' . $block->module;
|
|
$suggestions[] = 'block-' . $block->module . '-' . $block->delta;
|
|
|
|
return _phptemplate_callback('block', array('block' => $block), $suggestions);
|
|
}
|
|
|
|
/**
|
|
* Prepare the values passed to the theme_box function to be passed
|
|
* into a pluggable template engine.
|
|
*/
|
|
function phptemplate_box($title, $content, $region = 'main') {
|
|
return _phptemplate_callback('box', array(
|
|
'content' => $content,
|
|
'region' => $region,
|
|
'title' => $title
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Default callback for PHPTemplate.
|
|
*
|
|
* Load a template file, and pass the variable array to it.
|
|
* If the suggested file is not found, PHPTemplate will attempt to use
|
|
* a $hook.tpl.php file in the template directory, and failing that a
|
|
* $hook.tpl.php in the PHPTemplate directory.
|
|
*
|
|
* @param $hook
|
|
* The name of the theme function being executed.
|
|
* @param $variables
|
|
* A sequential array of variables passed to the theme function.
|
|
* @param $suggestions
|
|
* An array of suggested template files to use.
|
|
*/
|
|
function _phptemplate_default($hook, $variables, $suggestions = array(), $extension = '.tpl.php') {
|
|
global $theme_engine;
|
|
|
|
// Loop through any suggestions in FIFO order.
|
|
$suggestions = array_reverse($suggestions);
|
|
foreach ($suggestions as $suggestion) {
|
|
if (!empty($suggestion) && file_exists(path_to_theme() .'/'. $suggestion . $extension)) {
|
|
$file = path_to_theme() .'/'. $suggestion . $extension;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isset($file)) {
|
|
if (file_exists(path_to_theme() ."/$hook$extension")) {
|
|
$file = path_to_theme() ."/$hook$extension";
|
|
}
|
|
else {
|
|
if (in_array($hook, array('node', 'block', 'box', 'comment'))) {
|
|
$file = "themes/engines/$theme_engine/$hook$extension";
|
|
}
|
|
else {
|
|
$variables['hook'] = $hook;
|
|
watchdog('error', t('%engine.engine was instructed to override the %name theme function, but no valid template file was found.', array('%engine' => $theme_engine, '%name' => $hook)));
|
|
$file = "themes/engines/$theme_engine/default$extension";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($file)) {
|
|
return call_user_func('_'. $theme_engine .'_render', $file, $variables);
|
|
}
|
|
}
|
|
|
|
function _phptemplate_render($file, $variables) {
|
|
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
|
|
ob_start(); // Start output buffering
|
|
include "./$file"; // Include the file
|
|
$contents = ob_get_contents(); // Get the contents of the buffer
|
|
ob_end_clean(); // End buffering and discard
|
|
return $contents; // Return the contents
|
|
}
|
|
|
|
?>
|