The current Spring MVC support uses a similar approach to JAXRS /
Servlets - taking the default model and mapping it to the 'it'
attribute. Though if there's a different way you'd like to map things
it should be trivial to support other approaches.
e.g. we could expose each entry in Spring MVC's model Map as
attributes in the template.
Do you fancy tweaking the Spring MVC classes to suit your needs and
submitting a patch?
--
James
-------
FuseSource
Email: ja...@fusesource.com
Web: http://fusesource.com
Twitter: jstrachan
Blog: http://macstrac.blogspot.com/
Open Source Integration
@RequestMapping(value = "/user", method = RequestMethod.GET)
protected ModelAndView listAllUsers(final Model model) {
Collection<User> users = userService.listUsers();
ModelAndView mv = new ModelAndView(viewName("/WEB-INF/scala/user.scaml", true));
mv.addObject("it", users);
return mv;
}
Thanks for a great example! More inline...
> The controller:
>
> @Controller
> @RequestMapping("/scalate")
> public class ScalateController {
> @RequestMapping("test")
> public String test(Model model) {
> model.addAttribute("aStr", "100");
> model.addAttribute("aInt", 21387);
> model.addAttribute("someObject", new SomeObject());
> return "render:scamlTest.scaml";
> }
> }
>
> The SomeObject class:
>
> package sample;
>
> public class SomeObject {
> public String a = "The first string";
> public String b = "The second string";
> }
>
> The scamlTest.scaml template looks like this:
>
> -@ val aStr : String = attributes("aStr").asInstanceOf[String]
> -@ val aint : Int = attributes("aInt").asInstanceOf[Int]
> -@ val someObject: sample.SomeObject =
> attributes("someObject").asInstanceOf[sample.SomeObject]
Note that you don't need to use the right hand assignment part above.
When you use the syntax...
-@ val aStr : String
that actually maps to code roughly equal to...
- val aStr : String = attributes[String]("aStr")
which is a helper method for the code you wrote...
- val aStr : String = attributes("aStr").asInstanceOf[String]
So really all the -@ syntax does is allow you to automatically bind
attributes to named parameters in a more concise DRY way. Plus it lets
you define optional values if there is no attribute defined. e.g.
-@val aStr: String = "some default"
is syntax sugar for
- val aStr : String = attributeOrElse[String]("aStr", "some default")
> int: #{aInt} (#{aint.asInstanceOf[AnyRef].getClass()})
> someObject: #{someObject}
> someObject->a: #{someObject.a}
> someObject->b: #{someObject.b}
>
> I wonder if the typecasting is needed at the beginning or if there is
> a more simple way. Maybe via generics.
Yeah, see above - I thought I'd reply under a specific line so its
easier to compare the differences.
> Another problem is that you cant use the ScalateViewResolver together
> with the
> org.springframework.web.servlet.view.InternalResourceViewResolver.
> So you have to choose between jsp and scalate and can not use both
> together.
Shame; wonder if there's a way around it? Though ditching all JSP
everywhere is quite a pleasing moment :)
> Spring MVC does have the option to chain multiple ViewResolvers.
> Spring goes tthrough the chain one after another, until one view
> resolver can render the template.
>
> When a resolver is unable to render the template, it needs to return
> null from loadView(..). Unfortunately InternalResourceViewResolver can
> never return null,
> because of the way it handles the render process. ScalateViewResolver
> now also doesnt return null in case there is no template found. In
> fact it tries to render
> the template, which leads to this exception:
>
> org.springframework.web.util.NestedServletException: Request
> processing failed; nested exception is
> org.fusesource.scalate.TemplateException: Template file extension
> missing. Cannot determine which template processor to use.
>
> Maybe it would be sufficient to add a simple check if the template
> file exists:
> https://github.com/scalate/scalate/blob/master/scalate-spring-mvc/src/main/scala/org/fusesource/scalate/spring/view/ScalateViewResolver.scala#L27
> What do you think?
Sounds great! Then could Scalate go first in the chain; then if it
can't find the template it returns null and lets the next one in the
chain render it?
Thanks for the feedback!
We should definitely improve the Spring MVC samples & docs!
scalate-website/src/main/webapp/documentation
See the jog.page for an example of a framework documentation page.
and the examples should go under samples/scalate-sample-spring-mv
Regards,
Hiram
FuseSource
Web: http://fusesource.com/
it looks to me that layouts are not meant to receive a model, but rather
take care on how the final layout of the website will look like. That
means you pass the model to a render template and this render template
to layout again. If you need to use attributes inside the layout, you
declare them in the layout template and assign them in the render
template. Check the documentation at:
http://scalate.fusesource.org/documentation/user-guide.html#layouts
Greets,
Stefan
patches all applied now with huge thanks!
<bean class="org.fusesource.scalate.spring.view.ScalateViewResolver" p:order="1" p:prefix="/WEB-INF/views/scalate/" p:suffix=".jade" p:cache="false" />
Do you have a full example with the namespace declaration BTW?
> I will make a patch for sample project in order to illustrated a
> little more the Scalate Spring MVC Integration in a Java Project
> I could be a good sample for projects that would migrated to scala
Great stuff!
James: Maybe there is a better way to do this?
Greets,
Stefan
> J�r�me
>
>
>
> On 6 jan, 13:14, James Strachan<ja...@fusesource.com> wrote:
@RequestMapping("layout")
public String layout(Model model) {
model.addAttribute("layout", "/WEB-INF/scalate/layouts/special.scaml");
return "layout:views/foo";
}
This one uses now layouts/special.scaml instead of layouts/default.scaml =)
Greets,
Stefan
Do you have a link to spring's documentation about this syntax? Looks
like it is a shortcut for <property ..> and is handled differently by
spring than the property tags. Maybe there is something written in the docs.
Please check this version:
https://github.com/dozed/scalate/commit/f4fc1fcaa2ba93267cf6901880f6767b3099182c
It works for me with the following xml configuration:
<bean class="org.fusesource.scalate.spring.view.ScalateViewResolver"
p:order="1"
p:cache="false"
p:prefix="/WEB-INF/scalate/"
p:suffix=".scaml" />
Greets,
Stefan