blueimp/JavaScript-Templates

How to use two independent instances of the Templates function

Closed this issue · 11 comments

Original title: "Remove from the global window ?"

Hey Sebastian,

Any chance that you can remove tmpl from the global window and add to to its own window to avoid conflicts ?

Any reason not to do this ?

Thanks

If you load the script via a module loader like Require.js or any other AMD compatible loader, nothing will be added to the global window object.

By the way, what do you mean by "add to its own window"?

thanks for the response

i mean so its within its own scope such like

(function(tmpl, $, undefined) {

//....existing code

} (window.tmpl = window.tmpl || {}, jQuery));

So that it doesnt cause conflicts ?

Sorry, but your code snippet above doesn't make any sense to me (and the tmpl function doesn't require jQuery).

Like I said, if you make use of an AMD compatible Loader, the tmpl function will be available in your require calls and not added to the window object.

Otherwise, the function has to be made available somewhere.
Since the tmpl function doesn't have any dependencies, the global JavaScript namespace is the only way it can be made available without making any further assumptions about available libraries (or alternative loaders).

Maybe if you tell me which conflicts you encounter, I might give you advice on how to avoid them.
If another library you use makes use of a global tmpl function, you can simply add the following script after including the tmpl.js script:

<script>this.someOtherName=window.tmpl;</script>

thanks for the response :)

basically I was experiencing conflicts with the o data object argument. i.e. a plugin was using your tmpl and had defined the o as the data object argument and I was also using it but with a custom data object tm instead.

Lead to a conflict error - so thats why I was wondering if I could remove it from the global object. Not sure if you can recommend how to avoid this outside of only using 1 o data object across everything or changing it within plugins ?

OK, what you wanna do is run two instances of the same plugin.
Unfortunately, this is not supported with the current version of the JavaScript Templates function.
However, since the code is rather small, you could just copy the code and replace "tmpl" with another name.

Is it possible to just implement something like

tmpl.arg = tmpl.option.arg || "o";

where the tmpl option can be defined and if it's not then it simply reverts to the "o"

This would only make sense if two instances of the JavaScript Templates function could be used.
However, due to the closure references used to optimize the code in size, this is not possible without copying the whole constructor function.
Well, you can just do that, as the code is short:

var tmpl2 = function (str, data) {
    var f = !/[^\w\-\.:]/.test(str) ? tmpl2.cache[str] = tmpl2.cache[str] ||
            tmpl2(tmpl2.load(str)) :
                new Function(
                    tmpl2.arg + ',tmpl',
                    "var _e=tmpl2.encode" + tmpl2.helper + ",_s='" +
                        str.replace(tmpl2.regexp, tmpl2.func) +
                        "';return _s;"
                );
    return data ? f(data, tmpl2) : function (data) {
        return f(data, tmpl2);
    };
};
$.extend(tmpl2, tmpl);

Now you can set the options for tmpl2 without affecting the original tmpl function.

i guess the other way to do it is to detect it when the template renders ?

that is - if I define the argument like

{%=aws.id%}

but then another plugin decides to use

{%=o.id%}

It could test when rendering the template (i.e. first arg it comes across) and determine whether an arg has been defined and is being used (i.e. aws) otherwise it uses (o) ? Would just be great to allow the tmpl to avoid conflicts where plugins use the default and others templates render using a custom argument ?

Yeah, you could do that, e.g. by adding the following at the top of your template:

{% var aws = typeof o !== 'undefined' ? o : aws; %}

Then you could always use aws as object name:

<h3>{%=aws.title%}</h3>

yeah that will work! thanks - would be great if you could incorporate any of these ideas into the plugin :) that way - if a custom arg is defined templates which use the o default argument wont error

thanks Sebastian !