Closure Tools

Using Closure Templates in JavaScript

Table of Contents

  1. Compilation
  2. Usage with the Closure Library
  3. Code Styles
  4. Utilities
  5. Rendering
  6. Globals
  7. Code Examples

Compilation

The template compiler's JavaScript Source backend supports JavaScript usage. You have two options for invoking the template compiler to generate JavaScript source: you can run the executable jar (which you can extract from closure-templates-for-javascript-latest.zip on the Closure Templates Downloads page) or you can call the compiler from Java. This section discusses how to use both options.

How to run the executable jar

Use this command syntax to run SoyToJsSrcCompiler:

$ java -jar SoyToJsSrcCompiler.jar [<flag1> <flag2> ...] --outputPathFormat <formatString> <soyFile1> <soyFile2> ...

In the command line arguments to the SoyToJsSrcCompiler, you must include the paths to all of the Soy files that you want compiled together as one bundle. The executable also accepts a number of command-line flags, some of which are required.

Note: To see all of the available command-line flags, run java -jar SoyToJsSrcCompiler.jar.

The table below lists the most important command-line flags for SoyToJsSrcCompiler:

Flag Usage
--inputPrefix

The path prefix that should be prepended to each input file path that is listed on the command line. This is a literal string prefix, so be sure to include a trailing slash if necessary.

--srcs

[Required] The list of source Soy files.

--allowExternalCalls

Whether to allow external calls. New projects should set this to false, and existing projects should remove existing external calls and then set this to false. External calls are calls to templates that aren't defined in the same bundle of Soy files being compiled together. Their existence prevents the Soy compiler from being able to accurately analyze your code. Currently defaults to true for backward compatibility.

--isUsingIjData

Not needed if you compile all your Soy files in one bundle (the recommended practice). If you need to compile your template files in multiple bundles for some reason, and you use injected data, then you should set this flag to true.

--locales

[Required for generating localized JavaScript] The list of locales for which to generate localized JavaScript. The compiler generates one output JavaScript file for each combination of input Soy file and locale.

--messageFilePathFormat

[Required for generating localized JavaScript] A format string that specifies how to build the path to each message file. The format string can include literal characters as well as the placeholders {INPUT_PREFIX}, {LOCALE}, and {LOCALE_LOWER_CASE}.

Note: {LOCALE_LOWER_CASE} turns dashes into underscores, e.g. pt-BR becomes pt_br.

--outputPathFormat

[Required] A format string that specifies how to build the path to each output file. The format string can include literal characters as well as the placeholders {INPUT_PREFIX}, {INPUT_DIRECTORY}, {INPUT_FILE_NAME}, {INPUT_FILE_NAME_NO_EXT}, {LOCALE}, {LOCALE_LOWER_CASE}.

If you are not generating localized JavaScript, then the template compiler outputs one JavaScipt file (encoded in UTF-8) for each input Soy file. If you are generating localized JavaScript, then the compiler outputs one JavaScript file for each combination of input Soy file and locale.

--shouldGenerateJsdoc

Use this option to generate JSDoc on each template function, with type info for the Closure Compiler. Note the generated JSDoc does not have any description text, only types for the benefit of the Closure Compiler.

--shouldProvideRequireSoyNamespaces Use this option to enable usage with Closure Library. If you set this flag, each generated JavaScript file contains:
  • one goog.provide statement for the corresponding Soy file's namespace
  • goog.require statements for the namespaces of the called templates.

For more information, see the section Usage with the Closure Library in this chapter.

--shouldProvideRequireJsFunctions Use this option to enable usage with Closure Library. If you set this flag, each generated JS file contains:
  • goog.provide statements for the full names of each of its template JS functions
  • goog.require statements for the full names of each of the called templates.

For more information, see the section Usage with the Closure Library in this chapter.

--shouldGenerateGoogMsgDefs

Set this flag if you want goog.getMsg definitions to be generated for all msg blocks. For more information, see the section on Letting Closure Compiler Handle Translation in the Translation chapter.

--bidiGlobalDir

[Required if and only if generating goog.getMsg definitions] For more information, see the section on Letting Closure Compiler Handle Translation in the Translation chapter.

--compileTimeGlobalsFile

The path of the file that contains the mappings for global names to be bound at compile time. Please see the Globals section in this chapter for more information.

--cssHandlingScheme

See the section on the css command in Commands.

--pluginModules

See the section on function or print directive plugins in Plugins.

--messagePluginModule

See the section on message plugins in Plugins.


Here's an example of how the compiler might be invoked from the command line:

