#Getting started with journo
##Introduction
Recently I've been moving most of my JavaScript development to CoffeeScript, a language that compiles to JavaScript and contains many modern programming idioms. I have welcomed CoffeeScript into my workflows as a way to script with greater clarity and thank Jeremy Ashkenas for sharing his work with the community.
I recently read a post on HN about a feature in CoffeeScript I had yet to use: the ability to code in a literate manner. Literate CoffeeScript connects the documentation and script into a single document that can be executed or read by a human. There are few ways to implement documentation as elegant and intuitive as the literate approach.
To provide a unique example of how this could be useful Jeremy shared the journo blog engine. It is a static site generator that uses Markdown and Underscore.js for posts and templating. It is extremely minimalistic.
##Setting up the environment
At the time of writing I am using Mac OS X 10.8.2 with homebrew installed. Getting everything installed is really easy thanks to the Node Package Manager (npm).
In a bash terminal:
brew install node
sudo npm install -g journo coffee-script
The Node Package Manager will resolve the dependencies for you:
journo@0.0.1 /usr/local/share/npm/lib/node_modules/journo
├── mime@1.2.9
├── marked@0.2.8
├── underscore@1.4.4
├── highlight@0.2.3
└── rss@0.0.4 (xml@0.0.7)
Then, to access these new tools more easily I placed them into my path.
export PATH=$PATH:/usr/local/share/npm/bin
You should now be able to run the CoffeeScript REPL terminal by executing coffee
in a terminal:
coffee> 'Hello World'
'Hello World'
Now that you have Node.js, CoffeeScript, and journo installed, you can begin to put together a blog.
##Bootstrapping a journo blog
At this point I encourage you to read the source for journo. Although this may sound menacing, given that it is written in Literal CoffeeScript it is entirely readable.
journo init
mv bootstrap blog
cd blog
touch layout.html
journo
If you are on a Mac your default browser will probably have opened to a blank page at http://localhost:1234
. This is because our template is empty, but as you can see journo is running its own http server ideal for testing on your local machine.
When initializing the blog it provides some default configuration, but not a default layout. Using layout.html
journo wraps posts and pages so they can be themed and formatted. The template is written in HTML/CSS with Underscore.js tags for placing content.
##Example layout
journo is an extremely lightweight static blog generator. It doesn't come with themes, or even the most simple layout. Here is a layout that will give you a starting point.
layout.html
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>My Blog | <% print("\<\% title \%\>") %></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
</head>
<body>
<% print("\<\% content \%\>") %>
<hr>
<footer>
<% print("\<\% _.each(posts, function(p){ \%\>") %>
<li><a href="<% print("\<\%= postName(p) \%\>") %>"><% print("\<\%= manifest[p].title \%\>") %></a></li>
<% print("\<\% }); \%\>") %>
</footer>
</body>
</html>
Aside: in the above snippet you see Underscore template tags. In order for these to appear properly they must be escaped, this is how it appears in the Markdown entry.
<% print("\<\% print(\"\\<\\% title \\%\\>\")") %>
This quickly becomes an escape character nightmare, as to cause this snippet to appear properly another layer of escape characters are put in. Underscore.js provides methods for customizing the escape characters and template tags, I'm interested in a more elegant solution if you have one.
##Start blogging!
You can now start writing markdown and placing it in the posts directory. Again, please do read through the journo source as an example of Literate CoffeeScript. In a future post I hope to add pagination.
Thanks for doing this! I've just got one question. What should the output of these steps using the example template be? Cause it seems like the underscore tags are showing as literals in mine: http://cl.ly/image/2Q2U3K3l1E3q