<?php
+
/**
* Copyright 2003, Paul James
- * Copyright (c) 2005 The SquirrelMail Project Team
- * Licensed under the GNU GPL. For full terms see the file COPYING.
*
* This file contains some methods from the Smarty templating engine version
* 2.5.0 by Monte Ohrt <monte@ispi.net> and Andrei Zmievski <andrei@php.net>.
*
- * @version $Id$
- */
-
-/**
* The SquirrelMail (Foowd) template implementation.
* Derived from the foowd template implementation and adapted
* for squirrelmail
- * @package SquirrelMail
+ * @copyright © 2005-2006 The SquirrelMail Project Team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
+ * @version $Id$
+ * @package squirrelmail
*/
/**
* This class uses a similar API to Smarty.
*
* @author Paul James
- * @author Monte Ohrt <monte@ispi.net>
- * @author Andrei Zmievski <andrei@php.net>
- * @package SquirrelMail
+ * @author Monte Ohrt <monte at ispi.net>
+ * @author Andrei Zmievski <andrei at php.net>
+ * @package squirrelmail
*/
class Template
{
*
* @var string
*/
- var $template_dir = 'templates\default';
+ var $template_dir = '';
+
+ /**
+ * The default template directory
+ *
+ * @var string
+ */
+ var $default_template_dir = 'templates/default/';
+
+ /**
+ * Template files provided by this template set
+ *
+ * @var array
+ */
+ var $templates_provided = array();
/**
- * Constructor
+ * Javascript files required by the template
*
- * @param string $sTplDir where the template set is located
+ * @var array
*/
- function Template($sTplDir = 'templates\default') {
- $this->template_dir = $sTplDir;
+ var $required_js_files = array();
+
+ /**
+ * Javascript files provided by the template. If a JS file is required, but
+ * not provided, the js file by the same name will be included from the
+ * default template directory.
+ *
+ * @var array
+ */
+ var $provided_js_files = array();
+
+ /**
+ * Additional stylesheets provided by the template. This allows template
+ * authors to provide additional CSS sheets to templates while using the
+ * default template set stylesheet for other definitions.
+ */
+ var $additional_css_sheets = array();
+
+ /**
+ * Constructor
+ *
+ * @param string $sTplDir where the template set is located
+ */
+ function Template($sTplDir) {
+ $this->template_dir = $sTplDir;
+
+ // Pull in the tempalte config file
+ if (!file_exists($this->template_dir . 'template.php')) {
+ trigger_error('No template.php could be found in the requested template directory ("'.$this->template_dir.'")', E_USER_ERROR);
+ } else {
+ include ($this->template_dir . 'template.php');
+ $this->templates_provided = is_array($templates_provided) ? $templates_provided : array();
+ $this->required_js_files = is_array($required_js_files) ? $required_js_files : array();
+ $this->provided_js_files = is_array($provided_js_files) ? $provided_js_files: array();
+ $this->additional_css_sheets = is_array($additional_css_sheets) ? $additional_css_sheets : array();
+ }
}
*
* @param array|string $tpl_var the template variable name(s)
* @param mixed $value the value to append
+ * @param boolean $merge when $value is given as an array,
+ * this indicates whether or not that
+ * array itself should be appended as
+ * a new template variable value or if
+ * that array's values should be merged
+ * into the existing array of template
+ * variable values
*/
function append($tpl_var, $value = NULL, $merge = FALSE)
{
if (is_array($tpl_var))
{
+ //FIXME: $tpl_var is supposed to be a list of template var names,
+ // so we should be looking at the values NOT the keys!
foreach ($tpl_var as $_key => $_val)
{
if ($_key != '')
if(isset($this->values[$_key]) && !is_array($this->values[$_key]))
settype($this->values[$_key],'array');
+ //FIXME: we should be iterating the $value array here not the values of the
+ // list of template variable names! I think this is totally broken
+ // This might just be a matter of needing to clarify the method's API;
+ // values may have been meant to be passed in $tpl_var in the case that
+ // $tpl_var is an array. Ugly and non-intuitive.
+ // PROPOSAL: API should be as such:
+ // if (is_string($tpl_var)) then $values are added/merged as already done
+ // if (is_array($tpl_var)) then $values is required to be an array whose
+ // keys must match up with $tpl_var keys and
+ // whose values are then what is added to
+ // each template variable value (array or
+ // strings, doesn't matter)
if($merge && is_array($_val))
{
foreach($_val as $_mkey => $_mval)
*
* @param string $tpl_var the template variable name
* @param mixed $value the referenced value to append
+ * @param boolean $merge when $value is given as an array,
+ * this indicates whether or not that
+ * array itself should be appended as
+ * a new template variable value or if
+ * that array's values should be merged
+ * into the existing array of template
+ * variable values
*/
function append_by_ref($tpl_var, &$value, $merge = FALSE)
{
}
}
+
+ /**
+ *
+ * Return the relative template directory path for this template set.
+ *
+ * @return string The relative path to the template directory based
+ * from the main SquirrelMail directory (SM_PATH).
+ *
+ */
+ function get_template_file_directory() {
+
+//FIXME: temporarily parse off SM_PATH from the template dir class attribute until we can change the entire template subsystem such that the template dir is derived internally in this class from the template ID/name/attributes
+return substr($this->template_dir, strlen(SM_PATH));
+ return $this->template_dir;
+
+ }
+
+
+ /**
+ *
+ * Return the relative template directory path for the DEFAULT template set.
+ *
+ * @return string The relative path to the default template directory based
+ * from the main SquirrelMail directory (SM_PATH).
+ *
+ */
+ function get_default_template_file_directory() {
+
+ return $this->default_template_dir;
+
+ }
+
+
+ /**
+ *
+ * Find the right template file.
+ *
+ * Templates are expected to be found in the template set directory,
+ * for example:
+ * SM_PATH/templates/<template name>/
+ * or, in the case of plugin templates, in a plugin directory in the
+ * template set directory, for example:
+ * SM_PATH/templates/<template name>/plugins/<plugin name>/
+ * *OR* in a template directory in the plugin as a fallback, for example:
+ * SM_PATH/plugins/<plugin name>/templates/<template name>/
+ * If the correct file is not found for the current template set, a
+ * default template is loaded, which is expected to be found in the
+ * default template directory, for example:
+ * SM_PATH/templates/default/
+ * or for plugins, in a plugin directory in the default template set,
+ * for example:
+ * SM_PATH/templates/default/plugins/<plugin name>/
+ * *OR* in a default template directory in the plugin as a fallback,
+ * for example:
+ * SM_PATH/plugins/<plugin name>/templates/default/
+ *
+ * Plugin authors must note that the $filename MUST be prefaced
+ * with "plugins/<plugin name>/" in order to correctly resolve the
+ * template file.
+ *
+ * @param string $filename The name of the template file,
+ * possibly prefaced with
+ * "plugins/<plugin name>/"
+ * indicating that it is a plugin
+ * template.
+ *
+ * @return string The full path to the template file; if
+ * not found, an empty string. The caller
+ * is responsible for throwing erros or
+ * other actions if template file is not found.
+ *
+ */
+ function get_template_file_path($filename) {
+
+ // is the template found in the normal template directory?
+ //
+ $filepath = SM_PATH . $this->get_template_file_directory() . $filename;
+ if (!file_exists($filepath)) {
+
+ // no, so now we have to get the default template...
+ // however, in the case of a plugin template, let's
+ // give one more try to find the right template as
+ // provided by the plugin
+ //
+ if (strpos($filename, 'plugins/') === 0) {
+
+ $plugin_name = substr($filename, 8, strpos($filename, '/', 8) - 8);
+ $filepath = SM_PATH . 'plugins/' . $plugin_name . '/'
+ . $this->get_template_file_directory()
+ . substr($filename, strlen($plugin_name) + 9);
+
+ // no go, we have to get the default template,
+ // first try the default SM template
+ //
+ if (!file_exists($filepath)) {
+
+ $filepath = SM_PATH
+ . $this->get_default_template_file_directory()
+ . $filename;
+
+ // still no luck? get default template from the plugin
+ //
+ if (!file_exists($filepath)) {
+
+ $filepath = SM_PATH . 'plugins/' . $plugin_name . '/'
+ . $this->get_default_template_file_directory()
+ . substr($filename, strlen($plugin_name) + 9);
+
+ // no dice whatsoever, return empty string
+ //
+ if (!file_exists($filepath)) {
+ $filepath = '';
+ }
+
+ }
+
+ }
+
+
+ // get default template for non-plugin templates
+ //
+ } else {
+
+ $filepath = SM_PATH . $this->get_default_template_file_directory()
+ . $filename;
+
+ // no dice whatsoever, return empty string
+ //
+ if (!file_exists($filepath)) {
+ $filepath = '';
+ }
+
+ }
+
+ }
+
+ return $filepath;
+
+ }
+
+
+ /**
+ * Display the template
+ *
+ * @param string $file The template file to use
+ */
+ function display($file)
+ {
+ // Pull in our config file
+ $t = &$this->values; // place values array directly in scope
+
+ // Get right template file
+ $template = $this->get_template_file_path($file);
+ if (empty($template)) {
+ trigger_error('The template "'.htmlspecialchars($file).'" could not be displayed!', E_USER_ERROR);
+ } else {
+ ob_start();
+ include($template);
+ ob_end_flush();
+ }
+ }
+
+ /**
+ * Return the results of applying a template.
+ *
+ * @param string $file The template file to use
+ * @return string A string of the results
+ */
+ function fetch($file) {
+ $t = &$this->values; // place values array directly in scope
+
+ // Get right template file
+ $template = $this->get_template_file_path($file);
+ if (empty($template)) {
+ trigger_error('The template "'.htmlspecialchars($file).'" could not be fetched!', E_USER_ERROR);
+ } else {
+ ob_start();
+ include($template);
+ $contents = ob_get_contents();
+ ob_end_clean();
+ return $contents;
+ }
+ }
+
/**
- * Display the template
+ * Return paths to the required javascript files. Used when generating page
+ * header.
*
- * @param string $file The template file to use
+ * @return array $paths
*/
- function display($file)
- {
- $t = &$this->values; // place values array directly in scope
- ob_start();
- include($this->template_dir.$file);
- ob_end_flush();
+ function getJavascriptIncludes () {
+ $paths = array();
+ foreach ($this->required_js_files as $file) {
+ if (in_array($file, $this->provided_js_files))
+ $paths[] = './'.$this->template_dir.'js/'.basename($file);
+ else $paths[] = SM_PATH .'templates/default/js/'.basename($file);
+ }
+
+ return $paths;
}
/**
- * Return the results of applying a template.
+ * Return any additional stylsheets provided by the template. Used when
+ * generating page headers.
*
- * @param string $file The template file to use
- * @return string A string of the results
+ * @return array $paths
*/
- function fetch($file)
- {
- ob_start();
- $t = &$this->values; // place values array directly in scope
- include($this->template_dir.$file);
- $contents = ob_get_contents();
- ob_end_clean();
- return $contents;
+ function getAdditionalStyleSheets () {
+ $paths = array();
+ foreach ($this->additional_css_sheets as $css) {
+ $css = basename($css);
+ if (strtolower($css) == 'stylesheet.tpl') {
+ continue;
+ }
+ $paths[] = $css;
+ }
+ return $paths;
}
-
}
-
-?>