# Freemarker

Available as of Apache Camel 1.6

The freemarker: component allows you to process a message using a Freemarker template. This can be ideal when using Templating to generate responses for requests.

Maven users will need to add the following dependency to their `pom.xml` for this component:

    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-freemarker</artifactId>
        <version>x.x.x</version>
        <!-- use the same version as your Camel core version -->
    </dependency>

## URI format

    freemarker:templateName[?options]

Where templateName is the classpath-local URI of the template to invoke; or the complete URL of the remote template (for example, `file://folder/myfile.ftl`).

You can append query options to the URI in the following format, `?option=value&option=value&...`

## Options

Option | Default | Description
--- | --- | ---
`contentCache` | `true` | Cache for the resource content when its loaded.
`encoding` | `null` | Character encoding of the resource content.

## Freemarker Context

Apache Camel will provide exchange information in the Freemarker context (just a `Map`). The `Exchange` is transfered as:

Key | Value
--- | ---
`exchange` | The Exchange itself.
`headers` | The headers of the In message.
`camelContext` | The Camel Context.
`request` | The In message.
`body` | The In message body.
`response` | The Out message (only for InOut message exchange pattern).

## Hot reloading

The Freemarker template resource is by default not hot reloadable for both file and classpath resources (expanded jar). If you set `contentCache=false`, then Apache Camel will not cache the resource and hot reloading is thus enabled. This scenario can be used in development.

## Dynamic templates

Available as of Apache Camel 2.1 Camel provides two headers by which you can define a different resource location for a template or the template content itself. If any of these headers is set then Camel uses this over the endpoint configured resource. This allows you to provide a dynamic template at runtime.

Header | Type | Description
--- | --- | ---
CamelFreemarkerResourceUri | String | Apache Camel 2.1: A URI for the template resource to use instead of the endpoint configured.
CamelFreemarkerTemplate | String | Apache Camel 2.1: The template to use instead of the endpoint configured.

## Samples

For example, you can define a route like the following:

    from("activemq:My.Queue").
      to("freemarker:com/acme/MyResponse.ftl");

To use a Freemarker template to formulate a response to InOut message exchanges (where there is a `JMSReplyTo` header).

If you want to process InOnly exchanges, you could use a Freemarker template to transform the message before sending it on to another endpoint:

    from("activemq:My.Queue").
      to(ExchangePattern.InOut,"freemarker:com/acme/MyResponse.ftl").
      to("activemq:Another.Queue");

And to disable the content cache (for example, for development usage where the `.ftl` template should be hot reloaded):

    from("activemq:My.Queue").
      to(ExchangePattern.InOut,"freemarker:com/acme/MyResponse.ftl?contentCache=false").
      to("activemq:Another.Queue");

And for a file-based resource:

    from("activemq:My.Queue").
      to(ExchangePattern.InOut,"freemarker:file://myfolder/MyResponse.ftl?contentCache=false").
      to("activemq:Another.Queue");

In Apache Camel 2.1 it's possible to specify what template the component should use dynamically via a header, so for example:

    from("direct:in").
      setHeader("CamelFreemarkerResourceUri").constant("path/to/my/template.ftl").
      to("freemarker:dummy");

## The Email Sample

In this sample we want to use Freemarker templating for an order confirmation email. The email template is laid out in Freemarker as:

    Dear ${headers.lastName}, ${headers.firstName}

    Thanks for the order of ${headers.item}.

    Regards Camel Riders Bookstore
    ${body}

And the java code:

    private Exchange createLetter() {
        Exchange exchange = context.getEndpoint("direct:a").createExchange();
        Message msg = exchange.getIn();
        msg.setHeader("firstName", "Claus");
        msg.setHeader("lastName", "Ibsen");
        msg.setHeader("item", "Camel in Action");
        msg.setBody("PS: Next beer is on me, James");
        return exchange;
    }

    @Test
    public void testFreemarkerLetter() throws Exception {
        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);
        mock.expectedBodiesReceived("Dear Ibsen, Claus\n\nThanks for the order of Camel in Action.\n\nRegards Camel Riders Bookstore\nPS: Next beer is on me, James");

        template.send("direct:a", createLetter());

        mock.assertIsSatisfied();
    }

    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            public void configure() throws Exception {
                from("direct:a").to("freemarker:org/apache/camel/component/freemarker/letter.ftl").to("mock:result");
            }
        };
    }