Skip to content

Commit

Permalink
Add support for else if
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed May 2, 2021
1 parent 51b4812 commit c11fcc1
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 7 deletions.
7 changes: 4 additions & 3 deletions src/main/php/com/handlebarsjs/BlockNode.class.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php namespace com\handlebarsjs;

use com\github\mustache\Node;
use util\Objects;

/**
* A block starts with {{#sec}} (or {{^sec}} for inverted blocks)
Expand Down Expand Up @@ -81,8 +82,8 @@ public function toString() {
nameof($this),
$this->name,
($this->options ? ' '.implode(' ', $this->options) : ''),
\xp::stringOf($this->fn, ' '),
\xp::stringOf($this->inverse, ' ')
Objects::stringOf($this->fn, ' '),
Objects::stringOf($this->inverse, ' ')
);
}

Expand Down Expand Up @@ -133,7 +134,7 @@ public function equals($cmp) {
$this->name === $cmp->name &&
$this->start === $cmp->start &&
$this->end === $cmp->end &&
\util\Objects::equal($this->options, $cmp->options) &&
Objects::equal($this->options, $cmp->options) &&
$this->fn->equals($cmp->fn) &&
$this->inverse->equals($cmp->inverse)
);
Expand Down
18 changes: 16 additions & 2 deletions src/main/php/com/handlebarsjs/HandlebarsParser.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,23 @@ protected function initialize() {
$state->target->add(new IteratorNode(true));
return;
} else if ('else' === $parsed[0] && $state->parents) {
$context= $state->parents[sizeof($state->parents) - 1];
$context= &$state->parents[sizeof($state->parents) - 1];
if ($context instanceof BlockNode) {
$state->target= $context->inverse();

// `else if` vs. `else`
if (isset($parsed[1]) && 'if' === (string)$parsed[1]) {
$context= $context->inverse()->add(new IfBlockHelper(
array_slice($parsed, 2),
null,
null,
$state->start,
$state->end
));
$state->target= $context->fn();
} else {
$state->target= $context->inverse();
}

return;
}
// Fall through, "else" has no special meaning here.
Expand Down
3 changes: 1 addition & 2 deletions src/main/php/com/handlebarsjs/IfBlockHelper.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ public function __construct($options= [], NodeList $fn= null, NodeList $inverse=
* @param io.streams.OutputStream $out
*/
public function write($context, $out) {
$f= $this->options[0];
$target= $f($this, $context, []);
$target= $this->options[0]($this, $context, []);

if ($target instanceof \Generator ? $target->valid() : $context->isTruthy($target)) {
$this->fn->write($context, $out);
Expand Down
7 changes: 7 additions & 0 deletions src/test/php/com/handlebarsjs/unittest/IfHelperTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public function shows_for_non_empty_array() {
]));
}

#[Test, Values(map: ['one' => '1', 'two' => '2', 'three' => '3', 'other' => '3'])]
public function chained_elses($key, $expected) {
Assert::equals($expected, $this->evaluate('{{#if one}}1{{else if two}}2{{else}}3{{/if}}', [
$key => true
]));
}

#[Test, Values(['else', '^'])]
public function else_invoked_for_non_truthy($else) {
Assert::equals('Default', $this->evaluate('{{#if var}}-{{var}}-{{'.$else.'}}Default{{/if}}', [
Expand Down

0 comments on commit c11fcc1

Please sign in to comment.