samskivert / jmustache

A Java implementation of the Mustache templating language.
Other
834 stars 128 forks source link

Caching partial templates #116

Open Gohla opened 4 years ago

Gohla commented 4 years ago

Partial templates can be provided with a TemplateLoader. However, TemplateLoader.getTemplate returns a Reader instead of a Template, meaning that every time a partial is used, it is recompiled into a Template, which incurs extra overhead. I don't see a nice way to cache these partial templates with the current code (but I could be wrong).

As a workaround, I currently subclass Mustache.Compiler and add caching behavior. However, because Mustache.Delims is protected, this subclass must live under the com.samskivert.mustache package, and split packages are not allowed in Java 9 or higher.

Is there a nicer way to implement this caching behavior?

agentgt commented 2 years ago

However, TemplateLoader.getTemplate returns a Reader instead of a Template, meaning that every time a partial is used, it is recompiled into a Template, which incurs extra overhead. I don't see a nice way to cache these partial templates with the current code (but I could be wrong)

You should test it to verify that claim:

     @Test
    public void testPartials()
            throws Exception {
        AtomicInteger count = new AtomicInteger();
        TemplateLoader tl = new TemplateLoader() {
            @Override
            public Reader getTemplate(
                    String name)
                    throws Exception {
                count.incrementAndGet();
                return new StringReader(name);
            }
        };

        Template t = Mustache.compiler().withLoader(tl)
                .compile("{{> crap }}");
        t.execute(new Object());
        t.execute(new Object(){});
        t.execute(new Object());

        //If the sub template was not cached we would expect 3
        assertEquals(1, count.get());
    }

Thus the only thing you need to cache are the root templates. Most of the frameworks that use JMustache do this like Spring MVC.

agentgt commented 9 months ago

@samskivert

I think the above issue could be remedied for now with better documentation.

  1. That extending the compiler is how to add caching of templates
  2. That the partials are cached in the root templates (and have to be as they can processed differently based on spec indentation).

The javadoc does answer how to cache templates but its discoverability is not easy:

https://javadoc.io/doc/com.samskivert/jmustache/latest/com.samskivert.jmustache/com/samskivert/mustache/Mustache.Compiler.html

Furthermore we are missing Javadoc on the package-info.java and module-info.java. I plan on submitting a PR with basically a good portion the README.md in the module-info.java as javadoc later this week.