Browse Source

Expose view url to render function in ScriptTemplateView

After this change, with Nashorn it is possible to use either
render(template, model) or render(template, model, url).
With JRuby or Jython, specifying the 3 parameters is mandatory.

Issue: SPR-13453
pull/860/merge
Sebastien Deleuze 11 years ago
parent
commit
f3b7e9ff2d
  1. 8
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java
  2. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java
  3. 32
      spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java
  4. 3
      spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/jruby/render.rb
  5. 2
      spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/jython/render.py
  6. 6
      spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/nashorn/render.js
  7. 5
      src/asciidoc/web-view.adoc

8
spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java

@ -157,10 +157,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { @@ -157,10 +157,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig {
/**
* Set the render function name (mandatory).
* This function will be called with the following parameters:
*
* <p>This function will be called with the following parameters:
* <ol>
* <li>{@code template}: the view template content (String)</li>
* <li>{@code model}: the view model (Map)</li>
* <li>{@code String template}: the template content</li>
* <li>{@code Map model}: the view model</li>
* <li>{@code String url}: the template url (since 4.2.2)</li>
* </ol>
*/
public void setRenderFunction(String renderFunction) {

7
spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateView.java

@ -323,14 +323,15 @@ public class ScriptTemplateView extends AbstractUrlBasedView { @@ -323,14 +323,15 @@ public class ScriptTemplateView extends AbstractUrlBasedView {
try {
ScriptEngine engine = getEngine();
Invocable invocable = (Invocable) engine;
String template = getTemplate(getUrl());
String url = getUrl();
String template = getTemplate(url);
Object html;
if (this.renderObject != null) {
Object thiz = engine.eval(this.renderObject);
html = invocable.invokeMethod(thiz, this.renderFunction, template, model);
html = invocable.invokeMethod(thiz, this.renderFunction, template, model, url);
}
else {
html = invocable.invokeFunction(this.renderFunction, template, model);
html = invocable.invokeFunction(this.renderFunction, template, model, url);
}
response.getWriter().write(String.valueOf(html));
}

32
spring-webmvc/src/test/java/org/springframework/web/servlet/view/script/NashornScriptTemplateTests.java

@ -56,22 +56,31 @@ public class NashornScriptTemplateTests { @@ -56,22 +56,31 @@ public class NashornScriptTemplateTests {
Map<String, Object> model = new HashMap<>();
model.put("title", "Layout example");
model.put("body", "This is the body");
MockHttpServletResponse response = renderViewWithModel("org/springframework/web/servlet/view/script/nashorn/template.html", model);
MockHttpServletResponse response = renderViewWithModel("org/springframework/web/servlet/view/script/nashorn/template.html",
model, ScriptTemplatingConfiguration.class);
assertEquals("<html><head><title>Layout example</title></head><body><p>This is the body</p></body></html>",
response.getContentAsString());
}
private MockHttpServletResponse renderViewWithModel(String viewUrl, Map<String, Object> model) throws Exception {
ScriptTemplateView view = createViewWithUrl(viewUrl);
@Test // SPR-13453
public void renderTemplateWithUrl() throws Exception {
MockHttpServletResponse response = renderViewWithModel("org/springframework/web/servlet/view/script/nashorn/template.html",
null, ScriptTemplatingWithUrlConfiguration.class);
assertEquals("<html><head><title>Check url parameter</title></head><body><p>org/springframework/web/servlet/view/script/nashorn/template.html</p></body></html>",
response.getContentAsString());
}
private MockHttpServletResponse renderViewWithModel(String viewUrl, Map<String, Object> model, Class<?> configuration) throws Exception {
ScriptTemplateView view = createViewWithUrl(viewUrl, configuration);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest();
view.renderMergedOutputModel(model, request, response);
return response;
}
private ScriptTemplateView createViewWithUrl(String viewUrl) throws Exception {
private ScriptTemplateView createViewWithUrl(String viewUrl, Class<?> configuration) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ScriptTemplatingConfiguration.class);
ctx.register(configuration);
ctx.refresh();
ScriptTemplateView view = new ScriptTemplateView();
@ -94,4 +103,17 @@ public class NashornScriptTemplateTests { @@ -94,4 +103,17 @@ public class NashornScriptTemplateTests {
}
}
@Configuration
static class ScriptTemplatingWithUrlConfiguration {
@Bean
public ScriptTemplateConfigurer nashornConfigurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
configurer.setEngineName("nashorn");
configurer.setScripts("org/springframework/web/servlet/view/script/nashorn/render.js");
configurer.setRenderFunction("renderWithUrl");
return configurer;
}
}
}

3
spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/jruby/render.rb

@ -3,8 +3,7 @@ require 'ostruct' @@ -3,8 +3,7 @@ require 'ostruct'
require 'java'
# Renders an ERB template against a hashmap of variables.
# template should be a Java InputStream
def render(template, variables)
def render(template, variables, url)
context = OpenStruct.new(variables).instance_eval do
variables.each do |k, v|
instance_variable_set(k, v) if k[0] == '@'

2
spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/jython/render.py

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
from string import Template
def render(template, model):
def render(template, model, url):
s = Template(template)
return s.substitute(model)

6
spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script/nashorn/render.js

@ -1,3 +1,7 @@ @@ -1,3 +1,7 @@
function render(template, model) {
return template.replace("{{title}}", model.title).replace("{{body}}", model.body);
}
}
function renderWithUrl(template, model, url) {
return template.replace("{{title}}", "Check url parameter").replace("{{body}}", url);
}

5
src/asciidoc/web-view.adoc

@ -1589,8 +1589,9 @@ And the Mustache template is: @@ -1589,8 +1589,9 @@ And the Mustache template is:
The render function is called with the following parameters:
* template: the view template content (String)
* model: the view model (Map)
* `String template`: the template content
* `Map model`: the view model
* `String url`: the template url (since 4.2.2)
`Mustache.render()` is natively compatible with this signature, so you can call it directly.

Loading…
Cancel
Save