views:

128

answers:

3

Everyone who's done any web application development in Scala knows that you can use any existing Java web framework, or you can use Lift. Something that all of these frameworks have in common is that they all require two or more files to generate a page: an HTML template of some kind, and one or more classes to provide associated logic. Even if you're writing a JSP-only app, you're probably still making use of lots of custom tags.

And this brings me to something I've noticed: the template files often bear little resemblance to HTML. Wicket template files are pretty much HTML because in Wicket, components bind themselves to HTML tags in the template. But in all the frameworks that are based on custom tags, the templates are generally full of custom tags and are not renderable in a browser on their own.

Scala supports embedding arbitrary XML directly into the program source. Here is a Scala function that make an unnumbered list from a collection:

def listify[T](items: Iterable[T], liBody: T => NodeSeq) = <ul>{
  items.flatMap(i => <li>{liBody(i)}</li>)
}</ul>

Now if I have that, I've already abandoned architectural purity because I have ul and li tags in the "controller," or "business logic," or "backing object," or whatever you call it, and not in the template. Yet this is a pretty clear and straightforward way of creating a list. Doing it any other way requires substituting some run-time tag-binding framework in place of Scala's own built-in features.

So I'm wondering, why not just go the other way and get rid of the templates? If Scala is useful for creating an unnumbered list, then why can't it also create whatever contains the unnumbered list? And all the way up the page back to the html tag.

The question I'm asking is: given a language that already includes powerful support for XML, are there significant benefits to using template files and transforming them into actual HTML at run time, or is it better to just consider template files as artifacts carried over from languages without built-in XML support and abandon them?

+2  A: 

I think the main reason is for tooling support. It is easier to support tooling when part of the project is strictly XML (the template files). It is far trickier (though not impossible), to manipulate code from a design tool.

Also, in most production environments, the abstraction of business logic from the "view" (using whatever paradigm you like best, MVC, MVP, etc..) is critical. Any project large enough would likely be too unwieldy to go without it. Remember that in production environments, there are often more than one programmer, and sometimes new programmers join the team or existing ones move, so it's not really optional. Most of the efforts of web framework designers are invested in this use case, so functionality which breaks this abstraction is less of a priority.

However, I could see where an internal scala DSL for web development might be useful for small projects. It would certainly not be unwise to invest your time in creating a light-weight framework for such use, if you would find it useful. Chances are, if you created it and found it useful, others might too.

Suggested resources:

Jeremy Bell
In my experience, the line between "view" and "business logic" is more like a gradient. CSS is probably view. A database stored proc is usually logic. But somewhere there's a rule like "Display the user's account balance, unless the account is closed, in which display 'CLOSED'," which is both view and logic. In the case of Lift, the distinction is even more difficult to make, because due to Scala's XML support, it's trivial to output HTML directly from code. So when does HTML go in the template, and when does it go in the code?
Willis Blackburn
This article is kind of a ha-ha-only-serious piece, but I've found it pretty much spot on: http://thedailywtf.com/articles/the-mythical-business-layer.aspx
Willis Blackburn
+1  A: 

Your argument with the powerful XML support works both ways, I think. Because of the powerful XML support, it is possible to define your own tags in the template not only to bind variables but also to do some XML transformations inside your template.

For example, you can define a wrapper tag which takes all inner table nodes and adds odd and even classes to each of the rows. (See this.) Of course, you could do this in your listify (or tabularify) method as well but then you’d lose even more purity.

For simple applications with just a few controllers, I think it is possible to do without templates as is shown by the already quoted step framework. You just say ‘print that list’ and are done. For larger frameworks however, your logic obviously gets more and more complicated. There needs to be a way to tell the application when and where each controller needs to be called. You’re likely to define that in a single XML document – and there it is again, your XML template you wanted to get rid of.
And then, depending on who is going to design the template, you either want to allow code in XML or you want to avoid it. And because of scala’s XML processing ease, you won’t actually miss it that much when you avoid it, for you have other ways to work around it.

Now, the lift XML templates are decidedly non-scala-esque, so there is no direct way to insert scala-logic. Other frameworks might have chosen a different route. But also in lift, I think, you could just create a custom XML tag for your HTML body and then have a function where you deliberately mix scala code with XML stuff to produce your output.

Debilski
I'd probably use Scala's pattern matching to determine what controller to call, not an XML file.
Willis Blackburn
+2  A: 

The short answer is: both.

You don't "have" to use templates even with Lift - you can write views directly in code. Little-documented, but possible.

However, should you try, you will quickly discover that your view code is becoming ugly with layout and styling concerns. If you wish a taste, try replicating, say, the Facebook front page in raw Scala ;).

If more than 2-3 people are working on a project, separation of responsibilities naturally arises. The Model-View-Controller is popular not because the web is a good example of it (it's a really sh*tty example of it), but because it's the best approximation of such a separation of responsibilities - the HTML/CSS/JavaScript are usually not the PHP/Java/Scala people, and both kinds need to be able to be productive independently.

In short, if you wish to write your views in Scala, may I advise figuring out how to do it in Lift - you get generous amounts of other tasty booty for taking the time to learn it. Once you've written perhaps an app or two that way, ask yourself if it was an experience you 'd wish to repeat. :)

My observation is that merely creating a new file for the template doesn't guarantee much separation. Lift templates aren't HTML but rather a different markup language that comes HTML tags with additional tags that are specific to the application in question. The custom tags essentially comprise an API between the template and the back-end code, and the HTML/CSS/JavaScript people would have to know that API. It's the same as the original JSP ideal, where developers create JavaBeans and expose them to the "UI developers." I've never seen that work very well in practice.
Willis Blackburn
Ran out of space, but in conclusion, on every project I've ever worked on, the people actually responsible for delivering the production HTML are developers. The UI designers may do HTML, CSS, and JavaScript, but in the end, developers do the back-end integration. I've never seen a successful project in which the back-end developers and UI designers get together and agree on a set of JavaBeans or custom tags that the developers will implement and the UI designers will use.
Willis Blackburn
Certainly agreed - it's an ugly picture whichever way. However, in absence of external templates separation of concerns is impossible - a non-starter. To your point, I do prefer Wicket's templates to Lift's (they are almost entirely XHTML).