zordius / lightncandy

An extremely fast PHP implementation of handlebars ( http://handlebarsjs.com/ ) and mustache ( http://mustache.github.io/ ),
https://zordius.github.io/HandlebarsCookbook/
MIT License
608 stars 76 forks source link

A Fatal Error occurs when including curly braces in a string for a parameter of a partial. #316

Open friedlink opened 4 years ago

friedlink commented 4 years ago

The PHP Code:

require('./vendor/autoload.php');
use LightnCandy\LightnCandy;

// Define the template string.
$templateString = '{{> MyStrongPartial text="To reference a variable in Handlebars use the syntax: {{varName}}."}}';

// Define the partial template string.
$partialTemplateString = '<strong>{{text}}</strong>';

// Define helpers...
$helpers = [];

// Define the LightnCandy compile options.
$compileOptions = [
    'flags' => LightnCandy\LightnCandy::FLAG_HANDLEBARSJS_FULL | LightnCandy\LightnCandy::FLAG_ERROR_SKIPPARTIAL | LightnCandy\LightnCandy::FLAG_EXTHELPER | LightnCandy\LightnCandy::FLAG_ERROR_EXCEPTION,
    'helperresolver' => (
        function ($context, $name) use ($helpers): bool {
            return array_key_exists($name, $helpers);
        }
    )
];

// Create the template using LightnCandy.
$template = eval(LightnCandy\LightnCandy::compile($templateString, $compileOptions));

// Define the LightnCandy render options.
$renderOptions = [
    'partials' => [
        'MyStrongPartial' => eval('use \LightnCandy\Runtime as LR; use \LightnCandy\SafeString as SafeString; return ' . LightnCandy\LightnCandy::compilePartial($partialTemplateString, $compileOptions) . ';')
    ],
    'helpers' => $helpers
];

// Create a context.
$context = new stdClass();
$context->varName = 'variableName';

?>
<!doctype html>
<html lang="en">

    <head>
        <meta charset="utf-8">
        <title>Partial Block Test</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <style>
            #php, #js {
                border: 1px solid black;
                margin: 20px;
                padding: 20px;
            }
            #php {
                background: #ffe;
            }
            #js {
                background: #eff;
            }
        </style>
    </head>

    <body>

        <div id="php">
            <h1>Rendered by PHP</h1>
            <div id="render-php"><?= $template($context, $renderOptions); ?></div>
        </div>

        <div id="js">
            <h1>Rendered by JS</h1>
            <div id="render-js"></div>
        </div>

        <script id="context" type="application/json"><?= json_encode($context) ?></script>

        <script id="parent-template" type="text/x-handlebars-template"><?= $templateString ?></script>
        <script id="partial-template" type="text/x-handlebars-template"><?= $partialTemplateString ?></script>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.0/handlebars.min.js" integrity="sha256-dlwklXLDib5XGMYI+HdNEXczJXTsFtq+qIrSdXoCv6o=" crossorigin="anonymous"></script>

        <script>

            // Make the partial template available as a partial.
            Handlebars.registerPartial("MyStrongPartial", Handlebars.compile(document.getElementById("partial-template").innerHTML));

            // Compile the template and render with the supplied context.
            document.getElementById("render-js").innerHTML = Handlebars.compile(document.getElementById("parent-template").innerHTML)(JSON.parse(document.getElementById("context").innerHTML));

        </script>

    </body>

</html>

The Issue:

When including curly braces in a string when setting the parameter of a partial, a fatal error occurs:

stderr: PHP Fatal error:  Uncaught Exception: Error in ' MyStrongPartial text="To reference a variable in Handlebars use the syntax: {{varName': expect '"' but the token ended!! in /vendor/zordius/lightncandy/src/LightnCandy.php:110

Handlebars renders the string "To reference a variable in Handlebars use the syntax: {{varName}}."

jasonh-brimar commented 4 years ago

I can confirm that this issue is still present in LightnCandy 1.2.5. Here is the current stack trace

PHP Fatal error:  Uncaught Exception: Error in 'echo message="This is what a Handlebars expression looks like {{var': expect '"' but the token ended!! in vendor/zordius/lightncandy/src/LightnCandy.php:108
Stack trace:
#0 vendor/zordius/lightncandy/src/LightnCandy.php(50): LightnCandy\\LightnCandy::handleError()
#1 test.php(34): LightnCandy\\LightnCandy::compile()
#2 {main}
  thrown in vendor/zordius/lightncandy/src/LightnCandy.php on line 108