From 08260fd7be48f3725cbd6235e9725b13636ea352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 3 Apr 2019 11:52:01 +0200 Subject: [PATCH] Add localization option for template engines --- .../sonia/scm/template/TemplateEngine.java | 47 +++++++++++++++++-- .../template/MustacheTemplateEngineTest.java | 5 ++ .../scm/template/TemplateEngineTestBase.java | 32 ++++++++++++- .../resources/sonia/scm/template/loc.mustache | 1 + .../sonia/scm/template/loc_de.mustache | 1 + 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 scm-webapp/src/test/resources/sonia/scm/template/loc.mustache create mode 100644 scm-webapp/src/test/resources/sonia/scm/template/loc_de.mustache diff --git a/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java b/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java index bfeca8f42c..0f26fd49c4 100644 --- a/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java +++ b/scm-core/src/main/java/sonia/scm/template/TemplateEngine.java @@ -37,6 +37,7 @@ package sonia.scm.template; import java.io.IOException; import java.io.Reader; +import java.util.Locale; /** * The {@link TemplateEngine} searches for {@link Template}s and prepares the @@ -59,11 +60,42 @@ public interface TemplateEngine * * @param templatePath path of the template * - * @return template associated withe the given path or null + * @return template associated with the given path or null * * @throws IOException */ - public Template getTemplate(String templatePath) throws IOException; + Template getTemplate(String templatePath) throws IOException; + + /** + * Returns the template associated with the given path and the given language + * or the default version. To do this, the template path will be extended + * with the language. For example `my-template.type` will be extended to + * `my-template_en.type`, if the language is {@link Locale#ENGLISH}. If no + * dedicated template can be found, the template without the extension will + * be used. + *

The template engine + * will search the template in the folder of the web application and in + * the classpath. This method will return null, + * if no template could be found for the given path. + * + * + * @param templatePath path of the template + * @param locale the preferred language + * + * @return template associated with the given path, extended by the language + * if found, or null + * + * @throws IOException + */ + default Template getTemplate(String templatePath, Locale locale) throws IOException { + String templatePathWithLanguage = extendWithLanguage(templatePath, locale); + Template templateForLanguage = getTemplate(templatePathWithLanguage); + if (templateForLanguage == null) { + return getTemplate(templatePath); + } else { + return templateForLanguage; + } + } /** * Creates a template of the given reader. Note some template implementations @@ -79,7 +111,7 @@ public interface TemplateEngine * * @since 1.22 */ - public Template getTemplate(String templateIdentifier, Reader reader) + Template getTemplate(String templateIdentifier, Reader reader) throws IOException; /** @@ -87,5 +119,12 @@ public interface TemplateEngine * * @return type of template engine */ - public TemplateType getType(); + TemplateType getType(); + + static String extendWithLanguage(String templatePath, Locale locale) { + int lastIndexOfDot = templatePath.lastIndexOf('.'); + String filename = templatePath.substring(0, lastIndexOfDot); + String extension = templatePath.substring(lastIndexOfDot); + return filename + "_" + locale.getLanguage() + extension; + } } diff --git a/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java b/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java index 1f24df3a5e..be0c33f098 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java +++ b/scm-webapp/src/test/java/sonia/scm/template/MustacheTemplateEngineTest.java @@ -97,6 +97,11 @@ public class MustacheTemplateEngineTest extends TemplateEngineTestBase return "sonia/scm/template/001.mustache"; } + @Override + public String getTemplateResourceWithGermanTranslation() { + return "sonia/scm/template/loc.mustache"; + } + /** * Method description * diff --git a/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java b/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java index 2622ab5f7a..75d40e558f 100644 --- a/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java +++ b/scm-webapp/src/test/java/sonia/scm/template/TemplateEngineTestBase.java @@ -37,6 +37,7 @@ package sonia.scm.template; import com.google.common.collect.Maps; +import org.assertj.core.api.Assertions; import org.junit.Test; import static org.junit.Assert.*; @@ -52,6 +53,7 @@ import java.io.StringWriter; import java.net.URL; +import java.util.Locale; import java.util.Map; import javax.servlet.ServletContext; @@ -92,6 +94,8 @@ public abstract class TemplateEngineTestBase */ public abstract String getTemplateResource(); + public abstract String getTemplateResourceWithGermanTranslation(); + /** * Method description * @@ -126,7 +130,7 @@ public abstract class TemplateEngineTestBase * @throws IOException */ @Test - public void testGetTemlateNotFound() throws IOException + public void testGetTemplateNotFound() throws IOException { ServletContext context = mock(ServletContext.class); TemplateEngine engine = createEngine(context); @@ -151,6 +155,32 @@ public abstract class TemplateEngineTestBase assertNotNull(engine.getTemplate(getTemplateResource())); } + @Test + public void testGetTemplateFromClasspathWithExistingLocale() throws IOException + { + ServletContext context = mock(ServletContext.class); + + TemplateEngine engine = createEngine(context); + + Template template = engine.getTemplate(getTemplateResourceWithGermanTranslation(), Locale.GERMAN); + StringWriter writer = new StringWriter(); + template.execute(writer, new Object()); + Assertions.assertThat(writer.toString()).contains("German"); + } + + @Test + public void testGetTemplateFromClasspathWithNotExistingLocale() throws IOException + { + ServletContext context = mock(ServletContext.class); + + TemplateEngine engine = createEngine(context); + + Template template = engine.getTemplate(getTemplateResourceWithGermanTranslation(), Locale.CHINESE); + StringWriter writer = new StringWriter(); + template.execute(writer, new Object()); + Assertions.assertThat(writer.toString()).contains("English"); + } + /** * Method description * diff --git a/scm-webapp/src/test/resources/sonia/scm/template/loc.mustache b/scm-webapp/src/test/resources/sonia/scm/template/loc.mustache new file mode 100644 index 0000000000..fb54c64e2c --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/template/loc.mustache @@ -0,0 +1 @@ +English diff --git a/scm-webapp/src/test/resources/sonia/scm/template/loc_de.mustache b/scm-webapp/src/test/resources/sonia/scm/template/loc_de.mustache new file mode 100644 index 0000000000..fc0b97796a --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/template/loc_de.mustache @@ -0,0 +1 @@ +German