I cut my teeth as a web developer building dynamic web sites, but more and more lately I'm finding that I don't need to do as much on the server. In fact, in some cases I don't need a back end server at all. Today I decided to take a stab at converting a dynamic web site to static using the Harp framework.
Harp is a lightweight web server with built in processors for multiple different languages (Markdown, Jade, EJS, LESS, Stylus, and CoffeeScript). It follows a simple convention that makes it easy to layout a simple web site. After installing you can get up and running in seconds. You should definitely check out the documentation yourself (but note - I saw some layout issues in Chrome so you may want to use Firefox instead).
But the real killer feature though is that once you've built your site, you can convert the entire thing into a static version with one command.
You may ask - why would you even bother? If I'm building a simple 3-4 page site, what is the benefit?
I went through this myself a few months ago when I built a site for a family friend. She is an artist (http://louisianawatercolors.com/) and basically needed a quick web site she could use to showcase some work and add contact information. I picked up a web site template and everything was cool until I realized I needed to make a few tweaks to the template. This was after I had built out the site. It certainly wasn't a big deal, I just edited 5 files, but where Harp shines is that I could have done this in one layout file and simply generated a new build at once.
For my experiment, I decided to rebuild my oldest (still living) web site, What the Thunder Said. This is a site I built in 1996 (yes, they had the Internet back then) as a class project. The HTML is horrible. Now, horrible is a bit too nice. If you view source you'll see tables, font tags, and, I'm sorry to say, tags in all caps. I'm sorry. But I also thought it would be a perfect candidate for conversion.
The ColdFusion version of the site was "dynamic", but only minimally so. I used a ColdFusion template for layout. On top of that there was a contact form and forums. No one used the forums or the contact form in the past five years so I decided they could go away. Therefore the only real work I had to do was build out my layout. Let's take a look at the code. (And disclaimer - this is my first Harp site - I probably did it wrong.)
First - I decided to go with EJS for my templating. EJS is ok, not as good as Handlebars, but I absolutely loathe Jade and Harp doesn't support Handlebars yet. (Although it is coming soon apparently.) Using EJS, I could build a simple template like so.
<html>
<head>
<meta name="robots" content="index,follow" />
<meta name="title" content="<%- title %>"/>
<meta name="Description" content="What the Thunder Said is a site devoted to the life and works of T.S. Eliot.">
<meta name="Keywords" content="t.s. eliot,eliot,T.S. Eliot,poetry,fiction,what the thunder said,thunder,waste land">
<link rel="stylesheet" type="text/css" href="/style.css">
<title><%- title %></title>
</head>
<body bgcolor="#ac9581" text="#000000" link="#490000" vlink="#490000">
<%- yield %>
</body>
</html>
Note - this is a somewhat simpler version of the real template file. In the template, you can see a few tokens. The title value is one, and yield is another. The yield value will be replaced with the HTML of the file being requested. What this means is that I can write an about page and just drop in the content specific to that page.
So while it's obvious where the body comes from for a template, what about that title field? In my ColdFusion application, each page passed this as an argument to a layout helper. In Harp, you use a _data.json file to specify values like this. Here is how I did it for my site.
{
"index": {
"title":"What the Thunder Said: T.S. Eliot"
},
"eliot_timeline": {
"title":"What the Thunder Said: Timeline of T.S. Eliot",
"header":"timeline"
},
"poetry_works": {
"title":"Works by T.S. Eliot",
"header":"works"
},
"literature_resources": {
"title":"Resources on T.S. Eliot",
"header":"res"
},
"eliot_etcetera": {
"title":"Etcetera",
"header":"etc"
},
"poetry_feedback":{
"title":"Feedback",
"header":"feedback"
},
"404":{
"title":"File not found",
"header":"etc"
}
}
In case you are curious, the header value is used by my real layout template to handle changing out the header graphic.
Once I built out the files (and finished shaking my head at how bad my HTML was back then), I then dropped to the command line:
harp compile
And that's it. Seriously. It parsed my project and spit out pure HTML. Here is the folder for my project. The public folder is where I did my work, and the www folder is the static output.
If I opened up index.html, I saw the combination of my layout file along with the contents of index.ejs. Ditto for my other files as well. And just to drive the point home - if I find a mistake in my layout (outside of the horrible HTML) - I can edit the file - rebuild my static site - and I'm done.
So - the final aspect of this journey was even cooler. Greg Wilson has been telling me for ages to look into static web site hosting with Amazon S3. Turns out - Amazon's free tier allows for an incredible 20000 requests per month for free. That's insane! It is definitely more than I'd need for this site.
If you haven't seen it, Amazon makes the process pretty gentle for creating a web site out of a S3 bucket. You begin in the properties:
Next, you need to add a bucket policy. This part is pretty confusing. But I found I could copy the XML from here (http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html) and just change the bucket name and it worked fine.
The final step of the process was a few quick domain/DNS updates at GoDaddy (and thanks again to Greg for the help) and that was it. The first change is a CNAME for the www prefix. That's pretty simple. The next one wasn't so obvious. (Again, thanks to Greg.) In order for foo.com to also work, add a Forwarding rule:
I've gone from a hosted solution running with Apache and ColdFusion to a completely static solution on S3... for no price. Even better, I still have the power of a dynamic application for generating my files. A win all around I'd say.
p.s. As an aside, I just noticed that my titles aren't consistent. It took me about 20 seconds to correct and push to production.
Archived Comments
Introduction to Harp Web Server
https://www.youtube.com/wat...
Very cool
Thanks for sharing that Edward. I wanted to add - if anyone wants a copy of the site, let me know and I'll add it as an attachment.
This feels a lot like nodeJS.
Steve, Harp does run with Node. You don't have to know Node at all though. Or heck, any programming, outside of the template language of your choice.
Static site generation FTW. (Useless comment, I know :p)
Great post, Ray. Harp is new to me, but I'll certainly be checking it out. My initial thought was hoping that it works with Heroku... turns out it does! -> http://harpjs.com/docs/depl...
Ray Camden moves away from Coldfusion, news at 11
@Matt: Cool. I hope it was clear that you could run Harp as is too - as a dynamic app - and it still is cool as it is so easy to use. You don't *have* to convert it.
@matt: I'm not moving away from CF. This was a case where it wasn't necessary.
As a quick tip, I ran into an issue with CSS today with another site I moved to S3. I have no idea why whatthethundersaid.org wasn't impacted, but it seems like a good tip in general:
http://log.adamwilcox.org/2...
Hi Ray
Amen!
I've become a convert to static websites for various use cases. I converted my blog, which went from Blogcfc, to Wordpress to static, using Jekyll. Feels fresh and clean from a nerdy point of view, loads fast, no server software concerns etc etc.
I'm trying to convince some business clients to do likewise for their corporate sites, and to leverage Amazon CloudFront (or similar) to provide a snappy, global epxerience
Hey Raymond, glad you found my CSS tip useful.
I'm confused. According to http://harpjs.com/docs/envi... you do need node.js
So what did you actually do with this example? Install harp locally which needs you to install node, then compile the source to static pages, then upload to s3?
I don't get any advantage over plain HTML files. If I create a 5 page static site I will start with my template (page 1), copy it 4 times and paste in my content. You would have to go in each file anyways to make changes anyways as the header and content info are different. So what's the purpose? Just to have a dynamic layout? On a small site it will hardly ever change. If anything regular HTML files would be better as I could have a twitter feed box on the right side of one page and a left column box on another page. Using harp I assume that I would need different layouts or some programmatic way to say "On this page, include this). Certainly doesn't sound any quicker as I can make text changes in two HTML files in about 15 seconds
I hope I'm just clueless and you can explain to me the benefit that I didn't understand from your post.
papi, read what I said carefully:
"Steve, Harp does run with Node. You don't have to know Node at all though."
You don't have to know how to use Node. Please see their Getting Started guide and you will see.
"So what did you actually do with this example? Install harp locally which needs you to install node, then compile the source to static pages, then upload to s3?"
I already had Node installed, so I just installed Harp. I then built my site. When I was done, I then converted it to static and uploaded to S3.
"I don't get any advantage over plain HTML files. If I create a 5 page static site I will start with my template (page 1), copy it 4 times and paste in my content"
Copy it 4 times. Why? I'd rather have one template file. Here is a question - what happens when you find a typo in your template? What happens when you want to add something to the footer? In a 5 page site it isn't a horribly big deal, but it IS something you could possibly screw up.
"You would have to go in each file anyways to make changes anyways as the header and content info are different. "
Not with Harp using one layout file. (And to be clear, Harp supports multiple layout files.
The thing is - even with it being simple to update 5 files, I don't want to. I'd rather update one file. I'm more inclined to play with my layout. Try new things. Etc. I wouldn't be that inclined with a pure HTML site.
Harp gives me the flexibility of a dynamic site locally while moving to static when done. To me it is an obvious win.
GitHub Pages is also a great place to host static pages for free; without the monthly limit or the surprise bill on your 13th month at AWS (the free tier is only valid for a year I believe).
Michael, thanks for that warning. Here is the FAQ:
http://aws.amazon.com/free/...
I'm not too concerned - but I'll let folks know. I've got 2 sites there now.
Btw - someone remind me to post my cost on Dec 1. :) So far I have 5 cents. Last month it was 8 cents. So in one day I'm almost half there.... but I found I had some demo assets for ColdFusion stuff that apparently I had forgotten about and they were still getting traffic. So I killed them all. 5 cents a day is still less than 2 bucks a month so I'm fine with it.