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
610 stars 76 forks source link

fix #305: do render the value "0" inside conditional #306

Open Krinkle opened 5 years ago

Krinkle commented 5 years ago

Fixes issue #305.

Krinkle commented 5 years ago

Build failure is unrelated, see https://github.com/zordius/lightncandy/issues/307.

zordius commented 5 years ago

Hello, This pull request breaks a handlebars.js spec test, which was definded in https://github.com/wycats/handlebars.js/pull/731 . Refer to these jsfiddle:

handlebars.js 4.1.1: https://jsfiddle.net/0rec6d2f/ mustache.js 3.0.1: http://jsfiddle.net/4nLockuy/

Here are some mustache <=> handlebars difference, you can refer to these document:

About block: https://zordius.github.io/HandlebarsCookbook/0008-block.html#BlockforFalse (search for 'Only mustache.js will think 0 as false')

About #if: https://zordius.github.io/HandlebarsCookbook/0016-if.html (search for '0 means false')

If you like to follow mustache, the FLAG_MUSTACHE is good, you may also check the document https://github.com/zordius/lightncandy , search 'Mustache Compatibility' for more detail.

If you like to follow handlebars.js, you should use FLAG_HANDLEBARS or check the document https://github.com/zordius/lightncandy , search 'Handlebars Compatibility' for more detail.

Krinkle commented 5 years ago

@zordius This is about the string '0', not the number 0.

The if logic is already working correctly in lightncandy. When passing data [ 'foo' => '0' ] to {{#foo}}Yes{{/foo}} the word Yes renders correctly in lightncandy.

The problem is in the internal lightncandy logic for getting a value from a path, in ::v().

The example template:

{{#foo}}<b>{{foo}}</b>{{/foo}}

The example data:

'data' => [
  'foo' => '0',
],

When ::v() is called by the processing of {{#foo}}, the following happens:

Then, for <b>{{foo}}</b> we also use ::v(). There we have the bug.

The value is never found, and never printed. We get <b></b>.

I might need help for a better fix. Do you have a recommendation?

zordius commented 5 years ago

Well, please refer to https://github.com/zordius/lightncandy/issues/305 , we compared handlebars.js and mustache.js there, again.

Now the handlebars.js behavior is strange but lightncandy is aligned with it. Here are some points:

  1. A better fix should works on block/section context handling.
  2. An issue/bug should be also created at handlebars.js repo to address this issue.
  3. Based on 2, if handlebars.js will be fixed for this, then we can fix lightncandy in better way.
  4. Based on 2, if handlebars.js will not change for this, then the fix will be harder because we can only fix this for mustache flag but not handlebars flag.