1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-07-18 23:51:49 +02:00

Merge remote-tracking branch 'github-p/feature/template-engine' into develop

* github-p/feature/template-engine: (87 commits)
  [feature/template-engine] Delete _get_locator function.
  [feature/template-engine] Clean up template locator usage in bbcode.
  [feature/template-engine] Need to call set_template on template.
  [feature/template-engine] Update installer for template engine changes.
  [feature/template-engine] Dependency inject locator into template.
  [feature/template-engine] Delete useless code from set_template.
  [feature/template-engine] Delete no longer used $template_filename property.
  [feature/template-engine] Delete useless $template globalization.
  [feature/template-engine] Use template engine class in bbcode class.
  [feature/template-engine] Corrected an error message in template locator.
  [feature/template-engine] Remaining documentation.
  [feature/template-engine] More documentation for template class.
  [feature/template-engine] Create load_and_render to reduce code duplication.
  [feature/template-engine] Get rid of orig_tpl_* in template engine.
  [feature/template-engine] Delete $style_name param from locator's set_custom_template.
  [feature/template-engine] Add constructor to template locator.
  [feature/template-engine] Factor template locator out of template class.
  [feature/template-engine] Delete $files_template property.
  [feature/template-engine] Rename is_absolute to phpbb_is_absolute.
  [feature/template-engine] Test template DEFINE statements across files
  ...

Conflicts:
	.gitignore
	phpBB/includes/template.php
This commit is contained in:
Nils Adermann
2011-08-13 23:59:15 -04:00
43 changed files with 2771 additions and 1712 deletions

View File

@@ -0,0 +1,47 @@
<?php
/**
*
* @package testing
* @copyright (c) 2011 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/template_test_case.php';
class phpbb_template_includephp_test extends phpbb_template_template_test_case
{
public function test_includephp_relative()
{
$this->setup_engine(array('tpl_allow_php' => true));
$cache_file = $this->template->cachepath . 'includephp_relative.html.php';
$this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file);
$this->template->set_filenames(array('test' => 'includephp_relative.html'));
$this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP");
}
public function test_includephp_absolute()
{
$path_to_php = dirname(__FILE__) . '/templates/_dummy_include.php.inc';
$this->assertTrue(phpbb_is_absolute($path_to_php));
$template_text = "Path is absolute.\n<!-- INCLUDEPHP $path_to_php -->";
$cache_dir = dirname($this->template->cachepath) . '/';
$fp = fopen($cache_dir . 'includephp_absolute.html', 'w');
fputs($fp, $template_text);
fclose($fp);
$this->setup_engine(array('tpl_allow_php' => true));
$this->template->set_custom_template($cache_dir, 'tests');
$cache_file = $this->template->cachepath . 'includephp_absolute.html.php';
$this->run_template('includephp_absolute.html', array(), array(), array(), "Path is absolute.\ntesting included php", $cache_file);
$this->template->set_filenames(array('test' => 'includephp_absolute.html'));
$this->assertEquals("Path is absolute.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP");
}
}

View File

@@ -0,0 +1 @@
Parent template.

View File

@@ -0,0 +1 @@
Only in parent.

View File

@@ -0,0 +1,29 @@
<?php
/**
*
* @package testing
* @copyright (c) 2011 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/../template_test_case.php';
class phpbb_template_subdir_includephp_from_subdir_test extends phpbb_template_template_test_case
{
// Exact copy of test_includephp_relatve from ../includephp_test.php.
// Verifies that relative php inclusion works when including script
// (and thus current working directory) is in a subdirectory of
// board root.
public function test_includephp_relative()
{
$this->setup_engine(array('tpl_allow_php' => true));
$cache_file = $this->template->cachepath . 'includephp_relative.html.php';
$this->run_template('includephp_relative.html', array(), array(), array(), "Path is relative to board root.\ntesting included php", $cache_file);
$this->template->set_filenames(array('test' => 'includephp_relative.html'));
$this->assertEquals("Path is relative to board root.\ntesting included php", $this->display('test'), "Testing INCLUDEPHP");
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
*
* @package testing
* @copyright (c) 2011 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
class phpbb_template_template_compile_test extends phpbb_test_case
{
private $template_compile;
private $template_path;
protected function setUp()
{
$this->template_compile = new phpbb_template_compile(false);
$this->template_path = dirname(__FILE__) . '/templates';
}
public function test_in_phpbb()
{
$output = $this->template_compile->compile_file($this->template_path . '/trivial.html');
$this->assertTrue(strlen($output) > 0);
$statements = explode(';', $output);
$first_statement = $statements[0];
$this->assertTrue(!!preg_match('#if.*defined.*IN_PHPBB.*exit#', $first_statement));
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
*
* @package testing
* @copyright (c) 2011 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/template_test_case.php';
class phpbb_template_template_inheritance_test extends phpbb_template_template_test_case
{
/**
* @todo put test data into templates/xyz.test
*/
public static function template_data()
{
return array(
// First element of the array is test name - keep them distinct
array(
'simple inheritance - only parent template exists',
'parent_only.html',
array(),
array(),
array(),
"Only in parent.",
),
array(
'simple inheritance - only child template exists',
'child_only.html',
array(),
array(),
array(),
"Only in child.",
),
array(
'simple inheritance - both parent and child templates exist',
'parent_and_child.html',
array(),
array(),
array(),
"Child template.",
),
);
}
/**
* @dataProvider template_data
*/
public function test_template($name, $file, array $vars, array $block_vars, array $destroy, $expected)
{
$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php';
$this->assertFileNotExists($cache_file);
$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
// Reset the engine state
$this->setup_engine();
$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
}
protected function setup_engine()
{
global $phpbb_root_path, $phpEx, $config, $user;
$this->template_path = dirname(__FILE__) . '/templates';
$this->parent_template_path = dirname(__FILE__) . '/parent_templates';
$this->template_locator = new phpbb_template_locator();
$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->template_locator);
$this->template->set_custom_template($this->template_path, 'tests', $this->parent_template_path);
}
}

