Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A working example using AMD and requirejs. #103

Open
josemadriz opened this issue Apr 1, 2014 · 7 comments
Open

A working example using AMD and requirejs. #103

josemadriz opened this issue Apr 1, 2014 · 7 comments

Comments

@josemadriz
Copy link

I have a project set up using bower handlebars shim library, which contains the runtime (compiler free) library and the library using amd.
I' using contrib-requirejs to compile my setup.
{
amd: true,
wrapped: false
}
handlebars-lang/handlebars.js#547 (comment)
The error in with .merge method no error in that comment is still happening.
This repo:
https://github.com/components/handlebars.js
is using the latest version of handlebars.

Shouldn't this library using the AMD config compile templates to be preferably used by handlebars.runtime.amd?
when I hardcode ['runtime.amd'] in the compiled template the library returns all handlebars methods inside a 'default' object therefore the methods aren't found in Handlebars properly.

Not sure if I should add more handlebars compiler variables to make this happen.
If this is the case there should be a sample in the readme.

@nathanjd
Copy link

nathanjd commented Apr 9, 2014

I ran into this issue as well. I fixed it with a small code change and upgrade to handlebars 2. I won't have the time to make a proper pull request until next week but you are welcome to check it out.

https://github.com/nathanjd/grunt-contrib-handlebars

@josemadriz
Copy link
Author

Thanks @nathanjd :)
I'll try that alpha then..
And check what has changed form current version.

@stephanebachelier
Copy link
Contributor

see #109. Need to wait before Handlebars 2 final release as stated by @sindresorhus.
It is the main reason why I complete work done by @nathanjd + support for partials.

@jaridmargolin
Copy link

AMD output currently does not work with handlebars 1.3.0. I do not see why this needs to wait until the release of handlebars ver 2.0.0. It would be great to see a patch applied immediately.

Grunt Options:

options: {
  amd: ['handlebars/handlebars.runtime'],
  namespace: false
}

Output:

define(['handlebars/handlebars.runtime'], function(Handlebars) {

return Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
  this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};



  return "<h1>Hello World</h1>";
  })

});

The problem with the output is that the handlebars AMD implementations expose an object:

Object {default: HandlebarsEnvironment}

I believe it could be immediately fixed with the following commit (minus the package.json update):

stephanebachelier@560a89d


@stephanebachelier
Copy link
Contributor

@jaridmargolin you can use the approach given by @ixtli in handlebars.js/796
See my comment.

IMHO it is simple as you only need to give require.js a handlebars object that export the Handlebars.default.

I can also create a PR with my change that you referenced.

@jaridmargolin
Copy link

@stephanebachelier I am currently using the approach outlined in 796. However, it would be preferred to not need an additional shim file...

@ixtli
Copy link

ixtli commented Aug 12, 2014

Ok so sorry for taking so long for this, but I'd like to explain how I work around this issue. It's a hack to be sure but I'm 99% sure it's safe and works on everything IE7+. First off I should say that I precompile my templates using the "simple" mode offered by the current version of handlebars (-s option). Doing so turns <div>This is a {{test}}</div> into

{"compiler":[5,">= 2.0.0"],"main":function(depth0,helpers,partials,data) {
  var helper, functionType="function", escapeExpression=this.escapeExpression;
  return "<div>This is a "
    + escapeExpression(((helper = helpers.test || (depth0 && depth0.test)),(typeof helper === functionType ? helper.call(depth0, {"name":"test","hash":{},"data":data}) : helper)))
    + "</div>\n";
},"useData":true}

I get a string representing this object via AJAX, so to execute it I including the AMD build as outlined in the thread @stephanebachelier mentioned:

var Handlebars = require('handlebars/handlebars.runtime')['default'];

Then I execute the raw string by doing the following:

function executeScript(raw)
{
    // The following is equivalent to
    // var script = $('<script>', {'type': 'text/javascript'})[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';

    try {
        // Fails on IE7
        script.appendChild(document.createTextNode(raw));
    } catch (e) {
        // IE is stupid
        script.text = raw;
    }

    // This is basically how jQuery implements $.noConflict();
    var old = window['NZomIzI2O'];

    // If you'd like you can trap errors with try{}catch(){}; here.
    _head.insertBefore('window["NZomIzI2O"]=' + script, _head.firstChild);
    _head.removeChild(script);

    // Save our output to return it
    var output = window['NZomIzI2O'];

    // Don't destroy global namespace
    window['NZomIzI2O'] = old;

    return output;
}

So whenever I want to turn a precompiled template in string form into a template I do this:

var template = Handlebars.template(executeScript(rawTemplate));

I believe this approach keeps the application from mutating the global namespace in any reasonable way, and while I do realize that it assumes the presence of a window object (clearly problematic for certain runtimes) this is my use case :) I also realize this is a hack, but I need to load arbitrary sets of templates in an environment without access to async loading features of requirejs and I'd rather not put eval() in my code. Also it needs to get done now. I look forward to unhacking, to a degree when grunt-contrib-handlebars gets update so I'm happy letting this serve as documentation of a legitimate use-case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants