Integrating HTML5 Boilerplate with Scalate and Play
HTML5 Boilerplate is a project that provides a number of basic files to help you build an HTML5 application. At its core, it's an HTML template that puts CSS at the top, JavaScript at the bottom, installs Chrome Frame for IE6 users and leverages Modernizr for legacy browser support. It also includes jQuery with the download. One of the major benefits of HTML5 Boilerplate is it ships with a build system (powered by Ant) that concatenates and minimizes CSS and JS for maximum performance. From html5boilerplate.com:
Boilerplate is not a framework, nor does it prescribe any philosophy of development, it's just got some tricks to get your project off the ground quickly and right-footed.
I like the idea of its build system to minify and gzip, but I'd probably only use it if I was working on a project that uses Ant. Since I'm using it in a Play project, the whole Ant build system doesn't help me. Besides, I prefer something like wro4j. Wro4j allows you to specify a group of files and then it compiles, minimizes and gzips them all on-the-fly. As far as I know, Play doesn't have any support for Servlet Filters, so using wro4j in Play is not trivial.
The good news is Play has a GreenScript module that contains much of the wro4j functionality. However, since I'm using Scalate in my project, this goodness is unavailable to me. In the future, the Scalate Team is considering adding better wro4j, JavaScript and CSS integration. In the meantime, I'm going to pretend I don't care about concatenation and minimization and trundle along without this feature.
To add HTML5 Boilerplate to my Play project, I performed the following steps:
- Downloaded the 2.0 Zipball.
- Copied all the static files to my project. Below are the commands I used (where $boilerplate-download is the expanded download directory and ~/dev/play-more is my project):
cd $boilerplate-download cp 404.html ~/dev/play-more/app/views/errors/404.html cp *.png ~/dev/play-more/public/. cp crossdomain.xml ~/dev/play-more/public/. cp -r css ~/dev/play-more/public/stylesheets/. cp favicon.ico ~/dev/play-more/public/. cp humans.txt ~/dev/play-more/public/. cp -r js/libs ~/dev/play-more/public/javascripts/. cp robots.txt ~/dev/play-more/public/.
- Copied the index.html to ~/dev/play-more/app/templates/layouts/default.jade and modified it to use Jade syntax. Since I downloaded the comments-heavy version, I modified many of them to be hidden in the final output.
-@ val body: String -@ var title: String = "Play More" -@ var header: String = "" -@ var footer: String = "" !!! 5 / paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]--> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> -# Consider adding an manifest.appcache: h5bp.com/d/Offline <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> head meta(charset="utf-8") -# Use the .htaccess and remove these lines to avoid edge case issues. More info: h5bp.com/b/378 meta(http-equiv="X-UA-Compatible" content="IE=edge,chrome=1") title=title meta(name="description" content="") meta(name="author" content="Matt Raible ~ [email protected]") -# Mobile viewport optimized: j.mp/bplateviewport meta(name="viewport" content="width=device-width,initial-scale=1") -# Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -# CSS: implied media=all link(rel="stylesheet" href={uri("/public/stylesheets/style.css")}) -# end CSS -# More ideas for your <head> here: h5bp.com/d/head-Tips -# All JavaScript at the bottom, except for Modernizr / Respond. Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries For optimal performance, use a custom Modernizr build: www.modernizr.com/download/ script(type="text/javascript" src={uri("/public/javascripts/libs/modernizr-2.0.6.min.js")}) body #container header = header #main(role="main") != body footer = footer -# JavaScript at the bottom for fast page loading / Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline script(type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js") :javascript window.jQuery || document.write('<script src={uri("/public/javascripts/libs/jquery-1.6.2.min.js")}><\/script>') -# Change UA-XXXXX-X to be your site's ID :javascript window._gaq = [['_setAccount','UA-25859875-1'],['_trackPageview'],['_trackPageLoadTime']]; Modernizr.load({ load: ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js' }); -# Prompt IE 6 users to install Chrome Frame. Remove this if you want to support IE 6. -# http://chromium.org/developers/how-tos/chrome-frame-getting-started /[if lt IE 7] script(src="//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js") :javascript window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'})}) != "</html>"
- Next, I had to add support for layouts to my homegrown Scalate support. I did this by specifying a
layoutStrategy
when initializing the TemplateEngine. From play-more/app/controllers/ScalateTemplate.scala:engine.classLoader = Play.classloader engine.layoutStrategy = new DefaultLayoutStrategy(engine, Play.getFile("/app/templates/layouts/default" + scalateType).getAbsolutePath) engine
That's it! Now I have HTML5 Boilerplate integrated into my Play/Scalate/Jade application. To set the title and header in my index.jade, I simply added the following lines at the top:
- attributes("title") = "Counting" - attributes("header") = "HTML5 Rocks!"
CoffeeScript Tip
Yesterday, I mentioned that I was having issues getting CoffeeScript to work with Scalate and that I was going to try and get the in-browser compiler working. First of all, reverting to Scalate 1.4.1 didn't work because there is no CoffeeScript support in 1.4.1. So I stayed with 1.5.2 and used PandaWood's Running CoffeeScript In-Browser Tutorial. I copied coffee-script.js to ~/dev/play-more/public/javascripts/libs and added a reference to it in my default.jade layout:
-# JavaScript at the bottom for fast page loading script(type="text/javascript" src={uri("/public/javascripts/libs/coffee-script.js")})
Then I was able to write CoffeeScript in a .jade template using the following syntax:
:plain <script type="text/coffeescript"> alert "hello world" </script>
Summary
If you've integrated HTML5 Boilerplate into your Play application, I'd love to hear about it. Now that I have all the infrastructure in place (Jade, CoffeeScript, HTML5 Boilerplate), I'm looking forward to getting some development done. Who knows, maybe I'll even come up with my own Play Un-Features That Really Irk My Inner Geek.