View File

@@ -8,69 +8,10 @@
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/template.php';
require_once dirname(__FILE__) . '/template_test_case.php';
class phpbb_template_template_test extends phpbb_test_case
class phpbb_template_template_test extends phpbb_template_template_test_case
{
private $template;
private $template_path;
// Keep the contents of the cache for debugging?
const PRESERVE_CACHE = false;
private function display($handle)
{
ob_start();
$this->assertTrue($this->template->display($handle, false));
return self::trim_template_result(ob_get_clean());
}
private static function trim_template_result($result)
{
return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result)))));
}
private function setup_engine()
{
$this->template_path = dirname(__FILE__) . '/templates';
$this->template = new template();
$this->template->set_custom_template($this->template_path, 'tests');
}
protected function setUp()
{
$this->markTestIncomplete("template::display raises notices.");
// Test the engine can be used
$this->setup_engine();
if (!is_writable(dirname($this->template->cachepath)))
{
$this->markTestSkipped("Template cache directory is not writable.");
}
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
$GLOBALS['config'] = array(
'load_tplcompile' => true,
'tpl_allow_php' => false,
);
}
protected function tearDown()
{
if (is_object($this->template))
{
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
}
}
/**
* @todo put test data into templates/xyz.test
*/
@@ -91,7 +32,7 @@ class phpbb_template_template_test extends phpbb_test_case
array(),
array(),
array(),
"pass\npass\n<!-- DUMMY var -->",
"pass\npass\npass\n<!-- DUMMY var -->",
),
array(
'variable.html',
@@ -105,14 +46,14 @@ class phpbb_template_template_test extends phpbb_test_case
array(),
array(),
array(),
'0',
'03',
),
array(
'if.html',
array('S_VALUE' => true),
array(),
array(),
"1\n0",
'1',
),
array(
'if.html',
@@ -161,22 +102,22 @@ class phpbb_template_template_test extends phpbb_test_case
array(),
array('loop' => array(array('VARIABLE' => 'x'))),
array(),
"first\n0\nx\nset\nlast",
),/* no nested top level loops
"first\n0 - a\nx - b\nset\nlast",
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y'))),
array(),
"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",
"first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast",
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
array(),
"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast\n0\n\n1\nlast inner\ninner loop",
),*/
"first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast\n0 - c\n1 - c\nlast inner\ninner loop",
),
array(
'loop_advanced.html',
array(),
@@ -189,14 +130,23 @@ class phpbb_template_template_test extends phpbb_test_case
array(),
array('loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())),
array(),
"xyz\nabc",
"xyz\nabc\nabc\nbar\nbar\nabc",
),
array(
'expressions.html',
array(),
array(),
array(),
trim(str_repeat("pass", 39)),
trim(str_repeat("pass\n", 10) . "\n"
. str_repeat("pass\n", 4) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 6) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 6) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 3) . "\n"
. str_repeat("pass\n", 2) . "\n"),
),
array(
'php.html',
@@ -226,6 +176,15 @@ class phpbb_template_template_test extends phpbb_test_case
array('loop.inner'),
"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",
),*/
array(
// Just like a regular loop but the name begins
// with an underscore
'loop_underscore.html',
array(),
array(),
array(),
"noloop\nnoloop",
),
array(
'lang.html',
array(),
@@ -247,6 +206,46 @@ class phpbb_template_template_test extends phpbb_test_case
array(),
"{ VARIABLE }\nValue'",
),
array(
'loop_nested_multilevel_ref.html',
array(),
array(),
array(),
"top-level content",
),
array(
'loop_nested_multilevel_ref.html',
array(),
array('outer' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'outer.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))),
array(),
// I don't completely understand this output, hopefully it's correct
"top-level content\nouter x\nouter y\ninner z\nfirst row\n\ninner zz",
),
array(
'loop_nested_deep_multilevel_ref.html',
array(),
array('outer' => array(array()), 'outer.middle' => array(array()), 'outer.middle.inner' => array(array('VARIABLE' => 'z'), array('VARIABLE' => 'zz'))),
array(),
// I don't completely understand this output, hopefully it's correct
"top-level content\nouter\n\ninner z\nfirst row\n\ninner zz",
),
array(
'loop_size.html',
array(),
array('loop' => array(array()), 'empty_loop' => array()),
array(),
"nonexistent = 0\n! nonexistent\n\nempty = 0\n! empty\nloop\n\nin loop",
),
/* Does not pass with the current implementation.
array(
'loop_reuse.html',
array(),
array('one' => array(array('VAR' => 'a'), array('VAR' => 'b')), 'one.one' => array(array('VAR' => 'c'), array('VAR' => 'd'))),
array(),
// Not entirely sure what should be outputted but the current output of "a" is most certainly wrong
"a\nb\nc\nd",
),
*/
);
}
@@ -257,7 +256,7 @@ class phpbb_template_template_test extends phpbb_test_case
$this->template->set_filenames(array('test' => $filename));
$this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist');
$expecting = sprintf('template->_tpl_load_file(): File %s does not exist or is empty', realpath($this->template_path . '/../') . '/templates/' . $filename);
$expecting = sprintf('template locator: File %s does not exist', realpath($this->template_path . '/../') . '/templates/' . $filename);
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->display('test');
@@ -265,7 +264,7 @@ class phpbb_template_template_test extends phpbb_test_case
public function test_empty_file()
{
$expecting = 'template->set_filenames: Empty filename specified for test';
$expecting = 'template locator: set_filenames: Empty filename specified for test';
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->template->set_filenames(array('test' => ''));
@@ -273,52 +272,12 @@ class phpbb_template_template_test extends phpbb_test_case
public function test_invalid_handle()
{
$expecting = 'template->_tpl_load(): No file specified for handle test';
$expecting = 'No file specified for handle test';
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->display('test');
}
private function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file)
{
$this->template->set_filenames(array('test' => $file));
$this->template->assign_vars($vars);
foreach ($block_vars as $block => $loops)
{
foreach ($loops as $_vars)
{
$this->template->assign_block_vars($block, $_vars);
}
}
foreach ($destroy as $block)
{
$this->template->destroy_block_vars($block);
}
try
{
$this->assertEquals($expected, $this->display('test'), "Testing $file");
$this->assertFileExists($cache_file);
}
catch (ErrorException $e)
{
if (file_exists($cache_file))
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
throw $e;
}
// For debugging
if (self::PRESERVE_CACHE)
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
}
/**
* @dataProvider template_data
*/
@@ -360,43 +319,22 @@ class phpbb_template_template_test extends phpbb_test_case
$this->template->destroy_block_vars($block);
}
$error_level = error_reporting();
error_reporting($error_level & ~E_NOTICE);
$this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)");
$this->template->assign_display('test', 'VARIABLE', false);
error_reporting($error_level);
$this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)");
}
public function test_php()
{
$GLOBALS['config']['tpl_allow_php'] = true;
$this->setup_engine(array('tpl_allow_php' => true));
$cache_file = $this->template->cachepath . 'php.html.php';
$this->assertFileNotExists($cache_file);
$this->run_template('php.html', array(), array(), array(), 'test', $cache_file);
$GLOBALS['config']['tpl_allow_php'] = false;
}
public function test_includephp()
{
$GLOBALS['config']['tpl_allow_php'] = true;
$cache_file = $this->template->cachepath . 'includephp.html.php';
$this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file);
$this->template->set_filenames(array('test' => 'includephp.html'));
$this->assertEquals('testing included php', $this->display('test'), "Testing INCLUDEPHP");
$GLOBALS['config']['tpl_allow_php'] = false;
}
public static function alter_block_array_data()
@@ -507,5 +445,5 @@ EOT
$this->template->alter_block_array($alter_block, $vararray, $key, $mode);
$this->assertEquals($expect, $this->display('test'), $description);
}
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
*
* @package testing
* @copyright (c) 2011 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
class phpbb_template_template_test_case extends phpbb_test_case
{
protected $template;
protected $template_path;
protected $template_locator;
// Keep the contents of the cache for debugging?
const PRESERVE_CACHE = true;
protected function display($handle)
{
ob_start();
$this->assertTrue($this->template->display($handle));
return self::trim_template_result(ob_get_clean());
}
protected static function trim_template_result($result)
{
return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result)))));
}
protected function setup_engine(array $new_config = array())
{
global $phpbb_root_path, $phpEx, $user;
$defaults = array(
'load_tplcompile' => true,
'tpl_allow_php' => false,
);
$config = new phpbb_config(array_merge($defaults, $new_config));
$this->template_path = dirname(__FILE__) . '/templates';
$this->template_locator = new phpbb_template_locator();
$this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->template_locator);
$this->template->set_custom_template($this->template_path, 'tests');
}
protected function setUp()
{
// Test the engine can be used
$this->setup_engine();
if (!is_writable(dirname($this->template->cachepath)))
{
$this->markTestSkipped("Template cache directory is not writable.");
}
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
$this->setup_engine();
}
protected function tearDown()
{
if (is_object($this->template))
{
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
}
}
protected function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file)
{
$this->template->set_filenames(array('test' => $file));
$this->template->assign_vars($vars);
foreach ($block_vars as $block => $loops)
{
foreach ($loops as $_vars)
{
$this->template->assign_block_vars($block, $_vars);
}
}
foreach ($destroy as $block)
{
$this->template->destroy_block_vars($block);
}
try
{
$this->assertEquals($expected, $this->display('test'), "Testing $file");
$this->assertFileExists($cache_file);
}
catch (ErrorException $e)
{
if (file_exists($cache_file))
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
throw $e;
}
// For debugging.
// When testing eval path the cache file may not exist.
if (self::PRESERVE_CACHE && file_exists($cache_file))
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
}
}