java -jar SoyToJsSrcCompiler.jar \
           --locales en,xx-YY,xx-ZZ \
           --compileTimeGlobalsFile 'features-usage_globals.txt' \
           --outputPathFormat '{INPUT_FILE_NAME_NO_EXT}_generated_{LOCALE}.js' \
           --messageFilePathFormat 'examples_translated_{LOCALE}.xlf' \
           --srcs simple.soy,features.soy

This example generates 6 total JavaScript files in your directory — one for each combination of input Soy file (in this example simple.soy, features.soy) and locale (en, xx-YY, xx-ZZ).

How to call the compiler from Java

You can invoke the compiler directly from Java code as an alternative to running the executable jar. Follow these steps to use this approach:

  1. Download closure-templates-for-java-latest.zip from the Closure Templates Downloads page. Extract Soy.jar and add it as a library to your Java application.
  2. Create a SoyFileSet object (package com.google.template.soy) from your Soy file inputs. You must provide each input as a File, resource URL, CharSequence, or InputSupplier<? extends Reader>.

  3. Call SoyFileSet.compileToJsSrc() to obtain the contents of the generated JavaScript files. You must also create the required parameters for these methods. See the Javadoc for details.

Usage with the Closure Library

By default your usage of Closure Templates is independent of the Closure Library. However, if you want the template compiler to generate JavaScript code that is compatible with the Closure Library, simply use the option --shouldProvideRequireSoyNamespaces to generate the following in each JavaScript file:

  • a single goog.provide statement for the corresponding Soy file's namespace.
  • goog.require statements for the namespaces of the called templates.

Note: If you want to use this option, make sure that you use a unique namespace in each Soy file. The namespace must be unique across all other Soy files as well as hand-written JavaScript files. This constraint exists because the Closure Library does not allow two different JavaScript files to call goog.provide with exactly the same string.

To learn more about the Closure Library, goog.provide, and goog.require, see Finding Your Way around the Closure Library.

Code Styles

The Closure Templates compiler supports two code generation styles, but most users should not worry about this and just let the compiler use the default concat style.

If your project needs to support the IE6 browser (much less than 1% market share) for some reason, then you may want to read on. This section first gives recommendations for the code generation style that you should choose for your application, then shows the generated code in both styles for the same example template. Note that performance discussions below only pertain to IE6.

Closure Templates support two code generation styles for JavaScript:

  • In IE6, the concat style is recommended only for individual pages or for small JS applications. This style generates the simplest and shortest code: the HTML output from various template elements is simply combined using JS string concatenation. The generated code is slow in IE6, and the inefficiencies are compounded for a large JavaScript application with many objects.

  • In IE6, the stringbuilder style is recommended for large JavaScript applications. This style generates code that collects HTML output into a soy.StringBuilder object. The generated template function has a second argument opt_sb, which allows you to pass in an existing soy.StringBuilder object for collecting output. If you provide opt_sb, then the template function has no return value. If you don't provide opt_sb, then the template function will revert back to the usual behavior of returning the HTML output as a string. Calls between templates always use the opt_sb argument for efficiency. The stringbuilder style generates slightly larger code than the concat style, but is much faster in IE6.

Example template:
/**
 * Says hello to a person.
 * @param name The name of the person to say hello to.
 */
{template .helloName}
  Hello {$name}!
{/template}
Generated code (concat style):
examples.features.helloName = function(opt_data) {
  return 'Hello ' + soy.$$escapeHtml(opt_data.name) + '!';
};
Generated code (stringbuilder style):
examples.features.helloName = function(opt_data, opt_sb) {
  var output = opt_sb || new soy.StringBuilder();
  output.append('Hello ', soy.$$escapeHtml(opt_data.name), '!');
  if (!opt_sb) return output.toString();
};

Utilities

JavaScript code that's generated by the template compiler depends on a number of utilities. Include one of these two utility files, depending on whether you're already using the Closure Library:

javascript/soyutils.js
javascript/soyutils_usegoog.js

These files are included in the tarball you can download from the Closure Templates downloads page.

If your project already uses the Closure Library, use soyutils_usegoog.js, which is a much smaller file than soyutils.js.

The JavaScript utilities files also define one useful class and two useful functions that you can call from your hand-written code:

  • The class soy.StringBuilder is a simple JavaScript string builder that is implemented to be efficient for IE6, while not sacrificing any speed in the other browsers. Soy uses this internally for the stringbuilder code style, but you can also use it in your hand-written code. Also, it is compatible with the optional second argument of the template functions generated using the stringbuilder code style, which is described in the Rendering section of this chapter. Supported methods are append(varargs), clear(), and toString().

  • The two utility functions soy.renderElement() and soy.renderAsFragment() are explained in the Rendering section of this chapter.

Rendering

