forked from Archives/Athou_commafeed
backbone for i18n support (#55)
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1
src/main/resources/i18n/en.properties
Normal file
1
src/main/resources/i18n/en.properties
Normal file
@@ -0,0 +1 @@
|
||||
toolbar.refresh=Refresh
|
||||
1
src/main/resources/i18n/fr.properties
Normal file
1
src/main/resources/i18n/fr.properties
Normal file
@@ -0,0 +1 @@
|
||||
toolbar.refresh=Rafraichir
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user