Support i18n and nested templates in ScriptTemplateView

This commit changes the 3rd parameter passed to the rendering
function from String url to RenderingContext renderingContext.

RenderingContext contains 4 properties:
 - ApplicationContext applicationContext
 - Locale locale
 - Function<String, String> templateLoader
 - String url

Issue: SPR-15064
This commit is contained in:
Sebastien Deleuze
2017-01-23 18:37:27 +01:00
parent 8038fb9c8b
commit 2d95199466
29 changed files with 320 additions and 28 deletions

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2002-2017 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 org.springframework.web.servlet.view.script;
import java.util.Locale;
import java.util.function.Function;
import org.springframework.context.ApplicationContext;
/**
* Context passed to {@link ScriptTemplateView} render function.
*
* @author Sebastien Deleuze
* @since 5.0
*/
public class RenderingContext {
private final ApplicationContext applicationContext;
private final Locale locale;
private final Function<String, String> templateLoader;
private final String url;
public RenderingContext(ApplicationContext applicationContext, Locale locale,
Function<String, String> templateLoader, String url) {
this.applicationContext = applicationContext;
this.locale = locale;
this.templateLoader = templateLoader;
this.url = url;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
public Locale getLocale() {
return locale;
}
public Function<String, String> getTemplateLoader() {
return templateLoader;
}
public String getUrl() {
return url;
}
}

View File

@@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@@ -83,6 +84,8 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
private String engineName;
private Locale locale;
private Boolean sharedEngine;
private String[] scripts;
@@ -126,6 +129,14 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
this.engine = engine;
}
/**
* Set the {@link Locale} to pass to the render function.
* @since 5.0
*/
public void setLocale(Locale locale) {
this.locale = locale;
}
/**
* See {@link ScriptTemplateConfigurer#setEngineName(String)} documentation.
*/
@@ -345,14 +356,23 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
Invocable invocable = (Invocable) engine;
String url = getUrl();
String template = getTemplate(url);
Function<String, String> templateLoader = path -> {
try {
return getTemplate(path);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
};
RenderingContext context = new RenderingContext(this.getApplicationContext(), this.locale, templateLoader, url);
Object html;
if (this.renderObject != null) {
Object thiz = engine.eval(this.renderObject);
html = invocable.invokeMethod(thiz, this.renderFunction, template, model, url);
html = invocable.invokeMethod(thiz, this.renderFunction, template, model, context);
}
else {
html = invocable.invokeFunction(this.renderFunction, template, model, url);
html = invocable.invokeFunction(this.renderFunction, template, model, context);
}
response.getWriter().write(String.valueOf(html));

View File

@@ -16,6 +16,9 @@
package org.springframework.web.servlet.view.script;
import java.util.Locale;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
/**
@@ -56,6 +59,12 @@ public class ScriptTemplateViewResolver extends UrlBasedViewResolver {
setSuffix(suffix);
}
@Override
protected View createView(String viewName, Locale locale) throws Exception {
ScriptTemplateView view = (ScriptTemplateView)super.createView(viewName, locale);
view.setLocale(locale);
return view;
}
@Override
protected Class<?> requiredViewClass() {