view vs. render

154 views
Skip to first unread message

Matt Raible

unread,
Oct 18, 2011, 10:17:48 AM10/18/11
to sca...@googlegroups.com
I have the following in one of my Scalate/Jade templates:

-@ val front: Option[(models.Workout,models.User,Seq[models.Comment])]
- attributes("title") = "Timeline"

- front.map { front =>
- view(front, "workout")

The error I get when I try this is:

NoSuchViewException occured : No 'workout' view template could be found for model object '(Workout(3,Creekside to Flume to Chainsaw,Awesome morning ride through falling yellow leaves and cool fall breezes. ,150.0,12.0,2011-10-15,2),User(2,trishm...@gmail.com,whiskey,Trish,McGinity),List())' of type: scala.Tuple3

Since my model object is a Tuple, I'm guessing "view" won't work? I tried putting the "workout.jade" file everywhere, but never found the correct location. If it still is possible to use it, is it possible to pass two arguments in?

I have been able to use render(), but it seems like view is a bit cleaner.

NoSuchViewException occured : No 'workout' view template could be found for model object '(Workout(3,Creekside to Flume to Chainsaw,Awesome morning ride through falling yellow leaves and cool fall breezes. ,150.0,12.0,2011-10-15,2),User(2,trishm...@gmail.com,whiskey,Trish,McGinity),List())' of type: scala.Tuple3

render("workout.jade", Map('workout -> front, 'mode -> "home"))

James Strachan

unread,
Oct 19, 2011, 11:33:19 AM10/19/11
to sca...@googlegroups.com
On 18 October 2011 15:17, Matt Raible <mra...@gmail.com> wrote:
> I have the following in one of my Scalate/Jade templates:
>
> -@ val front: Option[(models.Workout,models.User,Seq[models.Comment])]
> - attributes("title") = "Timeline"
>
> - front.map { front =>
>  - view(front, "workout")
>
> The error I get when I try this is:
>
> NoSuchViewException occured : No 'workout' view template could be found for model object '(Workout(3,Creekside to Flume to Chainsaw,Awesome morning ride through falling yellow leaves and cool fall breezes. ,150.0,12.0,2011-10-15,2),User(2,trishm...@gmail.com,whiskey,Trish,McGinity),List())' of type: scala.Tuple3
>
> Since my model object is a Tuple, I'm guessing "view" won't work? I tried putting the "workout.jade" file everywhere, but never found the correct location. If it still is possible to use it, is it possible to pass two arguments in?

So the idea behind the view stuff is that its a naming convention for
associating templates to domain model, resource beans or DTO classes
(e.g. templates for a Person / Customer / Address / Purchase order and
so forth. Its just a simple naming convention so that, say, a Person
and Manager could have different templates and you'd not have to
litter your code with case statements to find the right template for
the right kind of person etc. Its a little bit like the snippets in
rails.

More details here...
http://scalate.fusesource.org/documentation/user-guide.html#Views


FWIW the same kind of naming convention is used in Jersey's JAXRS
template naming convention; so the same naming can be used for Jersey
to find Scalate templates as Scalate itself uses to resolve which
template to use for a 'view' method call.


> I have been able to use render(), but it seems like view is a bit cleaner.
>
> NoSuchViewException occured : No 'workout' view template could be found for model object '(Workout(3,Creekside to Flume to Chainsaw,Awesome morning ride through falling yellow leaves and cool fall breezes. ,150.0,12.0,2011-10-15,2),User(2,trishm...@gmail.com,whiskey,Trish,McGinity),List())' of type: scala.Tuple3
>
> render("workout.jade", Map('workout -> front, 'mode -> "home"))

The tricky bit in your example is the really complex type name:
Option[(models.Workout,models.User,Seq[models.Comment])]

What you could do is have a generic view for Option - which if it was
a Some, just called view on the Some.get() and None could show nothing
(say). This would mean that Scalate would then 'unwrap' an Option
value passed into a view method.

e.g. here's a sample which provides a view template for any class
which is-a Product (if no more concrete view can be found)
https://github.com/scalate/scalate/blob/master/samples/scalate-sample/src/main/webapp/scala/Product.index.ssp

i.e. if you create a person...

case class Person(name: String, address: Address)

and you don't have a Person.index.jade available, then the above
scala/Product.index.ssp would be found as a Person is-a scala.Product.


Tuples are harder though :) Again you could have a generic template
for any tuple; then just view each part of the tuple; though that
doesn't sound that useful in and of itself. If you used a case class
instead of a tuple, it'd be easier to associate a set of templates
with a kind of case class.

e.g. if you defined...

package whatever

case class Foo(workout: models.Workout, user: models.User, comments:
Seq[models.Comment])

then if your value is of type Option[Foo] then you could have an
Option and Foo template and your code would work if you changed your
template to


-@ val front: Option[Foo]

then had templates...

scala/Option.index.jade
whatever/Foo.index.jade


As an aside its probably useful to include a standard template for
Option in scalate; though I guess you might want to specify what None
looks like yourself :)

--
James
-------
FuseSource
Email: ja...@fusesource.com
Web: http://fusesource.com
Twitter: jstrachan, fusenews
Blog: http://macstrac.blogspot.com/

Open Source Integration and Messaging

James Strachan

unread,
Oct 19, 2011, 12:21:09 PM10/19/11
to sca...@googlegroups.com
A quicker answer for dealing with Option[T] values is - if you are
happy to consider Option[T] as being a collection of 0 or 1 elements
and to not render anything when there are 0 elements is to use

-@ val foo: Option[Thing]
- collection(foo)

then if foo is Some[Thing(x)] then it'll basically do the view on the thing.

However if you want to display some kind of content for None, you
probably want to use an Option template.

I just added an example of rendering Option this way...
https://github.com/scalate/scalate/blob/master/samples/scalate-sample/src/main/webapp/jade/renderOptionCollection.jade

Matt Raible

unread,
Oct 19, 2011, 12:29:44 PM10/19/11
to sca...@googlegroups.com
Is "collection" similar to "view" in that it's calling some template somewhere to render the contents of the object?

James Strachan

unread,
Oct 19, 2011, 1:18:59 PM10/19/11
to sca...@googlegroups.com
On 19 October 2011 17:29, Matt Raible <mra...@gmail.com> wrote:
> Is "collection" similar to "view" in that it's calling some template somewhere to render the contents of the object?

Yeah, the only real difference is collection iterates through all
elements in the collection and calls 'view' on it. So its a little
like...

- for (e <- coll)
- view(e)

with the added option of a separator between items in the collection

Reply all
Reply to author
Forward
0 new messages