[2.x Scala] Announcing ScalaTags: HTML Generation in Scala

621 views
Skip to first unread message

Haoyi Li

unread,
Apr 22, 2013, 9:28:38 AM4/22/13
to play-fr...@googlegroups.com
Hey all,

I'm cross-posting this from the scala-user mailing list, because someone mentioned that some people here may be interested.

ScalaTags is a library I made to generate HTML programmatically. It basically gives you a nice nested-varargs syntax for generating HTML:

val title = "title"
val numVisitors = 1023

val frag = html(
    head(
        script("some script")
    ),
    body(
        h1("This is my ", title),
        div(
            p("This is my first paragraph"),
            p("you are the ", numVisitors, "th visitor!")
        )
    )
)
 which means it

- is way less verbose than normal HTML
- can sit right in your .scala files with everything else
- gets all sorts of things for free: variables, loops, if-elses, functions, template inheritence. It's just Scala
- gets free syntax highlighting/code completion in Eclipse/IntelliJ too!
- XSS free, oops-i-forgot-my-closing-tag free, typo-in-closing-tag-name-free. It generally ensures you have well-formed XML

So far I've used it in 3-4 different projects, with barely any changes to the library itself, after maybe 4000 lines of HTML written in it. I think it's pretty slick, and hope someone else can find a use for it or give me feedback =)

Thanks!
-Haoyi

James Ward

unread,
Apr 22, 2013, 9:32:10 AM4/22/13
to play-fr...@googlegroups.com
This is cool! Are you planning to do a release to Maven Central? That
would be nice.

-James


On 04/22/2013 07:28 AM, Haoyi Li wrote:
> Hey all,
>
> I'm cross-posting this from the scala-user mailing list, because someone
> mentioned that some people here may be interested.
>
> ScalaTags <https://github.com/lihaoyi/scalatags> is a library I made to
> --
> You received this message because you are subscribed to the Google
> Groups "play-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to play-framewor...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Haoyi Li

unread,
Apr 22, 2013, 9:33:43 AM4/22/13
to play-fr...@googlegroups.com
Yeah, I'm planning on putting it up there once I have some time =) I understand it would be way easier to get started with once it's up there, but I really haven't had the chance to do so. Soon!

Thanks!
-Haoyi



For more options, visit https://groups.google.com/groups/opt_out.


--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.

Jason Pearson

unread,
Apr 22, 2013, 9:52:35 AM4/22/13
to play-fr...@googlegroups.com

Nice work!

Have you thought of allowing syntax of other templating languages? Jade springs to mind as probably one of the easiest to do in Scala.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Jan Eriksson

unread,
Apr 22, 2013, 9:57:56 AM4/22/13
to play-fr...@googlegroups.com
Looks really interesting! I will try it out for sure :)

Haoyi Li

unread,
Apr 22, 2013, 10:14:01 AM4/22/13
to play-fr...@googlegroups.com
@Jason: ScalaTags is an internal DSL, so you don't need a special template parser or template files: the HTML fragments are just scala expressions, which makes handling them way easier. No need for a special template file, with a special way of defining arguments or inheritence, or a special preprocessor (a.l.a. Play/Twirl). The examples are all scala source code! You can copy&paste them into the scala REPL and they should just work.

Given that, Jade looks like it'd be impossible to shoehorn into scala syntax. You could probably do something clever with the new string interpolation macros, but that would be deviating from the spirit of ScalaTags back into classic-templating land.


--

virtualeyes

unread,
Apr 22, 2013, 12:33:21 PM4/22/13
to play-fr...@googlegroups.com
It is nice work indeed, but can we use this along with built-in Play template engine?

Would be nice to retain the useful features of Play's template engine (form generation in particular), while doing the same with ScalaTags (in-place variable declaration, code completion, etc.)

Jason Pearson

unread,
Apr 22, 2013, 12:48:15 PM4/22/13
to play-fr...@googlegroups.com

I realized it is an internal DSL, I was just wondering given what you've been able to do how hard it would be to do other templates' syntax, purely in the interest of being able to easily port over views from existing code.  And yeah it wouldn't be the same at all :/

Haoyi Li

unread,
Apr 25, 2013, 9:39:11 PM4/25/13
to play-fr...@googlegroups.com
Just as an update, ScalaTags 0.1.1 is now available on Maven Central: http://search.maven.org/#artifactdetails%7Ccom.scalatags%7Cscalatags_2.10%7C0.1.1%7Cjar

The readme has been updated to reflect this: https://github.com/lihaoyi/scalatags

With the magic sbt incantation being:

libraryDependencies += "com.scalatags" % "scalatags_2.10" % "0.1.1"

Should be able to just add that to your build file, fire up a `sbt console` and have ScalaTags work instantly. Any feedback is welcome =)

Grant Beaty

unread,
Apr 26, 2013, 12:57:17 PM4/26/13
to play-fr...@googlegroups.com
Awesome! I kept meaning to do something like this but haven't found the time.

Related question: anyone know if play2 devs are planning to release an immutable Html class?

/Grant

Haoyi Li

unread,
Apr 26, 2013, 1:09:28 PM4/26/13
to play-fr...@googlegroups.com
>Related question: anyone know if play2 devs are planning to release an immutable Html class?
 
