janl / mustache.js

Minimal templating with {{mustaches}} in JavaScript
https://mustache.github.io
MIT License
16.43k stars 2.39k forks source link

Registering global helpers #277

Open ifthikhan opened 11 years ago

ifthikhan commented 11 years ago

Is it possible to register helper functions in a global manner that the calls to render uses the helper when referenced.

I would like to i18n my templates and as far as I can see the helper function needs to be sent with each call to render.

3n commented 11 years ago

+1

jpbecotte-edu commented 11 years ago

You can register your globals by overloading the Mustache.render method with requirejs, as follow:

require(['mustache', 'path/to/your/i18n_file'], function (Mustache, i18n) {
    var _render = Mustache.render;
    Mustache.render = function (template, view, partials) {
        view['lang'] = i18n;
        return _render (template, view, partials);
    };
    return Mustache;
});

Your i18_file.js will contain:

define ({
     'colors_red': 'red'
     ...
});

And you can access the i18n tokens this way:

The color of your product is : {{lang.color_red}}
jpbecotte-edu commented 11 years ago

If you don't want to use requirejs, then you still can overload Mustache.render this way:

var lang = {
    'colors_red': 'red' 
};

var otherGlobals = {
    'eleven': 11
};

var Mustache = (function (Mustache) {
    var _render = Mustache.render;

    Mustache.render = function (template, view, partials) {
        view['lang'] = lang;
        view['numbers'] = otherGlobals;
        return _render (template, view, partials);
    };

    return Mustache;
}(Mustache));
igorescobar commented 9 years ago

is it still the better way to do this ~2 years later?

nicolaskern commented 9 years ago

What about in 2015? ;)

dasilvacontin commented 9 years ago

I'd go more with something of the likes of @bobthecow's example: https://github.com/bobthecow/mustache.php/commit/f77cf3729de0e46d6187da2353a4ab438657b6fe.

Someone could write it and publish it as a plugin.

nicolaskern commented 9 years ago

Seems like it's for a PHP compiling process, isn't it possible to add a helper, or a global filter/function/other, without having to compile server-side in PHP ?

dasilvacontin commented 9 years ago

Sorry, I should have explained myself better. I meant that I prefer @bobthecow's syntax where text is surrounded by a lambda, which performs the translation.

It's very easy to hack that functionality into mustache.js. More or less along the lines of:

function i18nLambda (text, render) {
  text = dict[text] || text
  return render(text)
}

var Context = mustache.Context
Context.prototype._lookup = Context.prototype.lookup
Context.prototype.lookup = function i18nLookup (name) {
  return (name === 'i18n' ? i18nLambda : this._lookup(name))
}

You could then:

{{#i18n}}Hello.{{/i18n}} {{#i18n}}My name is {{ name }}.{{/i18n}}
joshlopes commented 9 years ago

Thanks @dasilvacontin this trick worked perfectly!

dasilvacontin commented 9 years ago

No worries @joshlopes, glad it was useful!

I published it as an npm module: https://github.com/dasilvacontin/mustache-i18n