=== Templates

Templates are rendered using a javadoc:ModelAndView[] object and require a javadoc:TemplateEngine[] implementation to be installed.

.Basic Rendering
[source, java, role = "primary"]
----
{
  install(new MyTemplateEngineModule());           // <1>
  
  get("/", ctx -> {
    MyModel model = new MyModel();                 // <2>
    return new ModelAndView("index.html", model);  // <3>
  });
}
----

.Kotlin
[source, kotlin, role = "secondary"]
----
{
  install(MyTemplateEngineModule())                 // <1>
  
  get("/") { ctx ->
    val model = MyModel()                           // <2>
    ModelAndView("index.html", model)               // <3>
  }
}
----

<1> Install a template engine module.
<2> Build the view model.
<3> Return a `ModelAndView` instance containing the template path and the model data.

You can explicitly set the desired locale for template rendering on the javadoc:ModelAndView[] object:

.Setting the Locale
[source, java, role = "primary"]
----
{
  install(new MyTemplateEngineModule());

  get("/", ctx -> {
    MyModel model = new MyModel();
    return new ModelAndView("index.html", model)
        .setLocale(Locale.GERMAN);                // <1>
  });
}
----

.Kotlin
[source, kotlin, role = "secondary"]
----
{
  install(MyTemplateEngineModule())

  get("/") { ctx ->
    val model = MyModel()
    ModelAndView("index.html", model)
        .setLocale(Locale.GERMAN)                 // <1>
  }
}
----

<1> Explicitly set the preferred locale.

If no locale is specified explicitly, Jooby falls back to the locale matched by the `Accept-Language` header of the current request.

[NOTE]
====
Not all template engines support localized rendering. If you use a template engine that doesn't support it, setting the locale will have no effect.
====

==== Template Engine

A template engine handles the actual view rendering. A template engine extends the javadoc:MessageEncoder[] interface, accepting a `ModelAndView` instance and producing a `String` result.

The javadoc:TemplateEngine[extensions] method lists the file extensions that the template engine supports. The default file extension is `.html`.

Jooby uses the file extension of the requested template to locate the correct template engine. If a template engine for the specified file extension isn't found, an `IllegalArgumentException` is thrown.

This file-extension routing allows you to easily use multiple template engines side-by-side in the same application:

.Multiple Template Engines
[source, java, role = "primary"]
----
{
  install(new HandlebarsModule());                 // <1>
  install(new FreemarkerModule());                 // <2>
  
  get("/first", ctx -> {
    return new ModelAndView("index.hbs", model);   // <3>
  });
  
  get("/second", ctx -> {
    return new ModelAndView("index.ftl", model);   // <4>
  });
}
----

.Kotlin
[source, kotlin, role = "secondary"]
----
{
  install(HandlebarsModule())                       // <1>
  install(FreemarkerModule())                       // <2>
  
  get("/first") { ctx ->
    ModelAndView("index.hbs", model)                // <3>
  }
  
  get("/second") { ctx ->
    ModelAndView("index.ftl", model)                // <4>
  }
}
----

<1> Install Handlebars.
<2> Install Freemarker.
<3> Renders using Handlebars due to the `.hbs` extension.
<4> Renders using Freemarker due to the `.ftl` extension.

Check out the <<ecosystem-modules-template-engines, Modules>> section for a full list of supported template engines.

==== View Model

Since Jooby 3.1.x, the view model can be any custom Java object/POJO. (Previous versions strictly required the model to be a `Map`).

There are two primary ways to instantiate a `ModelAndView`:

* `new ModelAndView(String view, Object model)` (For POJOs)
* `new MapModelAndView(String view, Map<String, Object> model)` (For Maps)