I don't have an answer, but I'll chip in and say that *any* replacement XML library would be double-plus-one-awesome; perhaps we could adopt/bless ScalesXML or AntiXML and bring I up to production quality. Working with the default XML library, even for something as simple as converting my trees to XML trees to strings, is a complete headache.


--

picoly

unread,
Jun 9, 2013, 5:41:10 AM6/9/13
to play-fr...@googlegroups.com
Unsure of how to use ScalaTag in PlayFramework. To place the code in Application.scala or Scala template?

I had created this code:
val frag = html( ... )

Dave Sugden

unread,
Sep 10, 2013, 7:09:20 PM9/10/13
to play-fr...@googlegroups.com
I'm really loving this dsl. Using it in several projects now. Thanks for this

 

Byron Weber Becker

unread,
Dec 22, 2013, 7:34:34 AM12/22/13
to play-fr...@googlegroups.com
I've used scalatags for several non-Play projects and really liked it.  I'd love to use it for my Play app as well, but am getting hung up on forms.  I started defining some implicit conversions between scalatags and Play's Html type, but am becoming uneasy with that approach (one is a tree, the other is just a string -- lots of information loss).

Has anyone used scalatags with Play?  How did you handle forms?

Julien Richard-Foy

unread,
Dec 22, 2013, 7:03:02 PM12/22/13
to play-fr...@googlegroups.com
Why do you need to use Play templates if you want to use scalatags?


On Sun, Dec 22, 2013 at 1:34 PM, Byron Weber Becker <bwbe...@uwaterloo.ca> wrote:
I've used scalatags for several non-Play projects and really liked it.  I'd love to use it for my Play app as well, but am getting hung up on forms.  I started defining some implicit conversions between scalatags and Play's Html type, but am becoming uneasy with that approach (one is a tree, the other is just a string -- lots of information loss).

Has anyone used scalatags with Play?  How did you handle forms?

Haoyi Li

unread,
Dec 23, 2013, 1:01:24 AM12/23/13
to play-fr...@googlegroups.com
How did you handle forms?

Play Forms are basically a play termplate only thing, and HTML has existed long before play templates. With ScalaTags, you basically do all your form wiring/etc. the old way just with plain HTML. You can use standard things like functions and classes to modularize/re-use your common form code so you don't need to keep repeating it everywhere, but there's no magic "form" library.

That's not to say that there can't be one; eventually all your modularized/reusable common form code will probably end up looking something like the play form library, and maybe it would be nice if there wasn't a compatibility layer or shared API or something. But I'm not using ScalaTags for anything at the moment, and nobody's come up to me with suggestions on how such a thing would look, so it hasn't happened =)

Byron Weber Becker

unread,
Dec 23, 2013, 8:13:14 AM12/23/13
to play-fr...@googlegroups.com
Haoyi, Julien -- Thanks for your responses to my question about using ScalaTags with Play.

The underlying issue is that Play provides infrastructure for dealing with forms, validation in particular (the stuff in play.api.data_).  I'd rather not lose that infrastructure just because I want to render my pages using ScalaTags rather than Play's functions in views.html.helper{form, inputText, inputPassword, textarea, etc}.  

To continue to use the forms infrastructure, I need to take a field from the Form[...] data structure -- complete with its error information, for example -- and render it.  

Options I've thought about:

(1)  Render it by hand each time (yuck!)
(2)  Figure out some way to interoperate with the code in views.html.helper._  (hence my reference to implicits in the original post)
(3)  Translate the relevant parts of the Play library into equivalent functions that use ScalaTags
(4)  Come up with my own set of functions (the logical conclusion of (1))
(5)  Come up with an entirely new forms handling/validation architecture to replace play.api.data._

So my questions, stated in different terms, are:
-- Are the options I've overlooked?
-- If you've used ScalaTags with Play's form infrastructure, which option did you use?  How did it work out?  Any code you would be willing to share?

My thoughts at this point are leaning towards either (3) or (4).  The attraction of (3) is that the design work has already been done.  However, (3) has always felt over-engineered to me and as a result hard to understand and use.  That's what would drive me towards (4).

Byron

Julien Richard-Foy

unread,
Dec 23, 2013, 8:46:40 AM12/23/13
to play-fr...@googlegroups.com
You can reuse play.api.data._ but you have to rewrite the views.html.helper._ part using scalatags. Hopefully there is just a bunch of few functions.

Haoyi Li

unread,
Dec 23, 2013, 11:44:46 AM12/23/13
to play-fr...@googlegroups.com
> -- Are the options I've overlooked?
> -- If you've used ScalaTags with Play's form infrastructure, which option did you use?  How did it work out?  Any code you would be willing to share?

I haven't used the play forms API extensively myself, so I'm afraid I have no existing code to share =( You have not overlooked anything; there isn't any hidden functionality anywhere. On the other hand, I think #4 seems the most likely. I'd wager that despite it's apparently complexity, re-writing the HTML handling part of play forms using scalatags isn't going to be all that much code, maybe a couple 100 lines. Definitely worth a shot to sit down for a few hours to come up with an elegant wrapping, rather than making ad-hoc conversions here and there




jilen nil

unread,
Jan 27, 2014, 2:48:43 AM1/27/14
to play-fr...@googlegroups.com
It seems perfect for spray app to render some simple html page.
Reply all
Reply to author
Forward
0 new messages