javascriptgoogle-closure-compilergoogle-closuregoogle-closure-templates

Sending compiled objects to Closure Templates


If I call a template from JavaScript with:

namespace.template(record);

where record is an instance of:

/** @typedef {{var: string}} */

and I use the Google Closure Compiler in advanced mode, which rewrites var, then how can I receive var in the template? Is using 'var' instead of var to prevent rewriting the only way to do this?

I'm thinking that, ideally, it would be nice if I could provide types for the template's @params, just like I can for the JavaScript code, which should let the compiler know what rewritten name to use...


It looks like this doesn't happen for any value of var. It does happen though if the key is named default, because SoyToJsSrcCompiler generates code using 'default' (for this special name only, not for any other name I used so far), thus preventing Closure Compiler from renaming it, but the property is renamed in the JavaScript code, because I'm using default without quotes.


Solution

  • If your template looks something like:

    /**
     * Foo
     * @param rec
     */
    {template .Foo}
        <div>{$rec.var}</div>
    {/template}
    

    Then the SoyToJsSrcCompiler will produce code similar to:

    /**
     * @param {Object.<string, *>=} opt_data
     * @param {(null|undefined)=} opt_ignored
     * @return {string}
     * @notypecheck
     */
    namespace.Foo = function(opt_data, opt_ignored) {
      return '<div>' + soy.$$escapeHtml(opt_data.rec.var) + '</div>';
    };
    

    This generated template function is meant to be included in the compilation with your source file. Since the output property access is of the form rec.var the compiler should rename it correctly.