Fork me on GitHub

Examples

Render Single Fragment with Markdown

This is an example to render a template from string:

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Fragment template = fmd.createFragemnt(
                "# A Title\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n"
                + "\n"
                + "## A List\n"
                + "\n"
                + "<#list sequence as item>\n"
                + "- ${item}\n"
                + "</#list>");
        template.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        assertThat(fmd.render(template), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>"
                + "<h2>A List</h2>\n"
                + "<ul>\n"
                + "  <li>foo</li>\n"
                + "  <li>bar</li>\n"
                + "  <li>baz</li>\n"
                + "</ul>"));

This is an example to render a template from file:

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final URI file = getClass()
                .getResource("renderSingleFragmentwithMarkdownFromFileTemplate.md.ftl")
                .toURI();
        final Fragment template = fmd.createFragemnt(Paths.get(file));
        template.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        assertThat(fmd.render(template), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>"
                + "<h2>A List</h2>\n"
                + "<ul>\n"
                + "  <li>foo</li>\n"
                + "  <li>bar</li>\n"
                + "  <li>baz</li>\n"
                + "</ul>"));

Render Layout with Fragments and Markdown

This is an example to render a templates from strings:

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Layout layout = fmd.createLayout(
                "# A Title\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n"
                + "\n"
                + "## A List\n"
                + "\n"
                + "<#list sequence as item>\n"
                + "- ${item}\n"
                + "</#list>\n"
                + "\n"
                + "${fragment}");
        layout.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        final Fragment fragment = fmd.createFragemnt("This is ${foo}.");
        fragment.assignVariable("foo", "bar");
        layout.assignTemplateModel("fragment", fragment);
        assertThat(fmd.render(layout), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>"
                + "<h2>A List</h2>\n"
                + "<ul>\n"
                + "  <li>foo</li>\n"
                + "  <li>bar</li>\n"
                + "  <li>baz</li>\n"
                + "</ul>\n"
                + "<p>This is bar.</p>"));

This is an example to render a templates from files:

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final URI fileLayout = getClass()
                .getResource("renderLayoutwithFragmentsandMarkdownFromStringTemplate_layout.md.ftl")
                .toURI();
        final Layout layout = fmd.createLayout(Paths.get(fileLayout));
        layout.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        final URI fileFragment = getClass()
                .getResource("renderLayoutwithFragmentsandMarkdownFromStringTemplate_fragment.md.ftl")
                .toURI();
        final Fragment fragment = fmd.createFragemnt(Paths.get(fileFragment));
        fragment.assignVariable("foo", "bar");
        layout.assignTemplateModel("fragment", fragment);
        assertThat(fmd.render(layout), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>"
                + "<h2>A List</h2>\n"
                + "<ul>\n"
                + "  <li>foo</li>\n"
                + "  <li>bar</li>\n"
                + "  <li>baz</li>\n"
                + "</ul>\n"
                + "<p>This is bar.</p>"));

Render Without Markdown

This example shows how to suppress the Markdown processing.

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Fragment template = fmd.createFragemnt(
                "# A Title\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n"
                + "\n"
                + "## A List\n"
                + "\n"
                + "<#list sequence as item>\n"
                + "- ${item}\n"
                + "</#list>", RenderOptions.WITHOUT_MARKDOWN);
        template.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        assertThat(fmd.render(template), is(
                "# A Title\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n"
                + "\n"
                + "## A List\n"
                + "\n"
                + "- foo\n"
                + "- bar\n"
                + "- baz\n"));

Render With Preprocessor

