backbone for i18n support (#55)

This commit is contained in:
Athou
2013-05-11 19:21:53 +02:00
parent 637c41f2ce
commit 3778b44588
7 changed files with 181 additions and 11 deletions

View File

@@ -467,6 +467,7 @@
<source>${basedir}/src/main/webapp/templates</source>
<prefix>templates/</prefix>
<destination>${basedir}/target/generated-sources/angularjs/all-templates.html</destination>
<i18nPath>${basedir}/src/main/resources/i18n/</i18nPath>
</properties>
<scriptpath>
<element>${basedir}/src/main/script</element>
@@ -477,8 +478,11 @@
project.properties['prefix'];
def dest =
project.properties['destination'];
def i18n =
project.properties['i18nPath'];
new
HTMLConcat().concat(source, prefix, dest);
HTMLConcat().concat(source,
prefix, dest, i18n);
</source>
</configuration>
</execution>

View File

@@ -0,0 +1,132 @@
package com.commafeed.frontend.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.commafeed.frontend.CommaFeedSession;
/**
* Replace variables from templates on the fly in dev mode only. In production
* the substitution is done at build-time.
*
*/
public class InternationalizationDevelopmentFilter implements Filter {
private static Logger log = LoggerFactory
.getLogger(InternationalizationDevelopmentFilter.class);
private boolean production = true;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (production) {
chain.doFilter(request, response);
return;
}
final ServletOutputStream wrapper = new ServletOutputStreamWrapper();
ServletResponse interceptor = new HttpServletResponseWrapper(
(HttpServletResponse) response) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return wrapper;
}
};
chain.doFilter(request, interceptor);
Locale locale = CommaFeedSession.get().getLocale();
byte[] bytes = translate(wrapper.toString(), locale).getBytes();
response.getOutputStream().write(bytes);
response.setContentLength(bytes.length);
response.getOutputStream().close();
}
private String translate(String content, Locale locale) {
Properties props = new Properties();
InputStream is = null;
try {
is = getClass().getResourceAsStream(
"/i18n/" + locale.getLanguage() + ".properties");
if (is == null) {
is = getClass().getResourceAsStream("/i18n/en.properties");
}
if (is == null) {
throw new Exception("Locale file not found for locale "
+ locale.getLanguage());
}
props.load(is);
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
IOUtils.closeQuietly(is);
}
return replace(content, props);
}
private static final Pattern PATTERN = Pattern.compile("\\$\\{(.+?)\\}");
public String replace(String content, Properties props) {
Matcher m = PATTERN.matcher(content);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String var = m.group(1);
Object replacement = props.get(var);
m.appendReplacement(sb, replacement.toString());
}
m.appendTail(sb);
return sb.toString();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String prod = ResourceBundle.getBundle("application").getString(
"production");
production = Boolean.valueOf(prod);
}
@Override
public void destroy() {
// do nothing
}
private static class ServletOutputStreamWrapper extends ServletOutputStream {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Override
public void write(int b) throws IOException {
baos.write(b);
}
@Override
public String toString() {
return baos.toString();
}
}
}

View File

@@ -0,0 +1 @@
toolbar.refresh=Refresh

View File

@@ -0,0 +1 @@
toolbar.refresh=Rafraichir

View File

@@ -3,26 +3,50 @@ import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.SystemUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HTMLConcat {
public void concat(String source, String prefix, String destination)
private static final Pattern PATTERN = Pattern.compile('\\$\\{(.+?)\\}');
public void concat(String source, String prefix, String destination, String i18nPath)
throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("<div>");
for (File file : new File(source).listFiles()) {
if (file.isFile()) {
for(File i18n : new File(i18nPath).listFiles()) {
StringBuilder sb = new StringBuilder();
sb.append("<div>");
for (File file : new File(source).listFiles()) {
sb.append(SystemUtils.LINE_SEPARATOR);
sb.append(String.format(
"<script type=\"text/ng-template\" id=\"%s%s\">",
prefix, file.getName()));
sb.append(SystemUtils.LINE_SEPARATOR);
sb.append(FileUtils.readFileToString(file));
sb.append(translate(FileUtils.readFileToString(file), i18n));
sb.append(SystemUtils.LINE_SEPARATOR);
sb.append("</script>");
sb.append(SystemUtils.LINE_SEPARATOR);
}
sb.append("</div>");
String dest = destination.substring(0, destination.lastIndexOf(".")) + "." + i18n.getName().split("\\.")[0] + ".html";
FileUtils.writeStringToFile(new File(dest), sb.toString());
}
sb.append("</div>");
FileUtils.writeStringToFile(new File(destination), sb.toString());
}
public String translate(String content, File i18n) {
Properties props = new Properties();
props.load(new FileInputStream(i18n));
return replace(content, props);
}
public String replace(String content, Properties props) {
Matcher m = PATTERN.matcher(content);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String var = m.group(1);
Object replacement = props.get(var);
m.appendReplacement(sb, replacement.toString());
}
m.appendTail(sb);
return sb.toString();
}
}

View File

@@ -15,6 +15,10 @@
<filter-name>WebResourceOptimizer</filter-name>
<filter-class>ro.isdc.wro.http.WroFilter</filter-class>
</filter>
<filter>
<filter-name>i18n</filter-name>
<filter-class>com.commafeed.frontend.utils.InternationalizationDevelopmentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>WebResourceOptimizer</filter-name>
@@ -24,7 +28,11 @@
<filter-name>Wicket</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>i18n</filter-name>
<url-pattern>/templates/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.commafeed.frontend.resources.WroListener</listener-class>
</listener>

View File

@@ -15,7 +15,7 @@
<button type="button" class="btn" ng-model="settingsService.settings.viewMode" btn-radio="'expanded'"><i class="icon-th-list"></i></button>
</div>
<button type="button" class="btn" ng-click="refresh()"><i class="icon-refresh"></i> Refresh</button>
<button type="button" class="btn" ng-click="refresh()"><i class="icon-refresh"></i> ${toolbar.refresh}</button>
<button type="button" class="btn" ng-click="markAllAsRead()"><i class="icon-ok"></i> Mark all as read</button>
<div class="btn-group">