handlebars-php icon indicating copy to clipboard operation
handlebars-php copied to clipboard

Custom helper not working as expected

Open abhishek-ejam opened this issue 3 years ago • 1 comments

I've created a custom helper that evaulates a conditional expression (similar to if with conditional expression) as below:

$this->handlebars->addHelper("compare",
    function($template, $context, $args, $source){
        
        list($operandSpecName, $operator, $operand2) = explode(" ",$args);

        $operand1 = $context->get($operandSpecName);
        $operator = str_replace("'", "", $operator);
        $operand2 = str_replace("'", "", $operand2);

        switch($operator){
            case '==':
                return ($operand1 == $operand2) ? true: false;
            case '===':
                return ($operand1 === $operand2) ? true: false;
            case '!=':
                return ($operand1 != $operand2) ? true: false;
            case '!==':
                return ($operand1 !== $operand2) ? true: false;
            default:
                return false;
        }
    }
);

Here's my template:

$template = `"{{#compare comics '==' 'Marvel'}}{{#compare movie '==' 'Avenger'}}8{{\/compare}}{{\/compare}}{{#compare comics '==' 'DC'}}{{#compare movie '==' 'Batman'}}9{{\/compare}}{{\/compare}}"

And here's the data I've passed:

$data = [
    "comics" => "Marvel",
    "movie" => "Avenger"
];

I've called the render function as below:

$this->handlebars->render($template, $data);

I expect the result of expression as 8 since only the first two expression of compare helper are evaluated as being true. However, I get the output as 1189. I noticed that the helper returns 1 each time it evaluates a true condition and it also outputs result even if the codition does not evaluates true. I was wondering if anyone can help me to correct the logic of my custom helper? Thanks!

abhishek-ejam avatar Jul 20 '22 02:07 abhishek-ejam

I also tried to implement custom helpers with this library and ran into a lot of issues. Because of this, I've been building a modern PHP Handlebars project here: https://github.com/devtheorem/php-handlebars.

Your template and custom helper can be successfully implemented with it as follows:

<?php

use DevTheorem\Handlebars\{Handlebars, HelperOptions, Options};

require 'vendor/autoload.php';

$compareHelper = function (mixed $a, string $operator, mixed $b, HelperOptions $options) {
    $result = match ($operator) {
        '==' => $a == $b,
        '===' => $a === $b,
        '!=' => $a != $b,
        '!==' => $a !== $b,
        default => false,
    };

    return $result ? $options->fn() : '';
};

$template = "{{#compare comics '==' 'Marvel'}}{{#compare movie '==' 'Avenger'}}8{{/compare}}{{/compare}}
{{#compare comics '==' 'DC'}}{{#compare movie '==' 'Batman'}}9{{/compare}}{{/compare}}";

$templateFn = Handlebars::compile($template, new Options(
    helpers: ['compare' => $compareHelper],
));

echo $templateFn([
    "comics" => "Marvel",
    "movie" => "Avenger"
]);
// outputs: 8

theodorejb avatar Mar 20 '25 23:03 theodorejb