This example shows how to use preprocessors. The used key value preprocessor is part of FreeMarkerDown by default.

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Fragment template = fmd.createFragemnt(
                "# A Title\n"
                + "\n"
                + "<?fdm-keyvalue\n"
                + "    key1: value one\n"
                + "    key2: 42\n"
                + "?>\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n");
        final Map<String, String> keyValues = Maps.newHashMap();
        final PreProcessor processor = PreProcessors.createKeyValueProcessor(keyValues);
        fmd.register(processor);
        assertThat(fmd.render(template), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>"));
        assertThat(keyValues.size(), is(2));
        assertThat(keyValues, allOf(hasEntry("key1", "value one"), hasEntry("key2", "42")));
        if (processor.hasWarnings()) {
            for (final String warning : processor.getWarnings()) {
                // Handle warning ...
            }
        }

Layout Propagates Variables

Template variables assigned to a layout are propagated to all subsequent assigned template models. It does not matter if you assign the model before or after assigning variables. They will be propagated anyway.

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Layout layout = fmd.createLayout(
                "# A Title\n"
                + "\n"
                + "Lorem ipsum dolor sit amet.\n"
                + "\n"
                + "${fragment}");
        layout.assignVariable("sequence", Arrays.asList("foo", "bar", "baz"));
        final Fragment fragment = fmd.createFragemnt(
                "## A List\n"
                + "\n"
                + "<#list sequence as item>\n"
                + "- ${item}\n"
                + "</#list>\n"
                + "\n");
        layout.assignTemplateModel("fragment", fragment);
        assertThat(fmd.render(layout), is(
                "<h1>A Title</h1>"
                + "<p>Lorem ipsum dolor sit amet.</p>\n"
                + "<h2>A List</h2>\n"
                + "<ul>\n"
                + "  <li>foo</li>\n"
                + "  <li>bar</li>\n"
                + "  <li>baz</li>\n"
                + "</ul>"));

Handling Template Errors

Except the standard Java exceptions (IOExceptio etc.) no checked exceptions will be thrown. The Checked template exception from FreeMarker is wrapped into an unchecked template error. This does not clutter the code with “throws”, but gives you the responsibility to ensure that templates will render in all circumstances or catch them at appropriate position.

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Fragment fragment = fmd.createFragemnt("Lorem ipsum dolor: ${foo}");
        try {
            fmd.render(fragment);
        } catch (final TemplateError err) {
            assertThat(err.getMessage(), is(
                    "The following has evaluated to null or missing:\n"
                    + "==> foo  [in template \"\" at line 1, column 22]\n"
                    + "\n"
                    + "----\n"
                    + "Tip: If the failing expression is known to be legally refer to "
                    + "something that's null or missing, either specify a default value "
                    + "like myOptionalVar!myDefault, or use <#if myOptionalVar??>"
                    + "when-present<#else>when-missing</#if>. (These only cover the last "
                    + "step of the expression; to cover the whole expression, use parenthesis: "
                    + "(myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??\n"
                    + "----\n"
                    + "\n"
                    + "----\n"
                    + "FTL stack trace (\"~\" means nesting-related):\n\t- Failed at: ${foo}  "
                    + "[in template \"\" at line 1, column 20]\n"
                    + "----"));
        }

More Complex Example

TODO

        final FreeMarkerDown fmd = FreeMarkerDown.create();
        final Fragment content = fmd.createFragemnt("<?fdm-keyvalue\n"
                + "    Description: This is the first post.\n"
                + "    Keywords: first, post\n"
                + "?>\n"
                + "\n"
                + "### This is the First Post\n"
                + "\n"
                + "Lorem ipsum  dolor sit amet consetetur  sadipscing elitr sed diam  nonumy eirmod\n"
                + "tempor invidunt ut labore et dolore magna aliquyam.\n"
                + "\n"
                + "Lorem ipsum  dolor sit amet consetetur  sadipscing elitr sed diam  nonumy eirmod\n"
                + "tempor invidunt ut labore et dolore magna aliquyam.");
        final Layout post = fmd.createLayout("<article>\n"
                + "    ${content}\n"
                + "</article>", RenderOptions.WITHOUT_MARKDOWN);
        post.assignTemplateModel("content", content);
        final Layout layout = fmd.createLayout("<!DOCTYPE html>\n"
                + "<html>\n"
                + "    <body>\n"
                + "        <h1>${name}</h1>\n"
                + "        <h2>${description}</h2>\n"
                + "\n"
                + "        ${content}\n"
                + "    </body>\n"
                + "</html>", RenderOptions.WITHOUT_MARKDOWN);
        layout.assignVariable("name", "NAME");
        layout.assignVariable("description", "DESCRIPTION");
        layout.assignTemplateModel("content", post);
        final Map<String, String> keyValues = Maps.newHashMap();
        final PreProcessor processor = PreProcessors.createKeyValueProcessor(keyValues);
        fmd.register(processor);
        assertThat(fmd.render(layout), is(
                "<!DOCTYPE html>\n"
                + "<html>\n"
                + "    <body>\n"
                + "        <h1>NAME</h1>\n"
                + "        <h2>DESCRIPTION</h2>\n"
                + "\n"
                + "        <article>\n"
                + "    <h3>This is the First Post</h3>"
                + "<p>Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor "
                + "invidunt ut labore et dolore magna aliquyam.</p>"
                + "<p>Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor "
                + "invidunt ut labore et dolore magna aliquyam.</p>\n"
                + "</article>\n"
                + "    </body>\n"
                + "</html>"));