ratpack.thymeleaf.ThymeleafModule Maven / Gradle / Ivy
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ratpack.thymeleaf;
import com.google.common.base.Strings;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.cache.ICacheManager;
import org.thymeleaf.cache.StandardCacheManager;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import ratpack.guice.ConfigurableModule;
import ratpack.server.ServerConfig;
import ratpack.thymeleaf.internal.FileSystemBindingThymeleafResourceResolver;
import ratpack.thymeleaf.internal.ThymeleafTemplateRenderer;
import java.io.File;
import java.util.Set;
/**
* An extension module that provides support for Thymeleaf templating engine.
*
* To use it one has to register the module and then render {@link ratpack.thymeleaf.Template} instances.
* Instances of {@code Template} can be created using one of the
* {@link ratpack.thymeleaf.Template#thymeleafTemplate(java.util.Map, String, String)}
* static methods.
*
* By default templates are looked up in the {@code thymeleaf} directory of the application root with a {@code .html} suffix.
* So {@code thymeleafTemplate("my/template/path")} maps to {@code thymeleaf/my/template/path.html} in the application root directory.
* This can be configured using {@link #setTemplatesPrefix(String)} and {@link #setTemplatesSuffix(String)} as well as configuration of
* {@link Config#templatesPrefix(String)} and {@link Config#templateSuffix(String)}.
*
* Response content type can be manually specified, i.e. {@code thymeleafTemplate("template", model, "text/html")} if
* not specified will default to {@code text/html}.
*
{@code
* import ratpack.guice.Guice;
* import ratpack.test.embed.EphemeralBaseDir;
* import ratpack.test.embed.EmbeddedApp;
*
* import java.nio.file.Path;
*
* import static org.junit.Assert.*;
*
* {@literal @}SuppressWarnings("deprecation")
* public class Example {
*
* public static void main(String... args) throws Exception {
* EphemeralBaseDir.tmpDir().use(baseDir -> {
* baseDir.write("thymeleaf/myTemplate.html", "");
* EmbeddedApp.of(s -> s
* .serverConfig(c -> c.baseDir(baseDir.getRoot()))
* .registry(Guice.registry(b -> b.module(ratpack.thymeleaf.ThymeleafModule.class)))
* .handlers(chain -> chain
* .get(ctx -> ctx.render(ratpack.thymeleaf.Template.thymeleafTemplate("myTemplate", m -> m.put("key", "Hello Ratpack!"))))
* )
* ).test(httpClient -> {
* assertEquals("Hello Ratpack!", httpClient.getText());
* });
* });
* }
* }
* }
*
* To register dialects, use Guice Multibindings to bind an implementation of {@code IDialect} in a module.
*
* @see Thymeleaf
* @see Guice Multibindings
* @deprecated since 1.7.0. Use {@code ratpack-thymeleaf3} instead.
*/
@SuppressWarnings("UnusedDeclaration")
@Deprecated
public class ThymeleafModule extends ConfigurableModule {
/**
* The configuration object for {@link ThymeleafModule}.
*/
public static class Config {
private int templatesCacheSize;
private String templatesMode = DEFAULT_TEMPLATE_MODE;
private String templatesPrefix = DEFAULT_TEMPLATE_PREFIX;
private String templatesSuffix = DEFAULT_TEMPLATE_SUFFIX;
/**
* The size of the templates cache.
*
* {@code 0} by default (disabled).
*
* @return the size of the templates cache.
*/
public int getTemplatesCacheSize() {
return templatesCacheSize;
}
/**
* The mode for templates.
*
* {@value ratpack.thymeleaf.ThymeleafModule#DEFAULT_TEMPLATE_MODE} by default.
*
* @return the mode for templates.
*/
public String getTemplatesMode() {
return templatesMode;
}
/**
* The prefix for templates.
*
* {@value ratpack.thymeleaf.ThymeleafModule#DEFAULT_TEMPLATE_PREFIX} by default.
*
* @return the prefix for templates.
*/
public String getTemplatesPrefix() {
return templatesPrefix;
}
/**
* The suffix for templates.
*
* {@value ratpack.thymeleaf.ThymeleafModule#DEFAULT_TEMPLATE_SUFFIX} by default.
*
* @return the suffix for templates.
*/
public String getTemplatesSuffix() {
return templatesSuffix;
}
/**
* Sets the size of the templates cache.
*
* @param templatesCacheSize the size of the templates cache
* @return this
*/
public Config templatesCacheSize(int templatesCacheSize) {
this.templatesCacheSize = templatesCacheSize;
return this;
}
/**
* Sets the mode for templates.
*
* @param templatesMode the mode for templates
* @return this
*/
public Config templatesMode(String templatesMode) {
this.templatesMode = templatesMode;
return this;
}
/**
* Sets the prefix for templates.
*
* @param templatesPrefix the prefix for templates
* @return this
*/
public Config templatesPrefix(String templatesPrefix) {
this.templatesPrefix = templatesPrefix;
return this;
}
/**
* Sets the suffix for templates.
*
* @param templatesSuffix the suffix for templates
* @return this
*/
public Config templateSuffix(String templatesSuffix) {
this.templatesSuffix = templatesSuffix;
return this;
}
}
public static final String DEFAULT_TEMPLATE_MODE = "XHTML";
public static final String DEFAULT_TEMPLATE_PREFIX = "thymeleaf";
public static final String DEFAULT_TEMPLATE_SUFFIX = ".html";
private String templatesMode;
private String templatesPrefix;
private String templatesSuffix;
private Integer templatesCacheSize;
public String getTemplatesMode() {
return templatesMode;
}
public void setTemplatesMode(String templatesMode) {
this.templatesMode = templatesMode;
}
public String getTemplatesPrefix() {
return templatesPrefix;
}
public void setTemplatesPrefix(String templatesPrefix) {
this.templatesPrefix = templatesPrefix;
}
public String getTemplatesSuffix() {
return templatesSuffix;
}
public void setTemplatesSuffix(String templatesSuffix) {
this.templatesSuffix = templatesSuffix;
}
public Integer getTemplatesCacheSize() {
return templatesCacheSize;
}
public void setTemplatesCacheSize(Integer templatesCacheSize) {
this.templatesCacheSize = templatesCacheSize;
}
@Override
protected void configure() {
Multibinder.newSetBinder(binder(), IDialect.class);
bind(ThymeleafTemplateRenderer.class).in(Singleton.class);
bind(ICacheManager.class).to(StandardCacheManager.class).in(Singleton.class);
}
@Provides
@Singleton
ITemplateResolver provideTemplateResolver(ServerConfig serverConfig, Config config) {
IResourceResolver resourceResolver = new FileSystemBindingThymeleafResourceResolver(serverConfig.getBaseDir());
TemplateResolver templateResolver = new TemplateResolver();
templateResolver.setResourceResolver(resourceResolver);
templateResolver.setTemplateMode(getTemplatesModeSetting(config));
templateResolver.setPrefix(getTemplatesPrefixSetting(config));
templateResolver.setSuffix(getTemplatesSuffixSetting(config));
templateResolver.setCacheable(getCacheSizeSetting(config) > 0);
templateResolver.setCacheTTLMs(null); // Never use TTL expiration
return templateResolver;
}
@Provides
@Singleton
StandardCacheManager provideCacheManager(Config config) {
int cacheSize = getCacheSizeSetting(config);
StandardCacheManager cacheManager = new StandardCacheManager();
cacheManager.setTemplateCacheMaxSize(cacheSize);
return cacheManager;
}
@Provides
@Singleton
TemplateEngine provideTemplateEngine(ITemplateResolver templateResolver, ICacheManager cacheManager, Set dialects) {
final TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
templateEngine.setCacheManager(cacheManager);
dialects.stream().forEach(templateEngine::addDialect);
return templateEngine;
}
private int getCacheSizeSetting(Config config) {
return templatesCacheSize == null ? config.getTemplatesCacheSize() : templatesCacheSize;
}
private String getTemplatesModeSetting(Config config) {
return templatesMode == null ? config.getTemplatesMode() : templatesMode;
}
private String getTemplatesPrefixSetting(Config config) {
String prefix = templatesPrefix == null ? config.getTemplatesPrefix() : templatesPrefix;
if (!prefix.endsWith(File.separator)) {
prefix += File.separator;
}
return prefix;
}
private String getTemplatesSuffixSetting(Config config) {
String suffix = Strings.emptyToNull(templatesSuffix == null ? config.getTemplatesSuffix() : templatesSuffix);
if (suffix == null) {
suffix = DEFAULT_TEMPLATE_SUFFIX;
}
return suffix;
}
}