Import Horde_Template from CVS HEAD
authorMichael M Slusarz <slusarz@curecanti.org>
Wed, 10 Jun 2009 18:52:05 +0000 (12:52 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Wed, 10 Jun 2009 18:52:05 +0000 (12:52 -0600)
16 files changed:
framework/Template/lib/Horde/Template.php [new file with mode: 0644]
framework/Template/package.xml [new file with mode: 0644]
framework/Template/test/Horde/Template/array_assoc.html [new file with mode: 0644]
framework/Template/test/Horde/Template/array_assoc.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/array_if.html [new file with mode: 0644]
framework/Template/test/Horde/Template/array_if.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/array_nested.html [new file with mode: 0644]
framework/Template/test/Horde/Template/array_nested.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/array_simple.html [new file with mode: 0644]
framework/Template/test/Horde/Template/array_simple.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/divider.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/if.html [new file with mode: 0644]
framework/Template/test/Horde/Template/if.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/iterator.phpt [new file with mode: 0644]
framework/Template/test/Horde/Template/scalar.html [new file with mode: 0644]
framework/Template/test/Horde/Template/scalar.phpt [new file with mode: 0644]

diff --git a/framework/Template/lib/Horde/Template.php b/framework/Template/lib/Horde/Template.php
new file mode 100644 (file)
index 0000000..20f491c
--- /dev/null
@@ -0,0 +1,557 @@
+<?php
+/**
+ * Horde Template system. Adapted from bTemplate by Brian Lozier
+ * <brian@massassi.net>.
+ *
+ * Horde_Template provides a basic template engine with tags, loops,
+ * and if conditions. However, it is also a simple interface with
+ * several essential functions: set(), fetch(), and
+ * parse(). Subclasses or decorators can implement (or delegate) these
+ * three methods, plus the options api, and easily implement other
+ * template engines (PHP code, XSLT, etc.) without requiring usage
+ * changes.
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Template
+ */
+class Horde_Template
+{
+    /**
+     * Option values.
+     *
+     * @var array
+     */
+    protected $_options = array();
+
+    /**
+     * Directory that templates should be read from.
+     *
+     * @var string
+     */
+    protected $_basepath = '';
+
+    /**
+     * Tag (scalar) values.
+     *
+     * @var array
+     */
+    protected $_scalars = array();
+
+    /**
+     * Loop tag values.
+     *
+     * @var array
+     */
+    protected $_arrays = array();
+
+    /**
+     * Cloop tag values.
+     *
+     * @var array
+     */
+    protected $_carrays = array();
+
+    /**
+     * If tag values.
+     *
+     * @var array
+     */
+    protected $_ifs = array();
+
+    /**
+     * Name of cached template file.
+     *
+     * @var string
+     */
+    protected $_templateFile = null;
+
+    /**
+     * Cached source of template file.
+     *
+     * @var string
+     */
+    protected $_template = null;
+
+    /**
+     * Constructor. Can set the template base path and whether or not
+     * to drop template variables after a parsing a template.
+     *
+     * @param string  $basepath  The directory where templates are read from.
+     */
+    public function __construct($basepath = null)
+    {
+        if (!is_null($basepath)) {
+            $this->_basepath = $basepath;
+        }
+    }
+
+    /**
+     * Sets an option.
+     *
+     * @param string $option  The option name.
+     * @param mixed  $val     The option's value.
+     */
+    public function setOption($option, $val)
+    {
+        $this->_options[$option] = $val;
+    }
+
+    /**
+     * Set the template contents to a string.
+     *
+     * @param string $template  The template text.
+     */
+    public function setTemplate($template)
+    {
+        $this->_template = $template;
+        $this->_templateFile = 'string';
+    }
+
+    /**
+     * Returns an option's value.
+     *
+     * @param string $option  The option name.
+     *
+     * @return mixed  The option's value.
+     */
+    public function getOption($option)
+    {
+        return isset($this->_options[$option])
+            ? $this->_options[$option]
+            : null;
+    }
+
+    /**
+     * Sets a tag, loop, or if variable.
+     *
+     * @param string|array $tag   Either the tag name or a hash with tag names
+     *                            as keys and tag values as values.
+     * @param mixed $var          The value to replace the tag with.
+     * @param boolean $isIf       Is this for an <if:> tag? (Default: no).
+     */
+    public function set($tag, $var, $isIf = false)
+    {
+        if (is_array($tag)) {
+            foreach ($tag as $tTag => $tVar) {
+                $this->set($tTag, $tVar, $isIf);
+            }
+        } elseif (is_array($var) || is_object($var)) {
+            $this->_arrays[$tag] = $var;
+            if ($isIf) {
+                // Just store the same variable that we stored in
+                // $this->_arrays - if we don't modify it, PHP's
+                // reference counting ensures we're not using any
+                // additional memory here.
+                $this->_ifs[$tag] = $var;
+            }
+        } else {
+            $this->_scalars[$tag] = $var;
+            if ($isIf) {
+                // Just store the same variable that we stored in
+                // $this->_scalars - if we don't modify it, PHP's
+                // reference counting ensures we're not using any
+                // additional memory here.
+                $this->_ifs[$tag] = $var;
+            }
+        }
+    }
+
+    /**
+     * Sets values for a cloop.
+     *
+     * @param string $tag   The name of the cloop.
+     * @param array $array  The values for the cloop.
+     * @param array $cases  The cases (test values) for the cloops.
+     */
+    public function setCloop($tag, $array, $cases)
+    {
+        $this->_carrays[$tag] = array(
+            'array' => $array,
+            'cases' => $cases,
+        );
+    }
+
+    /**
+     * Returns the value of a tag or loop.
+     *
+     * @param string $tag  The tag name.
+     *
+     * @return mixed  The tag value or null if the tag hasn't been set yet.
+     */
+    public function get($tag)
+    {
+        if (isset($this->_arrays[$tag])) {
+            return $this->_arrays[$tag];
+        } elseif (isset($this->_scalars[$tag])) {
+            return $this->_scalars[$tag];
+        }
+        return null;
+    }
+
+    /**
+     * Fetches a template from the specified file and return the parsed
+     * contents.
+     *
+     * @param string $filename  The file to fetch the template from.
+     *
+     * @return string  The parsed template.
+     * @throws Horde_Exception
+     */
+    public function fetch($filename)
+    {
+        $contents = $this->_getTemplate($filename);
+
+        // Parse and return the contents.
+        return $this->parse($contents);
+    }
+
+    /**
+     * Parses all variables/tags in the template.
+     *
+     * @param string $contents  The unparsed template.
+     *
+     * @return string  The parsed template.
+     */
+    public function parse($contents = null)
+    {
+        if (is_null($contents)) {
+            $contents = $this->_template;
+        }
+
+        // Process ifs.
+        if (!empty($this->_ifs)) {
+            foreach (array_keys($this->_ifs) as $tag) {
+                $contents = $this->_parseIf($tag, $contents);
+            }
+        }
+
+        // Process tags.
+        $replace = $search = array();
+        reset($this->_scalars);
+        while (list($key, $value) = each($this->_scalars)) {
+            $search[] = $this->_getTag($key);
+            $replace[] = $value;
+        }
+        if (count($search)) {
+            $contents = str_replace($search, $replace, $contents);
+        }
+
+        // Process cloops.
+        reset($this->_carrays);
+        while (list($key, $array) = each($this->_carrays)) {
+            $contents = $this->_parseCloop($key, $array, $contents);
+        }
+
+        // Parse gettext tags, if the option is enabled.
+        if ($this->getOption('gettext')) {
+            $contents = $this->_parseGettext($contents);
+        }
+
+        // Process loops and arrays.
+        reset($this->_arrays);
+        while (list($key, $array) = each($this->_arrays)) {
+            $contents = $this->_parseLoop($key, $array, $contents);
+        }
+
+        // Return parsed template.
+        return $contents;
+    }
+
+    /**
+     * Returns full start and end tags for a named tag.
+     *
+     * @param string $tag        The name of the tag.
+     * @param string $directive  The kind of tag [tag, if, loop, cloop].
+     *
+     * @return array  'b' => Start tag, 'e' => End tag.
+     */
+    protected function _getTags($tag, $directive)
+    {
+        return array(
+            'b' => '<' . $directive . ':' . $tag . '>',
+            'e' => '</' . $directive . ':' . $tag . '>'
+        );
+    }
+
+    /**
+     * Formats a scalar tag (default format is <tag:name>).
+     *
+     * @param string $tag  The name of the tag.
+     *
+     * @return string  The full tag with the current start/end delimiters.
+     */
+    protected function _getTag($tag)
+    {
+        return '<tag:' . $tag . ' />';
+    }
+
+    /**
+     * Extracts a portion of a template.
+     *
+     * @param array $t           The tag to extract. Hash format is:
+     *                             $t['b'] - The start tag
+     *                             $t['e'] - The end tag
+     * @param string &$contents  The template to extract from.
+     */
+    protected function _getStatement($t, &$contents)
+    {
+        // Locate the statement.
+        $pos = strpos($contents, $t['b']);
+        if ($pos === false) {
+            return false;
+        }
+
+        $tag_length = strlen($t['b']);
+        $fpos = $pos + $tag_length;
+        $lpos = strpos($contents, $t['e']);
+        $length = $lpos - $fpos;
+
+        // Extract & return the statement.
+        return substr($contents, $fpos, $length);
+    }
+
+    /**
+     * Parses gettext tags.
+     *
+     * @param string $contents  The unparsed content of the file.
+     *
+     * @return string  The parsed contents of the gettext blocks.
+     */
+    protected function _parseGettext($contents)
+    {
+        // Get the tags & loop.
+        $t = array(
+            'b' => '<gettext>',
+            'e' => '</gettext>'
+        );
+
+        while ($text = $this->_getStatement($t, $contents)) {
+            $contents = str_replace($t['b'] . $text . $t['e'], _($text), $contents);
+        }
+
+        return $contents;
+    }
+
+    /**
+     * Parses a given if statement.
+     *
+     * @param string $tag       The name of the if block to parse.
+     * @param string $contents  The unparsed contents of the if block.
+     *
+     * @return string  The parsed contents of the if block.
+     */
+    protected function _parseIf($tag, $contents, $key = null)
+    {
+        // Get the tags & if statement.
+        $t = $this->_getTags($tag, 'if');
+        $et = $this->_getTags($tag, 'else');
+
+        // explode the tag, so we have the correct keys for the array
+        if (isset($key)) {
+            list($tg, $k) = explode('.', $tag);
+        }
+        while (($if = $this->_getStatement($t, $contents)) !== false) {
+            // Check for else statement.
+            if ($else = $this->_getStatement($et, $if)) {
+                // Process the if statement.
+                $replace = ((isset($key) && $this->_ifs[$tg][$key][$k]) || (isset($this->_ifs[$tag]) && $this->_ifs[$tag]))
+                    ? str_replace($et['b'] . $else . $et['e'], '', $if)
+                    : $else;
+            } else {
+                // Process the if statement.
+                $replace = isset($key)
+                    ? ($this->_ifs[$tg][$key][$k] ? $if : null)
+                    : ($this->_ifs[$tag] ? $if : null);
+            }
+
+            // Parse the template.
+            $contents = str_replace($t['b'] . $if . $t['e'], $replace, $contents);
+        }
+
+        // Return parsed template.
+        return $contents;
+    }
+
+    /**
+     * Parses the given array for any loops or other uses of the array.
+     *
+     * @param string $tag       The name of the loop to parse.
+     * @param array  $array     The values for the loop.
+     * @param string $contents  The unparsed contents of the loop.
+     *
+     * @return string  The parsed contents of the loop.
+     */
+    protected function _parseLoop($tag, $array, $contents)
+    {
+        // Get the tags & loop.
+        $t = $this->_getTags($tag, 'loop');
+        $loop = $this->_getStatement($t, $contents);
+
+        // See if we have a divider.
+        $l = $this->_getTags($tag, 'divider');
+        $divider = $this->_getStatement($l, $loop);
+        $contents = str_replace($l['b'] . $divider . $l['e'], '', $contents);
+
+        // Process the array.
+        do {
+            $parsed = '';
+            $first = true;
+            reset($array);
+            while (list($key, $value) = each($array)) {
+                if (is_array($value) || is_object($value)) {
+                    $i = $loop;
+                    reset($value);
+                    while (list($key2, $value2) = each($value)) {
+                        if (!is_array($value2) && !is_object($value2)) {
+                            // Replace associative array tags.
+                            $aa_tag = $tag . '.' . $key2;
+                            $i = str_replace($this->_getTag($aa_tag), $value2, $i);
+                            $pos = strpos($tag, '.');
+                            if (($pos !== false) &&
+                                !empty($this->_ifs[substr($tag, 0, $pos)])) {
+                                $this->_ifs[$aa_tag] = $value2;
+                                $i = $this->_parseIf($aa_tag, $i);
+                                unset($this->_ifs[$aa_tag]);
+                            }
+                        } else {
+                            // Check to see if it's a nested loop.
+                            $i = $this->_parseLoop($tag . '.' . $key2, $value2, $i);
+                        }
+                    }
+                    $i = str_replace($this->_getTag($tag), $key, $i);
+                } elseif (is_string($key) && !is_array($value) && !is_object($value)) {
+                    $contents = str_replace($this->_getTag($tag . '.' . $key), $value, $contents);
+                } elseif (!is_array($value) && !is_object($value)) {
+                    $i = str_replace($this->_getTag($tag . ''), $value, $loop);
+                } else {
+                    $i = null;
+                }
+
+                // Parse conditions in the array.
+                if (!empty($this->_ifs[$tag][$key]) &&
+                    is_array($this->_ifs[$tag][$key]) &&
+                    $this->_ifs[$tag][$key]) {
+                    reset($this->_ifs[$tag][$key]);
+                    foreach (array_keys($this->_ifs[$tag][$key]) as $cTag) {
+                        $i = $this->_parseIf($tag . '.' . $cTag, $i, $key);
+                    }
+                }
+
+                // Add the parsed iteration.
+                if (isset($i)) {
+                    // If it's not the first time through, prefix the
+                    // loop divider, if there is one.
+                    if (!$first) {
+                        $i = $divider . $i;
+                    }
+                    $parsed .= rtrim($i);
+                }
+
+                // No longer the first time through.
+                $first = false;
+            }
+
+            // Replace the parsed pieces of the template.
+            $contents = str_replace($t['b'] . $loop . $t['e'], $parsed, $contents);
+        } while ($loop = $this->_getStatement($t, $contents));
+
+        return $contents;
+    }
+
+    /**
+     * Parses the given case loop (cloop).
+     *
+     * @param string $tag       The name of the cloop to parse.
+     * @param array  $array     The values for the cloop.
+     * @param string $contents  The unparsed contents of the cloop.
+     *
+     * @return string  The parsed contents of the cloop.
+     */
+    protected function _parseCloop($tag, $array, $contents)
+    {
+        // Get the tags & cloop.
+        $t = $this->_getTags($tag, 'cloop');
+
+        while ($loop = $this->_getStatement($t, $contents)) {
+            // Set up the cases.
+            $array['cases'][] = 'default';
+            $case_content = array();
+
+            // Get the case strings.
+            foreach ($array['cases'] as $case) {
+                $ctags[$case] = $this->_getTags($case, 'case');
+                $case_content[$case] = $this->_getStatement($ctags[$case], $loop);
+            }
+
+            // Process the cloop.
+            $parsed = '';
+            reset($array['array']);
+            while (list($key, $value) = each($array['array'])) {
+                if (is_numeric($key) &&
+                    (is_array($value) || is_object($value))) {
+                    // Set up the cases.
+                    $current_case = isset($value['case'])
+                        ? $value['case']
+                        : 'default';
+                    unset($value['case']);
+                    $i = $case_content[$current_case];
+
+                    // Loop through each value.
+                    reset($value);
+                    while (list($key2, $value2) = each($value)) {
+                        $i = (is_array($value2) || is_object($value2))
+                            ? $this->_parseLoop($tag . '.' . $key2, $value2, $i)
+                            : str_replace($this->_getTag($tag . '.' . $key2), $value2, $i);
+                    }
+                }
+
+                // Add the parsed iteration.
+                $parsed .= rtrim($i);
+            }
+
+            // Parse the cloop.
+            $contents = str_replace($t['b'] . $loop . $t['e'], $parsed, $contents);
+        }
+
+        return $contents;
+    }
+
+    /**
+     * Fetch the contents of a template into $this->_template; cache
+     * the filename in $this->_templateFile.
+     *
+     * @param string $filename  Location of template file on disk.
+     *
+     * @return string  The loaded template content.
+     * @throws Horde_Exception
+     */
+    protected function _getTemplate($filename = null)
+    {
+        if (!is_null($filename) && ($filename != $this->_templateFile)) {
+            $this->_template = null;
+        }
+
+        if (!is_null($this->_template)) {
+            return $this->_template;
+        }
+
+        // Get the contents of the file.
+        $file = $this->_basepath . $filename;
+        $contents = file_get_contents($file);
+        if ($contents === false) {
+            throw new Horde_Exception(sprintf(_("Template \"%s\" not found."), $file));
+        }
+
+        $this->_template = $contents;
+        $this->_templateFile = $filename;
+
+        return $this->_template;
+    }
+
+}
diff --git a/framework/Template/package.xml b/framework/Template/package.xml
new file mode 100644 (file)
index 0000000..34ca70e
--- /dev/null
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Template</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Template System</summary>
+ <description>Horde Template system. Adapted from bTemplate, by Brian Lozier &lt;brian@massassi.net&gt;.
+ </description>
+ <lead>
+  <name>Chuck Hagenbuch</name>
+  <user>chuck</user>
+  <email>chuck@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Michael Slusarz</name>
+  <user>slusarz</user>
+  <email>slusarz@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <date>2009-06-10</date>
+ <version>
+  <release>0.1.0</release>
+  <api>0.1.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Initial Horde 4 package.
+ </notes>
+ <contents>
+  <dir name="/">
+   <dir name="lib">
+    <dir name="Horde">
+     <file name="Template.php" role="php" />
+    </dir> <!-- /lib/Horde -->
+   </dir> <!-- /lib -->
+   <dir name="test">
+    <dir name="Horde">
+     <dir name="Template">
+      <file name="array_assoc.html" role="test" />
+      <file name="array_assoc.phpt" role="test" />
+      <file name="array_if.html" role="test" />
+      <file name="array_if.phpt" role="test" />
+      <file name="array_nested.html" role="test" />
+      <file name="array_nested.phpt" role="test" />
+      <file name="array_simple.html" role="test" />
+      <file name="array_simple.phpt" role="test" />
+      <file name="divider.html" role="test" />
+      <file name="if.html" role="test" />
+      <file name="if.phpt" role="test" />
+      <file name="iterator.phpt" role="test" />
+      <file name="scalar.html" role="test" />
+      <file name="scalar.phpt" role="test" />
+     </dir> <!-- /test/Horde/Template -->
+    </dir> <!-- /test/Horde -->
+   </dir> <!-- /test -->
+  </dir> <!-- / -->
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+   <package>
+    <name>Horde</name>
+    <channel>pear.horde.org</channel>
+   </package>
+  </required>
+  <optional>
+   <extension>
+    <name>gettext</name>
+   </extension>
+  </optional>
+ </dependencies>
+ <phprelease>
+  <filelist>
+   <install name="lib/Horde/Template.php" as="Horde/Template.php" />
+  </filelist>
+ </phprelease>
+ <changelog>
+  <release>
+   <date>2006-05-08</date>
+   <time>23:32:28</time>
+   <version>
+    <release>0.0.2</release>
+    <api>0.0.2</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+   <notes>
+   - Converted to package.xml 2.0 for pear.horde.org
+   - Remove numeric array key constraint (Request #4413).
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.0.1</release>
+    <api>0.0.1</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2003-07-05</date>
+   <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+   <notes>Initial release as a PEAR package
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/framework/Template/test/Horde/Template/array_assoc.html b/framework/Template/test/Horde/Template/array_assoc.html
new file mode 100644 (file)
index 0000000..f3e92af
--- /dev/null
@@ -0,0 +1 @@
+<tag:foo.one /> <tag:foo.two /> <tag:foo />
\ No newline at end of file
diff --git a/framework/Template/test/Horde/Template/array_assoc.phpt b/framework/Template/test/Horde/Template/array_assoc.phpt
new file mode 100644 (file)
index 0000000..38b39af
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Associative Array Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('foo', array('one' => 'one', 'two' => 2));
+echo $template->fetch('/array_assoc.html');
+
+?>
+--EXPECT--
+one 2 <tag:foo />
diff --git a/framework/Template/test/Horde/Template/array_if.html b/framework/Template/test/Horde/Template/array_if.html
new file mode 100644 (file)
index 0000000..b54f004
--- /dev/null
@@ -0,0 +1,8 @@
+<if:foo><loop:foo>
+<tag:foo />
+</loop:foo></if:foo>
+<if:bar><loop:bar>
+<tag:bar />
+</loop:bar><else:bar>
+else
+</else:bar></if:bar>
diff --git a/framework/Template/test/Horde/Template/array_if.phpt b/framework/Template/test/Horde/Template/array_if.phpt
new file mode 100644 (file)
index 0000000..c05d475
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+If Array Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('foo', array('one', 'two', 'three'), true);
+$template->set('bar', array(), true);
+echo $template->fetch('/array_if.html');
+
+?>
+--EXPECT--
+one
+two
+three
+
+else
diff --git a/framework/Template/test/Horde/Template/array_nested.html b/framework/Template/test/Horde/Template/array_nested.html
new file mode 100644 (file)
index 0000000..7401e48
--- /dev/null
@@ -0,0 +1,10 @@
+<loop:categories>
+<tag:categories /><loop:subcat_<tag:categories />>
+    <tag:subcat_<tag:categories /> />
+</loop:subcat_<tag:categories />>
+</loop:categories>
+<loop:keyed><tag:keyed />
+    <tag:keyed.key1 />
+    <tag:keyed.key2 />
+    <tag:keyed.key3 />
+</loop:keyed>
diff --git a/framework/Template/test/Horde/Template/array_nested.phpt b/framework/Template/test/Horde/Template/array_nested.phpt
new file mode 100644 (file)
index 0000000..f393996
--- /dev/null
@@ -0,0 +1,44 @@
+--TEST--
+Nested Array Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$categories = array('fruit', 'veggie', 'thing');
+$subcats = array('fruit' => array('apple', 'pear'),
+                 'veggie' => array('tomato', 'potato', 'carrot', 'onion'),
+                 'thing' => array('spoon', 'paperbag', 'tool'));
+$template->set('categories', $categories);
+foreach ($categories as $c) {
+    $template->set('subcat_' . $c, $subcats[$c]);
+}
+$template->set('keyed', array('widgets' => array(
+     'key1' => 'zipit',
+     'key2' => 'twisty',
+     'key3' => 'doowhopper'
+)));
+echo $template->fetch('/array_nested.html');
+
+?>
+--EXPECT--
+fruit
+    apple
+    pear
+veggie
+    tomato
+    potato
+    carrot
+    onion
+thing
+    spoon
+    paperbag
+    tool
+widgets
+    zipit
+    twisty
+    doowhopper
diff --git a/framework/Template/test/Horde/Template/array_simple.html b/framework/Template/test/Horde/Template/array_simple.html
new file mode 100644 (file)
index 0000000..c3c3e63
--- /dev/null
@@ -0,0 +1,6 @@
+<loop:string>
+<tag:string />
+</loop:string>
+<loop:int>
+<tag:int />
+</loop:int>
diff --git a/framework/Template/test/Horde/Template/array_simple.phpt b/framework/Template/test/Horde/Template/array_simple.phpt
new file mode 100644 (file)
index 0000000..e691bc7
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+Simple Array Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('string', array('one', 'two', 'three'));
+$template->set('int', array(1, 2, 3));
+echo $template->fetch('/array_simple.html');
+
+?>
+--EXPECT--
+one
+two
+three
+
+1
+2
+3
diff --git a/framework/Template/test/Horde/Template/divider.phpt b/framework/Template/test/Horde/Template/divider.phpt
new file mode 100644 (file)
index 0000000..a01c0c4
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Divider Test
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template();
+$template->set('a', array('a', 'b', 'c', 'd'));
+echo $template->parse("<loop:a><divider:a>,</divider:a><tag:a /></loop:a>");
+
+?>
+--EXPECT--
+a,b,c,d
diff --git a/framework/Template/test/Horde/Template/if.html b/framework/Template/test/Horde/Template/if.html
new file mode 100644 (file)
index 0000000..853d01f
--- /dev/null
@@ -0,0 +1,4 @@
+<if:foo>foo</if:foo>
+<if:bar>bar</if:bar>
+<if:bar>true<else:bar>false</else:bar>void</if:bar>
+<if:baz><tag:baz /></if:baz>
diff --git a/framework/Template/test/Horde/Template/if.phpt b/framework/Template/test/Horde/Template/if.phpt
new file mode 100644 (file)
index 0000000..20d7ec6
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+If/Else Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('foo', true, true);
+$template->set('bar', false, true);
+$template->set('baz', 'baz', true);
+echo $template->fetch('/if.html');
+
+?>
+--EXPECT--
+foo
+
+false
+baz
diff --git a/framework/Template/test/Horde/Template/iterator.phpt b/framework/Template/test/Horde/Template/iterator.phpt
new file mode 100644 (file)
index 0000000..c79b0dd
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Iterator Test
+--SKIPIF--
+<?php
+if (version_compare(PHP_VERSION, '5.0.0', '<')) {
+    echo 'skip Iterator test is not relevant for PHP 4';
+}
+?>
+--FILE--
+<?php
+
+$s = new ArrayObject(array('one', 'two', 'three'));
+$i = new ArrayObject(array(1, 2, 3));
+$a = new ArrayObject(array('one' => 'one', 'two' => 2));
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('s', $s);
+$template->set('i', $i);
+$template->set('a', $a);
+echo $template->parse("<loop:s><tag:s />,</loop:s>\n<loop:i><tag:i />,</loop:i>\n<tag:a.one />,<tag:a.two />,<tag:a />");
+
+?>
+--EXPECT--
+one,two,three,
+1,2,3,
+one,2,<tag:a />
diff --git a/framework/Template/test/Horde/Template/scalar.html b/framework/Template/test/Horde/Template/scalar.html
new file mode 100644 (file)
index 0000000..439cfcb
--- /dev/null
@@ -0,0 +1,2 @@
+<tag:one />
+<tag:two />
diff --git a/framework/Template/test/Horde/Template/scalar.phpt b/framework/Template/test/Horde/Template/scalar.phpt
new file mode 100644 (file)
index 0000000..ac54504
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+Scalar Test
+--FILE--
+<?php
+
+if (defined('E_DEPRECATED')) {
+    error_reporting(error_reporting() & ~E_DEPRECATED);
+}
+
+require dirname(__FILE__) . '/../../../lib/Horde/Template.php';
+$template = new Horde_Template(dirname(__FILE__));
+$template->set('one', 'one');
+$template->set('two', 2);
+echo $template->fetch('/scalar.html');
+
+?>
+--EXPECT--
+one
+2