shannonmoeller / handlebars-layouts

Handlebars helpers which implement layout blocks similar to Jinja, Nunjucks (Swig), Pug (Jade), and Twig.
http://npm.im/handlebars-layouts
MIT License
361 stars 29 forks source link

If content blocks no longer works #22

Closed mynameisstephen closed 9 years ago

mynameisstephen commented 9 years ago
{{#if @content.right }}

The above block always evaluates to false since the content helpers are being evaluated after the partial.

Changing the line

getStack(context).push(fn);

in the extend helper to

fn(context);

fixes the issue, but this is most likely not the correct solution.

shannonmoeller commented 9 years ago

Can you provide a little more context? Not sure what you mean by "always evaluates to false since the content helpers are being evaluated after the partial". Under what circumstances does this happen?

mynameisstephen commented 9 years ago

Not sure how I can be any more clear, if you actually try the example above/do a bit of digging you'll realise that @content.whatever does not work at all in any circumstance.

This was most likely due to this commit - https://github.com/shannonmoeller/handlebars-layouts/commit/86328430507912eaad85991282193a1843c01588 - however not having used this library previously, I can't be sure.

shannonmoeller commented 9 years ago

It's working as expected in the test cases.

Layout: https://github.com/shannonmoeller/handlebars-layouts/blob/master/test/fixtures/partials/layout.hbs#L12

Page that doesn't supply a header or footer: https://github.com/shannonmoeller/handlebars-layouts/blob/master/test/fixtures/templates/hash.html#L2

Expected output without a header or footer wrapper: https://github.com/shannonmoeller/handlebars-layouts/blob/master/test/expected/templates/hash.html

Would you be willing to put together a failing example? Perhaps as a gist.

mynameisstephen commented 9 years ago

Okay tracked it down. So this works

        <script type="text/x-handlebars-template" id="template">
            {{#extend 'layout'}}
                {{#content 'helper'}}
                    This is a test string
                {{/content}}

                {{#content "header"}}
                    <h1>Goodnight Moon</h1>
                {{/content}}
            {{/extend}}
        </script>

        <script type="text/x-handlebars-template" id="partial-layout">
            <div class="c-input-helper">{{{block 'helper'}}}</div>

            {{#if @content.header}}
                <div class="site-hd" role="banner">
                    {{#block "header"}}
                        <h1>{{title}}</h1>
                    {{/block}}
                </div>
            {{/if}}
        </script>

but if you remove the first line of the partial-layout <div class="c-input-helper">{{{block 'helper'}}}</div> it breaks. Looks like a block has to be evaluated before the content object gets populated. I looked through all your tests and it looks like there is at least one block before an if block.

You should be able to reproduce it by removing the head block in your layout.hbs file and then running your tests tho I haven't tried this.

shannonmoeller commented 9 years ago

I hope to tackle this over the upcoming weekend. Sorry for the delay and thanks for the test case.

shannonmoeller commented 9 years ago

This was a tricker issue to debug and resolve than I anticipated. Unfortunately the fix wasn't as simple as your initial recommendation due to the complicated relationships of nested layouts. I ended up having to replace the @content variable with a new subexpression use case for the content helper.

Before: {{#if @content.foo}}    {{{block "foo"}}} {{/if}}
After:  {{#if (content "foo")}} {{{block "foo"}}} {{/if}}

As this was a breaking change, it has been released as 3.0.0.

https://github.com/shannonmoeller/handlebars-layouts/blob/master/CHANGELOG.md#300