specfile
[plewww.git] / themes / engines / phptemplate / phptemplate.engine
1 <?php
2 // $Id: phptemplate.engine 144 2007-03-28 07:52:20Z thierry $
3
4 /**
5  * @file
6  * Handles integration of templates written in pure php with the Drupal theme system.
7  */
8
9 function phptemplate_init($template) {
10   $file = dirname($template->filename) . '/template.php';
11   if (file_exists($file)) {
12    include_once "./$file";
13   }
14 }
15
16 function phptemplate_templates($directory = 'themes') {
17   return system_listing('^page\.tpl\.php$', $directory, 'filename');
18 }
19
20 /**
21  * Declare the available regions implemented by this engine.
22  *
23  * @return
24  *  An array of regions.  The first array element will be used as the default region for themes.
25  */
26 function phptemplate_regions() {
27   return array(
28        'left' => t('left sidebar'),
29        'right' => t('right sidebar'),
30        'content' => t('content'),
31        'header' => t('header'),
32        'footer' => t('footer')
33   );
34 }
35
36 /**
37  * Execute a template engine call.
38  *
39  * Each call to the template engine has two parts. Namely preparing
40  * the variables, and then doing something with them.
41  *
42  * The first step is done by all template engines / themes, the second
43  * step is dependent on the engine used.
44  *
45  * @param $hook
46  *   The name of the theme function being executed.
47  * @param $variables
48  *   A sequential array of variables passed to the theme function.
49  * @param $file
50  *   A suggested template file to use. If the file is not found, the default $hook.tpl.php will be used.
51  * @return
52  *  The HTML generated by the template system.
53  */
54 function _phptemplate_callback($hook, $variables = array(), $file = NULL) {
55
56   $variables = array_merge($variables, _phptemplate_default_variables($hook, $variables));
57
58   // Allow specified variables to be overridden
59   if (function_exists('_phptemplate_variables')) {
60     $variables = array_merge($variables, _phptemplate_variables($hook, $variables));
61   }
62
63   if (isset($variables['template_file'])) {
64     $file = $variables['template_file'];
65   }
66
67   if (function_exists('_phptemplate_' . $hook)) {
68     return call_user_func('_phptemplate_' . $hook, $variables, $file);
69   }
70   elseif (function_exists('_phptemplate_default')) {
71     return call_user_func('_phptemplate_default', $hook, $variables, $file);
72   }
73
74 }
75
76 /**
77  * Adds additional helper variables to all templates.
78  *
79  * Counts how many times certain hooks have been called. Sidebar left / right are special cases.
80  *
81  * @param $hook
82  *   The name of the theme function being executed.
83  * @param $variables
84  *   A sequential array of variables passed to the theme function.
85  */
86 function _phptemplate_default_variables($hook, $variables) {
87   global $theme, $sidebar_indicator;
88   static $count = array();
89
90   $count[$hook] = isset($count[$hook]) && is_int($count[$hook]) ? $count[$hook] : 1;
91   $variables['zebra'] = ($count[$hook] % 2) ? 'odd' : 'even';
92   $variables['id'] = $count[$hook]++;
93
94   if ($hook == 'block') {
95     $count['block_counter'][$sidebar_indicator] = isset($count['block_counter'][$sidebar_indicator]) && is_int($count['block_counter'][$sidebar_indicator]) ? $count['block_counter'][$sidebar_indicator] : 1;
96     $variables['block_zebra'] = ($count['block_counter'][$sidebar_indicator] % 2) ? 'odd' : 'even';
97     $variables['block_id'] = $count['block_counter'][$sidebar_indicator]++;
98   }
99   elseif ($hook == 'page') {
100     $regions = system_region_list($theme);
101     // Load all region content assigned via blocks.
102     foreach (array_keys($regions) as $region) {
103       // Skip blocks in this region that have already been loaded.
104       // This pre-loading is necessary because phptemplate uses variable names different from
105       // the region names, e.g., 'sidebar_left' instead of 'left'.
106       if (!in_array($region, array('left', 'right', 'footer'))) {
107         isset($variables[$region]) ? $variables[$region] .= theme('blocks', $region) : $variables[$region] = theme('blocks', $region);
108       }
109     }
110   }
111   // Tell all templates where they are located.
112   $variables['directory'] = path_to_theme();
113   $variables['is_front'] = drupal_is_front_page();
114
115   return $variables;
116 }
117
118 /**
119  * @return
120  *  Array of template features
121  */
122 function phptemplate_features() {
123   return array(
124     'toggle_logo',
125     'toggle_comment_user_picture',
126     'toggle_favicon',
127     'toggle_mission',
128     'toggle_name',
129     'toggle_node_user_picture',
130     'toggle_search',
131     'toggle_slogan'
132   );
133 }
134
135 /**
136  * Prepare the values passed to the theme_page function to be passed
137  * into a pluggable template engine.
138  */
139 function phptemplate_page($content) {
140
141   /* Set title and breadcrumb to declared values */
142   if (drupal_is_front_page()) {
143     $mission = filter_xss_admin(theme_get_setting('mission'));
144   }
145
146   /* Add favicon */
147   if (theme_get_setting('toggle_favicon') && ($favicon_url = check_url(theme_get_setting('favicon')))) {
148     drupal_set_html_head('<link rel="shortcut icon" href="'. $favicon_url .'" type="image/x-icon" />');
149   }
150
151   /**
152   * Populate sidebars.
153   */
154   $layout = 'none';
155   global $sidebar_indicator;
156   /**
157    * Sidebar_indicator tells the block counting code to count sidebars separately.
158    */
159   $sidebar_indicator = 'left';
160   $sidebar_left = theme('blocks', 'left');
161   if ($sidebar_left != '') {
162     $layout = 'left';
163   }
164
165   $sidebar_indicator = 'right';
166   $sidebar_right = theme('blocks', 'right');
167   if ($sidebar_right != '') {
168     $layout = ($layout == 'left') ? 'both' : 'right';
169   }
170   $sidebar_indicator = NULL;
171
172   // Construct page title
173   if (drupal_get_title()) {
174     $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'drupal'));
175   }
176   else {
177     $head_title = array(variable_get('site_name', 'drupal'));
178     if (variable_get('site_slogan', '')) {
179       $head_title[] = variable_get('site_slogan', '');
180     }
181   }
182
183   $variables = array(
184     'base_path'           => base_path(),
185     'breadcrumb'          => theme('breadcrumb', drupal_get_breadcrumb()),
186     'closure'             => theme('closure'),
187     'content'             => '<!-- begin content -->' . $content . '<!-- end content -->',
188     'footer_message'      => filter_xss_admin(variable_get('site_footer', FALSE)) . "\n" . theme('blocks', 'footer'),
189     'head'                => drupal_get_html_head(),
190     'head_title'          => implode(' | ', $head_title),
191     'help'                => theme('help'),
192     'language'            => $GLOBALS['locale'],
193     'layout'              => $layout,
194     'logo'                => theme_get_setting('logo'),
195     'messages'            => theme('status_messages'),
196     'mission'             => isset($mission) ? $mission : '',
197     'primary_links'       => menu_primary_links(),
198     'search_box'          => (theme_get_setting('toggle_search') ? search_box() : ''),
199     'secondary_links'     => menu_secondary_links(),
200     'sidebar_left'        => $sidebar_left,
201     'sidebar_right'       => $sidebar_right,
202     'site_name'           => (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''),
203     'site_slogan'         => (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''),
204     'styles'              => theme_get_styles(),
205     'tabs'                => theme('menu_local_tasks'),
206     'title'               => drupal_get_title()
207   );
208
209   if ((arg(0) == 'node') && is_numeric(arg(1))) {
210     $variables['node'] = node_load(arg(1));
211   }
212
213   return _phptemplate_callback('page', $variables);
214 }
215
216 /*
217  * Prepare the values passed to the theme_node function to be passed
218  * into a pluggable template engine.
219  */
220 function phptemplate_node($node, $teaser = 0, $page = 0) {
221   if (module_exist('taxonomy')) {
222     $taxonomy = taxonomy_link('taxonomy terms', $node);
223   }
224   else {
225     $taxonomy = array();
226   }
227
228   $variables = array(
229     'content'        => ($teaser && $node->teaser) ? $node->teaser : $node->body,
230     'date'           => format_date($node->created),
231     'links'          => $node->links ? theme('links', $node->links) : '',
232     'name'           => theme('username', $node),
233     'node'           => $node,  // we pass the actual node to allow more customization
234     'node_url'       => url('node/'. $node->nid),
235     'page'           => $page,
236     'taxonomy'       => $taxonomy,
237     'teaser'         => $teaser,
238     'terms'          => theme('links', $taxonomy),
239     'title'          => check_plain($node->title)
240   );
241
242   // Flatten the node object's member fields.
243   $variables = array_merge((array)$node, $variables);
244
245   // Display info only on certain node types.
246   if (theme_get_setting('toggle_node_info_' . $node->type)) {
247     $variables['submitted'] =  t('Submitted by %a on %b.', array('%a' => theme('username', $node), '%b' => format_date($node->created)));
248     $variables['picture'] = theme_get_setting('toggle_node_user_picture') ? theme('user_picture', $node) : '';
249   }
250   else {
251     $variables['submitted'] = '';
252     $variables['picture'] = '';
253   }
254
255   return _phptemplate_callback('node', $variables, 'node-' . $node->type);
256 }
257
258 /**
259  * Prepare the values passed to the theme_comment function to be passed
260  * into a pluggable template engine.
261  */
262 function phptemplate_comment($comment, $links = 0) {
263   return _phptemplate_callback('comment', array(
264     'author'    => theme('username', $comment),
265     'comment'   => $comment,
266     'content'   => $comment->comment,
267     'date'      => format_date($comment->timestamp),
268     'links'     => isset($links) ? theme('links', $links) : '',
269     'new'       => $comment->new ? t('new') : '',
270     'picture'   => theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '',
271     'submitted' => t('Submitted by %a on %b.',
272                       array('%a' => theme('username', $comment),
273                             '%b' => format_date($comment->timestamp))),
274     'title'     => l($comment->subject, $_GET['q'], NULL, NULL, "comment-$comment->cid")
275   ));
276 }
277
278 /**
279  * Prepare the values passed to the theme_block function to be passed
280  * into a pluggable template engine.
281  */
282 function phptemplate_block($block) {
283   return _phptemplate_callback('block', array('block' => $block));
284 }
285
286 /**
287  * Prepare the values passed to the theme_box function to be passed
288  * into a pluggable template engine.
289  */
290 function phptemplate_box($title, $content, $region = 'main') {
291   return _phptemplate_callback('box', array(
292     'content' =>   $content,
293     'region'  =>   $region,
294     'title'   =>   $title
295   ));
296 }
297
298 /**
299  * Default callback for PHPTemplate.
300  *
301  * Load a template file, and pass the variable array to it.
302  * If the suggested file is not found, PHPTemplate will attempt to use
303  * a $hook.tpl.php file in the template directory, and failing that a
304  * $hook.tpl.php in the PHPTemplate directory.
305  *
306  * @param $hook
307  *   The name of the theme function being executed.
308  * @param $variables
309  *   A sequential array of variables passed to the theme function.
310  * @param $file
311  *   A suggested template file to use.
312  */
313 function _phptemplate_default($hook, $variables, $file = NULL) {
314   if (!empty($file) && file_exists(path_to_theme() . "/$file.tpl.php")) {
315     $file = path_to_theme() . "/$file.tpl.php";
316   }
317   else {
318     if (file_exists(path_to_theme() . "/$hook.tpl.php")) {
319       $file = path_to_theme() . "/$hook.tpl.php";
320     }
321     else {
322       if (in_array($hook, array('node', 'block', 'box', 'comment'))) {
323         $file = "themes/engines/phptemplate/$hook.tpl.php";
324       }
325       else {
326         $variables['hook'] = $hook;
327         watchdog('error', t('PHPTemplate was instructed to override the %name theme function, but no valid template file was found.', array('%name' => theme('placeholder', $hook))));
328         $file = 'themes/engines/phptemplate/default.tpl.php';
329       }
330     }
331   }
332
333   if (isset($file)) {
334     extract($variables, EXTR_SKIP);  // Extract the variables to a local namespace
335     ob_start();                      // Start output buffering
336     include "./$file";               // Include the file
337     $contents = ob_get_contents();   // Get the contents of the buffer
338     ob_end_clean();                  // End buffering and discard
339     return $contents;                // Return the contents
340   }
341
342 }
343
344 ?>