开发者

Rationale for separate HTML template files in Scala webapps?

开发者 https://www.devze.com 2023-01-04 22:35 出处:网络
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

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'r开发者_开发知识库e 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?


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:

  • Programming Scala, Chapter 10: Herding XML in Scala
  • Programming Scala, Chapter 11: Domain-Specific Languages in Scala


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. :)


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消