Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/Dust/Dust.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ class Dust implements \Serializable {

public $autoloaderOverride;

public function __construct($parser = null, $evaluator = null) {
// Default template extension
private $_extension = 'dust';

public function __construct($parser = null, $evaluator = null, $options = null) {
if ($parser === null) $parser = new Parse\Parser();
if ($evaluator === null) $evaluator = new Evaluate\Evaluator($this);
$this->parser = $parser;
Expand Down Expand Up @@ -47,6 +50,14 @@ public function __construct($parser = null, $evaluator = null) {
"contextDump" => new Helper\ContextDump()
];
$this->automaticFilters = [$this->filters['h']];

if (is_array($options)) {
if (isset($options['extension'])) {
$extension = $options['extension'];
$this->_extension = $extension{0} === '.' ? substr($extension, 1) : $extension;
}
}

}

public function compile($source, $name = null) {
Expand All @@ -62,7 +73,10 @@ public function compileFn($source, $name = null) {

public function resolveAbsoluteDustFilePath($path, $basePath = null) {
//add extension if necessary
if (substr_compare($path, '.dust', -5, 5) !== 0) $path .= '.dust';
$ext = explode('.', $path);
if (end($ext) !== $this->_extension) {
$path .= '.' . $this->_extension;
}
if ($basePath != null) {
$possible = realpath($basePath . '/' . $path);
if ($possible !== false) return $possible;
Expand Down
38 changes: 19 additions & 19 deletions src/Dust/Evaluate/Evaluator.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
use Dust\Filter;
class Evaluator {
public $dust;

public $options;

public function __construct(\Dust\Dust $dust, $options = null) {
if ($options === null) $options = new EvaluatorOptions();
$this->dust = $dust;
$this->options = $options;
}

public function error(Ast\Ast $ast = null, $message = null) {
throw new EvaluateException($ast, $message);
}

public function evaluate(Ast\Body $source, $state) {
return trim($this->evaluateBody($source, new Context($this, null, new State($state)), new Chunk($this))->out);
}

public function evaluateBody(Ast\Body $body, Context $ctx, Chunk $chunk) {
//go ahead and set the file path on the current context
$ctx->currentFilePath = $body->filePath;
Expand All @@ -35,7 +35,7 @@ public function evaluateBody(Ast\Body $body, Context $ctx, Chunk $chunk) {
}
return $chunk;
}

public function evaluateSection(Ast\Section $section, Context $ctx, Chunk $chunk) {
//stuff that doesn't need resolution
if ($section->type == '+') {
Expand Down Expand Up @@ -63,7 +63,7 @@ public function evaluateSection(Ast\Section $section, Context $ctx, Chunk $chunk
}
//do we have the helper?
if (!isset($this->dust->helpers[$section->identifier->key])) {
$this->error($section->identifier, 'Unable to find helper');
$this->error($section->identifier, 'Unable to find helper: ' . $section->identifier->key);
}
$helper = $this->dust->helpers[$section->identifier->key];
//build state w/ no current value
Expand Down Expand Up @@ -135,7 +135,7 @@ public function evaluateSection(Ast\Section $section, Context $ctx, Chunk $chunk
}
return $chunk;
}

public function evaluateElseBody(Ast\Section $section, Context $ctx, Chunk $chunk) {
if ($section->bodies != null && count($section->bodies) > 0) {
foreach ($section->bodies as $value) {
Expand All @@ -146,7 +146,7 @@ public function evaluateElseBody(Ast\Section $section, Context $ctx, Chunk $chun
}
return $chunk;
}

public function evaluatePartial(Ast\Partial $partial, Context $ctx, Chunk $chunk) {
$partialName = $partial->key;
if ($partialName == null) $partialName = $this->toDustString($this->normalizeResolved($ctx, $partial->inline, $chunk));
Expand Down Expand Up @@ -179,7 +179,7 @@ public function evaluatePartial(Ast\Partial $partial, Context $ctx, Chunk $chunk
//render the partial then
return $this->evaluateBody($partialBody, $ctx->pushState($state), $chunk);
}

public function evaluateSpecial(Ast\Special $spl, Context $ctx, Chunk $chunk) {
switch ($spl->key) {
case 'n':
Expand All @@ -202,7 +202,7 @@ public function evaluateSpecial(Ast\Special $spl, Context $ctx, Chunk $chunk) {
}
return $chunk;
}

public function evaluateReference(Ast\Reference $ref, Context $ctx, Chunk $chunk) {
//resolve
$resolved = $this->normalizeResolved($ctx, $ctx->resolve($ref->identifier), $chunk);
Expand All @@ -229,12 +229,12 @@ public function evaluateReference(Ast\Reference $ref, Context $ctx, Chunk $chunk
}
return $chunk;
}

public function evaluateBuffer(Ast\Buffer $buffer, Context $ctx, Chunk $chunk) {
$chunk->write($buffer->contents);
return $chunk;
}

public function evaluateParameters(array $params, Context $ctx) {
$ret = [];
foreach ($params as $value) {
Expand All @@ -251,7 +251,7 @@ public function evaluateParameters(array $params, Context $ctx) {
}
return $ret;
}

public function normalizeResolved(Context $ctx, $resolved, Chunk $chunk, Ast\Section $section = null) {
$handledSpecial = true;
while ($handledSpecial) {
Expand All @@ -274,14 +274,14 @@ public function normalizeResolved(Context $ctx, $resolved, Chunk $chunk, Ast\Sec
}
return $resolved;
}

public function isEmpty($val) {
//numeric not empty
if (is_numeric($val)) return false;
//otherwise, normal empty check
return empty($val);
}

public function exists($val) {
//object exists
if (is_object($val)) return true;
Expand All @@ -296,14 +296,14 @@ public function exists($val) {
//nulls do not exist
return !is_null($val);
}

public function toDustString($val) {
if (is_bool($val)) return $val ? 'true' : 'false';
if (is_array($val)) return implode(',', $val);
if (is_object($val) && !method_exists($val, '__toString')) return get_class($val);
return (string) $val;
}

public function handleCallback(Context $ctx, $callback, Chunk $chunk, Ast\Section $section = null) {
//reset "this" on closures
if ($callback instanceof \Closure) {
Expand Down Expand Up @@ -341,5 +341,5 @@ public function handleCallback(Context $ctx, $callback, Chunk $chunk, Ast\Sectio
//invoke
return call_user_func_array($callback, $args);
}

}
26 changes: 20 additions & 6 deletions tests/Dust/FilesystemTest.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

class FilesystemTest extends DustTestBase {
public static $dir;

public static function setUpBeforeClass() {
FilesystemTest::$dir = sys_get_temp_dir();
if (FilesystemTest::$dir[strlen(FilesystemTest::$dir) - 1] != '/') FilesystemTest::$dir .= '/';
Expand All @@ -18,8 +18,14 @@ public static function setUpBeforeClass() {
//add child template
$fileRes = file_put_contents(FilesystemTest::$dir . '/childTemplate.dust', '{>baseTemplate/}{<two}newTwo{/two}{<three}newThree{/three}');
if ($fileRes === false) throw new DustException('Unable to create template');

// Add template with custom extension
$fileRes = file_put_contents(FilesystemTest::$dir . '/simpleTemplate.tl', 'line1{~n}line2');
if ($fileRes === false) {
throw new DustException('Unable to create template');
}
}

public static function deleteTree($dir) {
foreach (scandir($dir) as $file) {
if ($file != '.' && $file != '..') {
Expand All @@ -29,23 +35,31 @@ public static function deleteTree($dir) {
}
return rmdir($dir);
}

public static function tearDownAfterClass() {
if (!FilesystemTest::deleteTree(FilesystemTest::$dir)) throw new DustException('Unable to delete dir: ' . FilesystemTest::$dir);
}

public function testSimpleBlock() {
//just run the child, it should auto-find the base
$compiled = $this->dust->compileFile(FilesystemTest::$dir . '/childTemplate');
$expected = "before\noneDefault...newTwo...newThree\nafter";
$this->assertEquals($expected, $this->dust->renderTemplate($compiled, (object)[]));
}

public function testIncludedDirectories() {
//add the dir
$this->dust->includedDirectories[] = FilesystemTest::$dir;
//now have something call the child
$this->assertTemplate("Begin - before\noneDefault...newTwo...newThree\nafter - End", 'Begin - {>childTemplate/} - End', (object)[]);
}


public function testCustomFileExtension() {
$dust = new Dust(null, null, [ 'extension' => 'tl' ]);
$dust->includedDirectories[] = FilesystemTest::$dir;
$template = $dust->compile('{>simpleTemplate/}');
$render = $dust->renderTemplate($template, (object)[]);
$this->assertEquals($render, "line1\nline2");
}

}
20 changes: 14 additions & 6 deletions tests/Dust/StandardTest.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public function testContextTypes() {
//class
$this->assertTemplate($expected, $template, new StoogesContext());
}

public function testArrayAccess() {
$this->assertTemplate('123', '{#items}{.}{/items}', (object)["items" => new \ArrayObject([1, 2, 3])]);
}

public function testStringIndex() {
$this->assertTemplate('a => b,2 => c,foo => blah', '{#items}{$idx} => {.}{@sep},{/sep}{/items}', ["items" => ["a" => 'b', 2 => 'c', "foo" => 'blah']]);
}

public function testAutoloaderOverride() {
//override
$autoloaderInvoked = false;
Expand All @@ -53,12 +53,12 @@ public function testAutoloaderOverride() {
]);
$this->assertTrue($autoloaderInvoked);
}

public function testCustomFilter() {
$this->dust->filters['stripTags'] = new StripTagsFilter();
$this->assertTemplate('Value: foo, bar', 'Value: {contents|stripTags}', (object)["contents" => '<div>foo, <br /><strong>bar</strong></div>']);
}

public function testCustomHelper() {
//from manual
$this->dust->helpers['substr'] = function (Evaluate\Chunk $chunk, Evaluate\Context $ctx, Evaluate\Bodies $bodies, Evaluate\Parameters $params) {
Expand All @@ -77,5 +77,13 @@ public function testCustomHelper() {
//test some things (kinda taken from PHP manual)
$this->assertTemplate('bcdef,bcd,abcd,abcdef,bc', '{@substr str="abcdef" begin=1 /},' . '{@substr str="abcdef" begin=1 len=3 /},' . '{@substr str="abcdef" len=4 /},' . '{@substr str="abcdef" len=8 /},' . '{@substr str="abcdef" begin=1 end=3 /}', (object)[]);
}


public function testCustomHelperNotFound() {
try {
$this->assertTemplate('NULL', '{@customHelper param=myParam/}', (object)[]);
} catch (Evaluate\EvaluateException $exc) {
$this->assertEquals('Unable to find helper: customHelper', $exc->getMessage());
}
}

}