Clarifications, questions, proposals
[squirrelmail.git] / class / template / template.class.php
index 094f428cc2690522275e6dc02ee51e8de9e5e55f..6bc25cca99703296a583e7de92fce2c46a8c371e 100755 (executable)
@@ -9,7 +9,7 @@
  * The SquirrelMail (Foowd) template implementation.
  * Derived from the foowd template implementation and adapted
  * for squirrelmail
- * @copyright © 2005 The SquirrelMail Project Team
+ * @copyright © 2005-2006 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -40,15 +40,56 @@ class Template
    *
    * @var string
    */
-  var $template_dir = 'templates\default';
+  var $template_dir = '';
 
   /**
-   * Constructor
+   * Template files provided by this template set
    *
-   * @param string $sTplDir where the template set is located
+   * @var array
+   */
+  var $templates_provided = array();
+
+  /**
+   * Javascript files required by the template
+   *
+   * @var array
+   */
+  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.
    */
-  function Template($sTplDir = 'templates\default') {
-       $this->template_dir = $sTplDir;
+  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();
+        }
   }
 
 
@@ -91,11 +132,20 @@ class Template
    *
    * @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 != '')
@@ -103,6 +153,18 @@ class Template
           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)
@@ -136,6 +198,13 @@ class Template
    *
    * @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)
   {
@@ -161,10 +230,17 @@ class Template
    */
   function display($file)
   {
+    // Pull in our config file
     $t = &$this->values; // place values array directly in scope
-    ob_start();
-    include($this->template_dir.$file);
-    ob_end_flush();
+
+    $template = in_array($file, $this->templates_provided) ? $this->template_dir . $file : SM_PATH .'templates/default/'. $file;
+    if (!file_exists($template)) {
+        trigger_error('The template "'.htmlspecialchars($file).'" could not be displayed!', E_USER_ERROR);
+    } else {
+        ob_start();
+        include($template);
+        ob_end_flush();
+    }
   }
 
   /**
@@ -173,16 +249,53 @@ class Template
    * @param string $file The template file to use
    * @return string A string of the results
    */
-  function fetch($file)
-  {
-    ob_start();
+  function fetch($file) {
     $t = &$this->values; // place values array directly in scope
-    include($this->template_dir.$file);
-    $contents = ob_get_contents();
-    ob_end_clean();
-    return $contents;
+
+    $template = in_array($file, $this->templates_provided) ? $this->template_dir . $file : SM_PATH .'templates/default/'. $file;
+    if (!file_exists($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;
+    }
   }
 
-}
+  /**
+   * Return paths to the required javascript files.  Used when generating page
+   * header.
+   *
+   * @return array $paths
+   */
+  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);
+    }
 
-?>
\ No newline at end of file
+    return $paths;
+  }
+
+  /**
+   * Return any additional stylsheets provided by the template.  Used when
+   * generating page headers.
+   *
+   * @return array $paths
+   */
+  function getAdditionalStyleSheets () {
+    $paths = array();
+    foreach ($this->additional_css_sheets as $css) {
+        $css = basename($css);
+        if (strtolower($css) == 'stylesheet.tpl') {
+            continue;
+        }
+        $paths[] = $css;
+    }
+    return $paths;
+  }
+}