Rendering templates from your hand-written JavaScript code is simply a matter of calling a JavaScript function that's generated by the compiler. For the JavaScript Source backend, the compiler compiles each template into a corresponding JavaScript function (sometimes referred to as a template function) with the same name as the full name of the template. Note that you don't have to define namespaces because the template compiler generates code to define any namespaces that aren't already defined. A template function takes the template data as its argument, and returns the rendered template as a string. You can omit the template data argument if a template does not have any required parameters.

The JavaScript implementations of the template data types are:

Template Type JavaScript Type
Null null
Boolean boolean
Integer number
Float number
String string
List Array
Map Object

To build a template data object, you can construct a one-off literal object just for a template call, or you can use an existing data structure that is also used by other parts of your code (in which case it can contain keys that are not parameters to the templates that you're calling).

Example templates (assume the file's namespace is examples.simple):

/**
 * Says hello to the world.
 */
{template .helloWorld}
  Hello world!
{/template}

/**
 * Says hello to a person.
 * @param name The name of the person to say hello to.
 */
{template .helloName}
  Hello {$name}!
{/template}

Example usage:

var output1 = examples.simple.helloWorld();
var output2 = examples.simple.helloName({name: 'Ed'});

In this example, output1 would be 'Hello world!' and output2 would be 'Hello Ed!'.

The soy.renderElement() function

In some cases you might want to set the generated output as the innerHTML of an element. You can do this yourself after generating the string output, or you can use the soy.renderElement() function:

soy.renderElement(myElement, examples.simple.helloName, {name: 'Ed'});

where the first argument is the element whose innerHTML you want to set, the second argument is the template to call, and the third argument is the template data.

The soy.renderAsFragment() function

In other cases you might want the result as a document fragment. Again, you can do this yourself after generating the string output, or you can use the soy.renderAsFragment() function:

var myFragment = soy.renderAsFragment(
    examples.simple.helloName, {name: 'Ed'});

where the first argument is the template to call and the second argument is the template data.

Finally, recall from the earlier Code Styles section that if you use the stringbuilder code style, you can provide a second optional argument opt_sb to each generated JavaScript function. If you provide this argument, then instead of the template output being returned as a string, the template directly collects its output into the provided string builder and there is no return value. This approach is more efficient than manually appending the template's output to a string builder.

Globals

A global is data that is not explicitly passed into the template as a parameter, but instead is expected to be provided some other way. In JavaScript usage, you can bind globals at compile time or at render time. Render-time binding simply means you refer to the globals in your templates and ensure that they are defined in your JavaScript environment. Compile-time binding means you provide a mapping of globals to the template compiler, as explained below:

  • If you're using the executable jar SoyToJsSrcCompiler, use the flag --compileTimeGlobalsFile to supply a mapping of globals at compile time. Each line of the file should follow this format:

    <global_name> = <primitive_data>
    

    where <primitive_data> is a valid template expression literal for a primitive type (null, boolean, integer, float, or string). For example:

    GLOBAL_INT = 26
    myapp.GLOBAL_BOOL = true
    myapp.silly.GLOBAL_STR = 'I\'m a string.'
    

    Follow these guidelines when creating your globals file:

    • The template compiler ignores empty lines and lines that begin with //.
    • Encode the file in UTF-8.
    • If you need to generate a file in this format from Java, consider using the utility SoyUtils.generateCompileTimeGlobalsFile() (package com.google.template.soy).
  • If you're invoking the compiler directly from Java, use one of the three methods SoyFileSet.Builder.setCompileTimeGlobals() to supply a mapping of globals at compile time. (Note: the three methods have the same name but different argument types.) You can supply either a Map<String, ?>, where each value must be of a primitive type, or a File or resource URL (in the file format described in the bulleted item above).

All globals bound at compile time are substituted at compile time, so the generated JavaScript code does not contain those global names. Any global that is not bound at compile time appears in the generated code as a JavaScript name, which is resolved at render time. You must ensure that any such global names are in fact defined in the JavaScript environment at render time.

Note: Avoid using render-time globals unless absolutely necessary, because it makes for tight coupling between your template and your runtime environment.

Code Examples

You can check out simple and complex code examples of JavaScript usage from the Subversion repository. These code examples have corresponding Ant build targets. To try these out, check out the project from Subversion:

http://code.google.com/p/closure-templates/source/checkout

The files for JavaScript examples are in:

  • examples — shared examples files
  • javascript/examples — JavaScript-specific examples files

These directories each have a file called README_FOR_EXAMPLES that explains their contents.

To try these examples, simply open simple-usage.html, features-usage_en.html, and features-usage_x-zz.html files in a browser.

These examples reference a few generated JavaScript files that are supplied in the example directories listed above. Refer to the README_FOR_EXAMPLES files in each directory to see the names of the Ant targets that correspond to these generated JavaScript files. Then look for the definitions of these Ant targets in build.xml, which is at the top-level.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.