View File

@@ -16,5 +16,8 @@ fail
<!-- BEGINELSE -->
pass
<!-- END empty -->
<!-- IF not S_EMPTY -->
pass
<!-- ENDIF -->
<!-- DUMMY var -->

View File

@@ -0,0 +1 @@
Only in child.

View File

@@ -2,6 +2,9 @@
{$VALUE}
<!-- DEFINE $VALUE = 'abc' -->
{$VALUE}
<!-- INCLUDE define_include.html -->
{$INCLUDED_VALUE}
{$VALUE}
<!-- UNDEFINE $VALUE -->
{$VALUE}
<!-- DEFINE $VALUE -->

View File

@@ -0,0 +1,3 @@
{$VALUE}
<!-- DEFINE $INCLUDED_VALUE = 'bar' -->
{$INCLUDED_VALUE}

View File

@@ -1,86 +1,57 @@
<!-- IF 10 is even -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 is even -->fail<!-- ELSE -->pass<!-- ENDIF -->
<!-- IF not 390 is even -->fail<!-- ELSE -->pass<!-- ENDIF -->
<!-- IF 9 is odd -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 32 is odd -->fail<!-- ELSE -->pass<!-- ENDIF -->
<!-- IF 32 is div by 16 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 is not even -->fail<!-- ELSE -->pass<!-- ENDIF -->
<!-- IF 24 == 24 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 eq 24 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF ((((((24 == 24)))))) -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 != 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 <> 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 ne 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 neq 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 lt 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 < 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 10 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 20 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 20 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 20 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 gt 1 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 > 1 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 >= 1 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 gte 1 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 ge 1 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 >= 9 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 gte 9 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 9 ge 9 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF true && (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF true and (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF false || true -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF false or true -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF !false -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF not false -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF not not not false -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 6 % 4 == 2 -->pass<!-- ELSE -->fail<!-- ENDIF -->
<!-- IF 24 mod 12 == 0 -->pass<!-- ELSE -->fail<!-- ENDIF -->

View File

@@ -3,9 +3,9 @@
<!-- ELSEIF S_OTHER_VALUE -->
2
<!-- ELSE -->
0
03
<!-- ENDIF -->
<!-- IF (S_VALUE > S_OTHER_VALUE) -->
0
<!-- IF S_VALUE and S_OTHER_VALUE and (S_VALUE > S_OTHER_VALUE) -->
04
<!-- ENDIF -->

View File

@@ -1 +1,2 @@
Path is relative to board root.
<!-- INCLUDEPHP ../tests/template/templates/_dummy_include.php.inc -->

View File

@@ -1,8 +1,6 @@
<!-- BEGIN outer -->
outer - {outer.S_ROW_COUNT}<!-- IF outer.VARIABLE --> - {outer.VARIABLE}<!-- ENDIF -->
<!-- BEGIN middle -->
middle - {middle.S_ROW_COUNT}<!-- IF middle.VARIABLE --> - {middle.VARIABLE}<!-- ENDIF -->
<!-- END middle -->
<!-- END outer -->

View File

@@ -0,0 +1,12 @@
top-level content
<!-- BEGIN outer -->
outer
<!-- BEGIN middle -->
<!-- BEGIN inner -->
inner {inner.VARIABLE}
<!-- IF outer.middle.inner.S_FIRST_ROW -->
first row
<!-- ENDIF -->
<!-- END inner -->
<!-- END middle -->
<!-- END outer -->

View File

@@ -0,0 +1,10 @@
top-level content
<!-- BEGIN outer -->
outer {outer.VARIABLE}
<!-- BEGIN inner -->
inner {inner.VARIABLE}
<!-- IF outer.inner.S_FIRST_ROW -->
first row
<!-- ENDIF -->
<!-- END inner -->
<!-- END outer -->

View File

@@ -0,0 +1,6 @@
<!-- BEGIN one -->
{one.VAR}
<!-- BEGIN one -->
{one.one.VAR}
<!-- END one -->
<!-- END one -->

View File

@@ -0,0 +1,39 @@
<!-- IF .nonexistent_loop -->
nonexistent
<!-- ENDIF -->
<!-- IF .nonexistent_loop == 0 -->
nonexistent = 0
<!-- ENDIF -->
<!-- IF ! .nonexistent_loop -->
! nonexistent
<!-- ENDIF -->
<!-- IF .empty_loop -->
empty
<!-- ENDIF -->
<!-- IF .empty_loop == 0 -->
empty = 0
<!-- ENDIF -->
<!-- IF ! .empty_loop -->
! empty
<!-- ENDIF -->
<!-- IF .loop -->
loop
<!-- ENDIF -->
<!-- IF .loop == 0 -->
loop = 0
<!-- ENDIF -->
<!-- IF ! .loop -->
! loop
<!-- ENDIF -->
<!-- BEGIN loop -->
in loop
<!-- END -->

View File

@@ -0,0 +1,21 @@
<!-- BEGIN _underscore_loop -->
loop
<!-- BEGINELSE -->
noloop
<!-- END loop -->
<!-- IF ._underscore_loop -->
loop
<!-- ELSE -->
noloop
<!-- ENDIF -->
<!-- IF ._underscore_loop == 2 -->
loop
<!-- ENDIF -->
<!-- BEGIN _underscore_loop -->
<!-- BEGIN !block -->
loop#{loop.S_ROW_COUNT}-block#{block.S_ROW_COUNT}
<!-- END !block -->
<!-- END _underscore_loop -->

View File

@@ -1,21 +1,14 @@
<!-- BEGIN loop -->
<!-- IF loop.S_FIRST_ROW -->first<!-- ENDIF -->
{loop.S_ROW_COUNT}
{loop.VARIABLE}
{loop.S_ROW_NUM} - a
{loop.VARIABLE} - b
<!-- IF loop.VARIABLE -->set<!-- ENDIF -->
<!-- IF loop.S_LAST_ROW -->
last
<!-- ENDIF -->
<!-- BEGIN inner -->
{inner.S_ROW_COUNT}
{inner.S_ROW_NUM} - c
<!-- IF inner.S_LAST_ROW and inner.S_ROW_COUNT and inner.S_NUM_ROWS -->last inner<!-- ENDIF -->
<!-- END inner -->
<!-- END loop -->
<!-- IF .loop.inner -->inner loop<!-- ENDIF -->

View File

@@ -0,0 +1 @@
Child template.

View File

@@ -0,0 +1 @@
This is a trivial template.