# Hello World Using Java

## Hello World

Follow these steps to create a simple Hello World template and use it in Java:

1.  Create a new [Maven](https://maven.apache.org) project using your favorite
    IDE. (`Closure Templates` is a plain Java library and will work with any Java
    build tool. This example uses Maven.) The final directory structure will
    look like this:

    ```
    .
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── example
            │       └── HelloWorld.java
            └── resources
                └── example
                    └── simple.soy
    ```

2.  All files that contain `Closure Templates` end with the `.soy` file extension
    and are called Soy files. Create `src/main/resources/example/simple.soy`
    containing the following line:

        {namespace examples.simple}

    This line declares a namespace for all the templates that you define in this
    file.

3.  Copy the following template to `src/main/resources/example/simple.soy`,
    making sure that it appears after the namespace declaration:

        {template .helloWorld}
          Hello world!
        {/template}

    This template simply outputs the text `Hello world!`. It has the partial
    name `.helloWorld`, which, when combined with the namespace, forms the fully
    qualified template name `examples.simple.helloWorld`.

4.  Now that we've written the template, we need to write the Java code to
    render the template. To do that, we need to tell Maven to add a dependency
    on `Closure Templates`.

    `pom.xml` is the main Maven configuration file. Edit to add the dependency:

        <dependencies>
          <dependency>
            <groupId>com.google.template</groupId>
            <artifactId>soy</artifactId>
            <version>2018-03-14 </version> <!-- Or latest version.-->
          </dependency>
        </dependencies>

    (See
    [here](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html)
    for more information about the structure of `pom.xml`.)

5.  Create `src/main/java/example/HelloWorld.java` with the following contents:

        package example;

        import com.google.template.soy.SoyFileSet;
        import com.google.template.soy.tofu.SoyTofu;

        public class HelloWorld {
          public static void main(String[] args) {
            SoyFileSet sfs = SoyFileSet
                .builder()
                .add(HelloWorld.class.getResource("simple.soy"))
                .build();
            SoyTofu tofu = sfs.compileToTofu();
            System.out.println(
                tofu.newRenderer("examples.simple.helloWorld").render());
          }
        }

    This example bundles the template files that you specify (in this case, just
    `simple.soy`) into a `SoyFileSet` object, then compiles the bundle into a
    `SoyTofu` object with a call to `compileToTofu()`. The final line calls the
    template, using the template's fully qualified name
    `examples.simple.helloWorld`, and renders its output to standard out.

6.  Add the following snippet to `pom.xml` to tell Maven how to execute the main
    class (`HelloWorld`):

        <build>
          <plugins>
            <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>exec-maven-plugin</artifactId>
              <version>1.6.0</version>
              <executions>
                <execution>
                  <phase>package</phase>
                  <goals>
                    <goal>java</goal>
                  </goals>
                </execution>
              </executions>
              <configuration>
                <mainClass>example.HelloWorld</mainClass>
              </configuration>
            </plugin>
          </plugins>
        </build>

7.  Run `mvn package` at the root of your project. You should see this message
    at standard out:

        Hello world!

## Hello Name and Hello Names

1.  Add the following second template, called `.helloName`, to `simple.soy`.
    Note that `.helloName` takes a required parameter called `name`, which is
    declared by `@param`. It also takes an optional parameter `greetingWord`,
    which is declared by `@param?`. These parameters are referenced in the
    template body using the expressions `$name` and `$greetingWord`,
    respectively. This template also demonstrates that you can conditionally
    include content in templates via the `if-else` commands. You can put this
    template before or after the `.helloWorld` template, just as long as it's
    after the `namespace` declaration.

        /** Greets a person using "Hello" by default. */
        {template .helloName}
          {@param name: string} /** The person's name. */
          {@param? greetingWord: string} /**
                                          * Optional greeting word to use
                                          * instead of "Hello".
                                          */
          {if not $greetingWord}
            Hello {$name}!
          {else}
            {$greetingWord} {$name}!
          {/if}
        {/template}

2.  Add a third template to the file. This template, `helloNames`, demonstrates
    a `for` loop with an `ifempty` command. It also shows how to call other
    templates and insert their output using the `call` command. Note that the
    `data="all"` attribute in the `call` command passes all of the caller's
    template data to the callee template.

        /** Greets a person and optionally a list of other people. */
        {template .helloNames}
          {@param name: string} /** The person's name. */
          {@param additionalNames: list<string>} /**
                                                  * Additional names to greet.
                                                  * May be an empty list.
                                                  */
          // Greet the person.
          {call .helloName data="all" /}<br>
          // Greet the additional people.
          {for $additionalName in $additionalNames}
            {call .helloName}
              {param name: $additionalName /}
            {/call}
            {if not isLast($additionalName)}
              <br>  // break after every line except the last
            {/if}
          {ifempty}
            No additional people to greet.
          {/for}
        {/template}

3.  Now edit `src/main/java/exampleHelloWorld.java` to call the new templates
    and exercise them with data:

         package example;

         import com.google.template.soy.SoyFileSet;
         import com.google.template.soy.tofu.SoyTofu;
         import java.util.Arrays;
         import java.util.HashMap;
         import java.util.List;
         import java.util.Map;

         public class HelloWorld {
           public static void main(String[] args) {
             SoyFileSet sfs = SoyFileSet
                 .builder()
                 .add(HelloWorld.class.getResource("simple.soy"))
                 .build();

             // helloWorld
             SoyTofu tofu = sfs.compileToTofu();
             System.out.println(
                 tofu.newRenderer("examples.simple.helloWorld").render());

             // For convenience, create another SoyTofu object that has a
             // namespace specified, so you can pass partial template names to
             // the newRenderer() method.
             SoyTofu simpleTofu = tofu.forNamespace("examples.simple");

             // helloName
             Map<String, Object> data = new HashMap<>();
             data.put("name", "Ana");
             System.out.println("-----------------");
             System.out.println(
                 simpleTofu.newRenderer(".helloName").setData(data).render());

             // helloNames
             List<String> additionalNames = Arrays.asList("Bob", "Cid", "Dee");
             data.put("additionalNames", additionalNames);
             System.out.println("-----------------");
             System.out.println(
                 simpleTofu.newRenderer(".helloNames").setData(data).render());
           }
         }

    This example exercises the `.helloName` template with a Java `Map` in which
    the parameter `name` is mapped to the string `Ana`. For the `.helloNames`
    template, the example maps the parameter `additionalNames` to a list of
    strings `Bob`, `Cid`, `Dee`.

4.  Run `mvn package` at the root of your project. You should see this message
    at standard out:

        Hello world!
        -----------------
        Hello Ana!
        -----------------
        Hello Ana!<br>Hello Bob!<br>Hello Cid!<br>Hello Dee!

## Using Guice

If your application uses [Guice](http://code.google.com/p/google-guice/), you
can inject Soy classes such as `SoyFileSet.Builder` instead of constructing them
yourself. Your Guice injector must contain `SoyModule`.

For example, if you used Guice, the Hello World example from the previous
section would start like this (with three additional import lines not shown):

~~~ {.prettyprint}
    // Create a Guice injector that contains the SoyModule and use it get a SoyFileSet.Builder.
    Injector injector = Guice.createInjector(new SoyModule());
    SoyFileSet.Builder sfsBuilder = injector.getInstance(SoyFileSet.Builder.class);

    // Bundle the Soy files for your project into a SoyFileSet.
    SoyFileSet sfs = sfsBuilder.add(new File("simple.soy")).build();
~~~

## Using SoyParseInfoGenerator

You might find it error-prone to type hard-coded strings for template names and
template parameters. If so, you can use `SoyParseInfoGenerator` to generate Java
constants for the template and parameter names in your templates. Follow the
steps below to use `SoyParseInfoGenerator` with the Hello World example:

1.  Download the latest version of `SoyParseInfoGenerator.jar` from [Maven
    Central](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22soy%22) and put
    it at the project root.

    Unlike the main `Closure Templates` jar, `SoyParseInfoGenerator.jar` is
    executable, and can be run from the command line with `java -jar
    SoyParseInfoGenerator.jar`. The jar parses Soy files and generates Java
    classes that contain information such as template and parameter names.
    (Typically, you would want to run SoyParseInfoGenerator as part of a build
    step. This can be done with exec-maven-plugin for example, but it is outside
    the scope of this codelab.)

    Run `SoyParseInfoGenerator` with the following flags:

        $ java -jar SoyParseInfoGenerator.jar \
            --outputDirectory src/main/java/example \
            --javaPackage example \
            --javaClassNameSource filename \
            --srcs src/main/resources/example/simple.soy

    This step creates the file `src/main/java/example/SimpleSoyInfo.java`. This
    file contains mappings between the generated constants and their
    corresponding strings.

    Open `src/main/java/example/SimpleSoyInfo.java` and look at the constants
    that `SoyParseInfoGenerator` generated for each of the templates and their
    parameters. For example, the Java constant `HELLO_NAME` maps to a
    `SoyTemplateInfo` object that represents the `.helloName` template, and the
    constant `HELLO_NAME.NAME` maps to the `.helloName` template's parameter
    `name`.

2.  Edit `src.main/java/example/HelloWorld.java` to looks like this:

~~~ {.prettyprint}
package example;

import static example.SimpleSoyInfo.HELLO_NAME;
import static example.SimpleSoyInfo.HELLO_NAMES;
import static example.SimpleSoyInfo.HELLO_WORLD;

import com.google.template.soy.SoyFileSet;
import com.google.template.soy.tofu.SoyTofu;
import example.SimpleSoyInfo.HelloNameSoyTemplateInfo;
import example.SimpleSoyInfo.HelloNamesSoyTemplateInfo;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HelloWorld {
  public static void main(String[] args) {
    SoyFileSet sfs = SoyFileSet
        .builder()
        .add(HelloWorld.class.getResource("simple.soy"))
        .build();
    SoyTofu tofu = sfs.compileToTofu();
    System.out.println(tofu.newRenderer(SimpleSoyInfo.HELLO_WORLD).render());

    SoyTofu simpleTofu = tofu.forNamespace("examples.simple");
    Map<String, Object> data = new HashMap<>();
    data.put(HelloNameSoyTemplateInfo.NAME, "Ana");
    System.out.println(
        simpleTofu
            .newRenderer(SimpleSoyInfo.HELLO_NAME)
            .setData(data)
            .render());

    List<String> additionalNames = Arrays.asList("Bob", "Cid", "Dee");
    data.put(HelloNamesSoyTemplateInfo.ADDITIONAL_NAMES, additionalNames);
    System.out.println(
        simpleTofu
            .newRenderer(SimpleSoyInfo.HELLO_NAMES)
            .setData(data)
            .render());
  }
}
~~~

3.  Run `mvn package` at the root of your project. You should see the same
    message as before:

        Hello world!
        -----------------
        Hello Ana!
        -----------------
        Hello Ana!<br>Hello Bob!<br>Hello Cid!<br>Hello Dee!

You've just completed the `Closure Templates` Hello World using Java. Where should
you go next?

-   To use the same templates from this chapter in JavaScript, try the [Hello
    World Using JavaScript](helloworld_js.md) examples.
-   To read more about `Closure Templates` concepts, take a look at the
    [Concepts](../concepts/index.md) chapter.
