mirror of
https://github.com/Mibew/handlebars.php.git
synced 2025-04-16 03:17:24 +03:00
Some test improvement and add an ArrayLoader
This commit is contained in:
parent
3514a2b151
commit
939c58bbee
76
src/Handlebars/Loader/ArrayLoader.php
Normal file
76
src/Handlebars/Loader/ArrayLoader.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Handlebars-php
|
||||
* Base on mustache-php https://github.com/bobthecow/mustache.php
|
||||
*
|
||||
* PHP version 5.3
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @copyright 2014 (c) f0ruD
|
||||
* @license MIT <http://opensource.org/licenses/MIT>
|
||||
* @version GIT: $Id$
|
||||
* @link http://xamin.ir
|
||||
*/
|
||||
|
||||
namespace Handlebars\Loader;
|
||||
|
||||
use Handlebars\Loader;
|
||||
|
||||
/**
|
||||
* Handlebars Template array Loader implementation.
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @copyright 2014 (c) f0ruD
|
||||
* @license MIT <http://opensource.org/licenses/MIT>
|
||||
* @version Release: @package_version@
|
||||
* @link http://xamin.ir *
|
||||
*/
|
||||
class ArrayLoader implements Loader
|
||||
{
|
||||
private $_templates;
|
||||
|
||||
/**
|
||||
* Create a new loader with associative array style
|
||||
*
|
||||
* @param array $templates the templates to load
|
||||
*/
|
||||
public function __construct(array $templates = array())
|
||||
{
|
||||
$this->_templates = $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a template to list
|
||||
*
|
||||
* @param string $name template name
|
||||
* @param string $template the template
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addTemplate($name, $template)
|
||||
{
|
||||
$this->_templates[$name] = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* @param string $name template name to load
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return String
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
if (isset($this->_templates[$name])) {
|
||||
return $this->_templates[$name];
|
||||
}
|
||||
throw new \RuntimeException(
|
||||
"Can not find the $name template"
|
||||
);
|
||||
}
|
||||
}
|
@ -243,6 +243,100 @@ class Template
|
||||
array_push($this->_stack, $topStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process handlebars section style
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
private function _handlebarsStyleSection(Context $context, $current)
|
||||
{
|
||||
$helpers = $this->handlebars->getHelpers();
|
||||
$sectionName = $current[Tokenizer::NAME];
|
||||
|
||||
if (isset($current[Tokenizer::END])) {
|
||||
$source = substr(
|
||||
$this->getSource(),
|
||||
$current[Tokenizer::INDEX],
|
||||
$current[Tokenizer::END] - $current[Tokenizer::INDEX]
|
||||
);
|
||||
} else {
|
||||
$source = '';
|
||||
}
|
||||
$params = array(
|
||||
$this, //First argument is this template
|
||||
$context, //Second is current context
|
||||
$current[Tokenizer::ARGS], //Arguments
|
||||
$source
|
||||
);
|
||||
|
||||
$return = call_user_func_array($helpers->$sectionName, $params);
|
||||
if ($return instanceof String) {
|
||||
return $this->handlebars->loadString($return)->render($context);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Mustache section style
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return mixed|string
|
||||
*/
|
||||
private function _mustacheStyleSection(Context $context, $current)
|
||||
{
|
||||
$sectionName = $current[Tokenizer::NAME];
|
||||
|
||||
// fallback to mustache style each/with/for just if there is
|
||||
// no argument at all.
|
||||
try {
|
||||
$sectionVar = $context->get($sectionName, true);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new \RuntimeException(
|
||||
$sectionName . ' is not registered as a helper'
|
||||
);
|
||||
}
|
||||
$buffer = '';
|
||||
if (is_array($sectionVar) || $sectionVar instanceof \Traversable) {
|
||||
$isList = is_array($sectionVar) &&
|
||||
(array_keys($sectionVar) == range(0, count($sectionVar) - 1));
|
||||
$index = 0;
|
||||
$lastIndex = $isList ? (count($sectionVar) - 1) : false;
|
||||
|
||||
foreach ($sectionVar as $key => $d) {
|
||||
$specialVariables = array(
|
||||
'@index' => $index,
|
||||
'@first' => ($index === 0),
|
||||
'@last' => ($index === $lastIndex),
|
||||
);
|
||||
if (!$isList) {
|
||||
$specialVariables['@key'] = $key;
|
||||
}
|
||||
$context->pushSpecialVariables($specialVariables);
|
||||
$context->push($d);
|
||||
$buffer .= $this->render($context);
|
||||
$context->pop();
|
||||
$context->popSpecialVariables();
|
||||
$index++;
|
||||
}
|
||||
} elseif (is_object($sectionVar)) {
|
||||
//Act like with
|
||||
$context->push($sectionVar);
|
||||
$buffer = $this->render($context);
|
||||
$context->pop();
|
||||
} elseif ($sectionVar) {
|
||||
$buffer = $this->render($context);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process section nodes
|
||||
*
|
||||
@ -257,70 +351,9 @@ class Template
|
||||
$helpers = $this->handlebars->getHelpers();
|
||||
$sectionName = $current[Tokenizer::NAME];
|
||||
if ($helpers->has($sectionName)) {
|
||||
if (isset($current[Tokenizer::END])) {
|
||||
$source = substr(
|
||||
$this->getSource(),
|
||||
$current[Tokenizer::INDEX],
|
||||
$current[Tokenizer::END] - $current[Tokenizer::INDEX]
|
||||
);
|
||||
} else {
|
||||
$source = '';
|
||||
}
|
||||
$params = array(
|
||||
$this, //First argument is this template
|
||||
$context, //Second is current context
|
||||
$current[Tokenizer::ARGS], //Arguments
|
||||
$source
|
||||
);
|
||||
|
||||
$return = call_user_func_array($helpers->$sectionName, $params);
|
||||
if ($return instanceof String) {
|
||||
return $this->handlebars->loadString($return)->render($context);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
return $this->_handlebarsStyleSection($context, $current);
|
||||
} elseif (trim($current[Tokenizer::ARGS]) == '') {
|
||||
// fallback to mustache style each/with/for just if there is
|
||||
// no argument at all.
|
||||
try {
|
||||
$sectionVar = $context->get($sectionName, true);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new \RuntimeException(
|
||||
$sectionName . ' is not registered as a helper'
|
||||
);
|
||||
}
|
||||
$buffer = '';
|
||||
if (is_array($sectionVar) || $sectionVar instanceof \Traversable) {
|
||||
$isList = is_array($sectionVar) && (array_keys($sectionVar) == range(0, count($sectionVar) - 1));
|
||||
$index = 0;
|
||||
$lastIndex = $isList ? (count($sectionVar) - 1) : false;
|
||||
|
||||
foreach ($sectionVar as $key => $d) {
|
||||
$specialVariables = array(
|
||||
'@index' => $index,
|
||||
'@first' => ($index === 0),
|
||||
'@last' => ($index === $lastIndex),
|
||||
);
|
||||
if (!$isList) {
|
||||
$specialVariables['@key'] = $key;
|
||||
}
|
||||
$context->pushSpecialVariables($specialVariables);
|
||||
$context->push($d);
|
||||
$buffer .= $this->render($context);
|
||||
$context->pop();
|
||||
$context->popSpecialVariables();
|
||||
$index++;
|
||||
}
|
||||
} elseif (is_object($sectionVar)) {
|
||||
//Act like with
|
||||
$context->push($sectionVar);
|
||||
$buffer = $this->render($context);
|
||||
$context->pop();
|
||||
} elseif ($sectionVar) {
|
||||
$buffer = $this->render($context);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
return $this->_mustacheStyleSection($context, $current);
|
||||
} else {
|
||||
throw new \RuntimeException(
|
||||
$sectionName . ' is not registered as a helper'
|
||||
@ -380,6 +413,7 @@ class Template
|
||||
$helpers = $this->getEngine()->getHelpers();
|
||||
// Tokenizer doesn't process the args -if any- so be aware of that
|
||||
$name = explode(' ', $current[Tokenizer::NAME], 2);
|
||||
|
||||
return $helpers->has(reset($name));
|
||||
}
|
||||
|
||||
@ -457,32 +491,34 @@ class Template
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Break an argument string into an array of strings
|
||||
*
|
||||
* @param string $string Argument String as passed to a helper
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return array the argument list as an array
|
||||
*/
|
||||
public function parseArguments($string)
|
||||
{
|
||||
$args = array();
|
||||
preg_match_all('#(?:[^\'"\[\]\s]|\[.+?\])+|(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $args);
|
||||
$args = isset($args[0])?$args[0]:array();
|
||||
|
||||
for ($x=0, $argc = count($args); $x<$argc;$x++) {
|
||||
$args = isset($args[0]) ? $args[0] : array();
|
||||
|
||||
for ($x = 0, $argc = count($args); $x < $argc; $x++) {
|
||||
// check to see if argument is a quoted string literal
|
||||
if ($args[$x][0] == "'" || $args[$x][0] == '"') {
|
||||
if ($args[$x][0] === substr($args[$x], -1)) {
|
||||
// remove enclosing quotes and unescape
|
||||
$args[$x] = new \Handlebars\String(stripcslashes(substr($args[$x], 1, strlen($args[$x]) -2)));
|
||||
$args[$x] = new \Handlebars\String(stripcslashes(substr($args[$x], 1, strlen($args[$x]) - 2)));
|
||||
} else {
|
||||
throw new \RuntimeException("Malformed string: ".$args);
|
||||
throw new \RuntimeException("Malformed string: " . $args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +283,22 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('<strong>Test</strong>', $engine->render('{{safeStringTest}}', array()));
|
||||
}
|
||||
|
||||
public function testInvalidHelperMustacheStyle()
|
||||
{
|
||||
$this->setExpectedException('RuntimeException');
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
|
||||
$engine->render('{{#NOTVALID}}XXX{{/NOTVALID}}', array());
|
||||
}
|
||||
|
||||
public function testInvalidHelper()
|
||||
{
|
||||
$this->setExpectedException('RuntimeException');
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
|
||||
$engine->render('{{#NOTVALID argument}}XXX{{/NOTVALID}}', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test mustache style loop and if
|
||||
*/
|
||||
@ -412,6 +428,18 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(1, count(glob($path . '/*')));
|
||||
}
|
||||
|
||||
public function testArrayLoader()
|
||||
{
|
||||
$loader = new \Handlebars\Loader\ArrayLoader(array('test' => 'HELLO'));
|
||||
$loader->addTemplate('another', 'GOODBYE');
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
|
||||
$this->assertEquals($engine->render('test', array()), 'HELLO');
|
||||
$this->assertEquals($engine->render('another', array()), 'GOODBYE');
|
||||
|
||||
$this->setExpectedException('RuntimeException');
|
||||
$engine->render('invalid-template', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test file system loader
|
||||
*/
|
||||
@ -477,6 +505,29 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('test', $engine->render('{{>loader}}', array()));
|
||||
}
|
||||
|
||||
public function testPartial()
|
||||
{
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$partialLoader = new \Handlebars\Loader\ArrayLoader(array('test' => '{{key}}', 'bar' => 'its foo'));
|
||||
$partialAliasses = array('foo' => 'bar');
|
||||
$engine = new \Handlebars\Handlebars(
|
||||
array(
|
||||
'loader' => $loader,
|
||||
'partials_loader' => $partialLoader,
|
||||
'partials_alias' => $partialAliasses
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals('HELLO', $engine->render('{{>test parameter}}', array('parameter' => array('key' => 'HELLO'))));
|
||||
$this->assertEquals('its foo', $engine->render('{{>foo}}', array()));
|
||||
$engine->registerPartial('foo-again', 'bar');
|
||||
$this->assertEquals('its foo', $engine->render('{{>foo-again}}', array()));
|
||||
$engine->unRegisterPartial('foo-again');
|
||||
|
||||
$this->setExpectedException('RuntimeException');
|
||||
$engine->render('{{>foo-again}}', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* test variable access
|
||||
*/
|
||||
@ -588,11 +639,12 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
||||
array('"arg1.[value 1]" arg2', array("arg1.[value 1]", 'arg2')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Argument Parser
|
||||
*
|
||||
* @param string $arg_string argument text
|
||||
* @param array $arg_ array data
|
||||
* @param $expected_array
|
||||
*
|
||||
* @dataProvider argumentParserProvider
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user