Add localization option for template engines

This commit is contained in:
René Pfeuffer
2019-04-03 11:52:01 +02:00
parent 751196c870
commit 08260fd7be
5 changed files with 81 additions and 5 deletions

View File

@@ -37,6 +37,7 @@ package sonia.scm.template;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.Locale;
/** /**
* The {@link TemplateEngine} searches for {@link Template}s and prepares the * The {@link TemplateEngine} searches for {@link Template}s and prepares the
@@ -59,11 +60,42 @@ public interface TemplateEngine
* *
* @param templatePath path of the template * @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 * @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.
* <p>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 * Creates a template of the given reader. Note some template implementations
@@ -79,7 +111,7 @@ public interface TemplateEngine
* *
* @since 1.22 * @since 1.22
*/ */
public Template getTemplate(String templateIdentifier, Reader reader) Template getTemplate(String templateIdentifier, Reader reader)
throws IOException; throws IOException;
/** /**
@@ -87,5 +119,12 @@ public interface TemplateEngine
* *
* @return type of template engine * @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;
}
} }

View File

@@ -97,6 +97,11 @@ public class MustacheTemplateEngineTest extends TemplateEngineTestBase
return "sonia/scm/template/001.mustache"; return "sonia/scm/template/001.mustache";
} }
@Override
public String getTemplateResourceWithGermanTranslation() {
return "sonia/scm/template/loc.mustache";
}
/** /**
* Method description * Method description
* *

View File

@@ -37,6 +37,7 @@ package sonia.scm.template;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.assertj.core.api.Assertions;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -52,6 +53,7 @@ import java.io.StringWriter;
import java.net.URL; import java.net.URL;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@@ -92,6 +94,8 @@ public abstract class TemplateEngineTestBase
*/ */
public abstract String getTemplateResource(); public abstract String getTemplateResource();
public abstract String getTemplateResourceWithGermanTranslation();
/** /**
* Method description * Method description
* *
@@ -126,7 +130,7 @@ public abstract class TemplateEngineTestBase
* @throws IOException * @throws IOException
*/ */
@Test @Test
public void testGetTemlateNotFound() throws IOException public void testGetTemplateNotFound() throws IOException
{ {
ServletContext context = mock(ServletContext.class); ServletContext context = mock(ServletContext.class);
TemplateEngine engine = createEngine(context); TemplateEngine engine = createEngine(context);
@@ -151,6 +155,32 @@ public abstract class TemplateEngineTestBase
assertNotNull(engine.getTemplate(getTemplateResource())); 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 * Method description
* *

View File

@@ -0,0 +1 @@
English

View File

@@ -0,0 +1 @@
German