fbrctr / fabricator

A tool for building website UI toolkits and style guides
http://fbrctr.github.io/
MIT License
1.11k stars 124 forks source link

Handlebars helpers executed twice in material views. #246

Closed DTwigs closed 8 years ago

DTwigs commented 8 years ago

I created a debug assemble handlebars helper in my gulpfile.js:

// assemble
gulp.task('assemble', function (done) {
  assemble({
    helpers: {
      debug: function(o) {
        console.log("Debugger:");
        console.log(o);
      }
    },
    logErrors: config.dev
  });
  done();
});

When I run npm start I see that it runs this debug helper twice for every time it appears ({{#debug this}}{{/debug}}) in a material view such as materials/atoms/button.html.

This is causing some issues with another helper that I wrote to have javascript snippets in these materials views get appended to the bottom of the default.html layout.

That helper looks like this:

scripts: function (name, options) {
        this.toolkit.scripts = this.toolkit.scripts || {};
        var scripts = this.toolkit.scripts;
        scripts[name] = scripts[name] || "";
        scripts[name] = scripts[name].concat(options.fn(this));
        return null;
},

So when I add the following snippet to the bottom of my materials/atoms/button.html it gets executed twice which ends up appending two of these script tags to the global assemble variable:

{{#scripts "js_lower"}}
  <script type="application/javascript">
    console.log("button load");
    $('.js-button-toggle').myButton();
  </script>
{{/scripts}}

And at the bottom of default.html I have:

<!-- toolkit scripts -->
<script src="{{baseurl}}/assets/toolkit/scripts/toolkit.js"></script>
<!-- /toolkit scripts -->
{{{toolkit.scripts.js_lower}}}

Since two script tags are saved into toolkit.scripts.js_lower, this ends up rendering two of the same script tag causing the JS to execute twice.

How can I prevent these view helper methods from being executed twice?

DTwigs commented 8 years ago

So I found the culprit, it's the f-item-content.html

{{#if notes}}<div class="f-item-notes" data-f-toggle="notes">
    {{{notes}}}
</div>{{/if}}
<div class="f-item-preview">
    {{{material @key @root}}}
</div>
<div class="f-item-code f-item-hidden" data-f-toggle="code">
    <pre><code class="language-markup">{{material @key @root}}</code></pre>
</div>

The two place where it calls {{material @key @root}} executes whatever code is in that material file twice.

Not sure what to do about that.

DTwigs commented 8 years ago

After reviewing some of your other issues I see that this is much more of a philosophy issue as to how and when ui elements are initialized.

I have decided to take the javascript out of each view and have them automatically initialized in my toolkit.js.

This makes this double rendering a non-issue.

LukeAskew commented 8 years ago

Glad you figured this out. Sorry I couldn't help!