Templating my Blog with FreeMarker
Part of the fun of shifting my Blog from Blogger to github has been building the static-site-generator tool which reads my blog content as Markdown and spits it out as html + css.
I'm using MarkdownJ to convert the Markdown syntax to HTML, and FreeMarker for templating.
FreeMarker for templating was an easy choice for me:
- It is a decent templating engine that I've used recently for a dynamic website,
- It is very easy to set up in Java for my one-hit templating needs,
- I like its syntax compared to, say, Velocity
Yesterday I used FreeMarker to add two new productions to my site-generator: a sitemap, and an RSS feed, and thought I'd make some quick notes...
FreeMarker strives to be a pure templating language, and as such resists the temptation to ... shall we say, make certain things easy that you probably shouldn't do in a template.
This can make templating a little uncomfortable sometimes - all the more so if you try to use complex domain objects directly in your templates instead of producing model's specifically for output (YMMV depending on the complexity of your domain model of course).
For the simple needs of my Blog FreeMarker has been great, allowing me to whiz up the sitemap template in a couple of minutes, and not much longer for the RSS-2.0 template.
Setting up FreeMarker in Java is very very simple indeed. I chose to abstract FreeMarker away behind my own interface (TemplateProcessor
), in case I want to use something different later:
import java.io.*;
import freemarker.template.*;
public class FreemarkerTemplateProcessor implements TemplateProcessor
{
private Configuration cfg;
public FreemarkerTemplateProcessor(File aTemplateDir)
throws IOException
{
cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(aTemplateDir);
cfg.setObjectWrapper(new DefaultObjectWrapper());
}
@Override
public void process(Object aModel, String aTemplate, Writer aWriter)
throws IOException, TemplateException
{
Template _tpl = cfg.getTemplate(aTemplate);
_tpl.process(aModel, aWriter);
}
}
The templating language is quite neat, and very easy to write - as I mentioned before, it helps if your model is a good fit for the view you are trying to render so you don't need to squeeze to many conditionals into the template.
Freemarker template for sitemap.xml
There are only 3 lines of FreeMarker markup in my sitemap template:
<#list posts as post>
which iterates over anIterable
containingPost
objects,- the closing
</#list>
, and - the line that reads the post's link
<loc>${blog.url}/${post.link}</loc>
Here's the template in full:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>${blog.url}/index.html</loc>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>${blog.url}/about_me.html</loc>
<changefreq>daily</changefreq>
<priority>0.9</priority>
</url>
<#list posts as post>
<url>
<loc>${blog.url}/${post.link}</loc>
<changefreq>hourly</changefreq>
</url>
</#list>
</urlset>
Freemarker template for RSS 2.0
The RSS template is very similar to the sitemap template, as it deals with exactly the same model. Skipping the pre-amble, here's the part that actually involves any freemarker markup:
<#list posts as post>
<item>
<title><![CDATA[${post.title}]]></title>
<link><![CDATA[http://${blog.url}/${post.link}]]></link>
<guid isPermaLink="true">${blog.url}/${post.link}</guid>
<description><![CDATA[${post.body}]]></description>
<#list post.keywords as keyword>
<category>${keyword}</category>
</#list>
<dc:creator><![CDATA[ Steve Liles ]]></dc:creator>
<pubDate>${post.date?string("EEE, dd MMM yyyy HH:mm:ss Z")}</pubDate>
</item>
</#list>
I like the date built-in here: ${post.date?string("EEE, dd MMM yyyy HH:mm:ss Z")}
which keeps the date format in the template where it belongs.
Of course, here I've just written it directly into this template because I only use this format once in my whole site - if I were using it more I could define a re-usable FreeMarker macro instead to avoid repetition.
Comment on this postMost geeky thing I ever saw
There's something fabulously, deliciously geeky about using Curl to call a url-shortening service for url's to the web-management console of an online source-code-control system! Githubber's you ROCK!
curl -i http://git.io -F "url=https://github.com/blog/985-git-io-github-url-shortener" -F "code=geek"
gives:
HTTP/1.1 201 Created
Server: nginx/1.0.4
X-Node: gitio2
X-Sha: 50f8f21981a362dfbaa5fbc85193621e56379dfb
Content-Type: text/html;charset=utf-8
Date: Thu, 10 Nov 2011 23:23:12 GMT
Status: 201 Created
Location: http://git.io/help
X-Runtime: 0.008420
Connection: keep-alive
Content-Length: 0
Comment on this post
Popularity contest - Ubuntu vs OSX Lion vs Win7
A while back I played with Google Trends to compare Linux distribution popularity. Ubuntu was the clear winner.
In that post I also tried to compare OSX and Windows7 against the Linux supremo, but I think I didn't hit on the right search term for OSX.
I tried again today out of curiosity, and I think I got better results, though perhaps still not really reflecting the true state of the world (I'm sure OSX kicks Ubuntu's pants in reality).
ubuntu(blue), windows7(red), OSX Lion(orange)
More at Google Trends.
Comment on this postEclipse code template for GWT jsni methods
GWT JavaScriptObject's and JavaScript Overlays are very cool. I've written about them before. It can get a bit tiresome to write jsni methods though, especially all those fiddly slashes, braces and asterisks at the end!
Here's a simple Eclipse code template that does the hard work for you, and lets you quickly tab-and-type through to completing your jsni method without ever having to type those fiddles again:
public final native ${return_type} ${newName}()/*-{
${cursor}
}-*/;
To add this in Eclipse:
- Open the preferences dialog (Window -> Preferences)
- Type "templates" into the filter box (it should have focus already so you can just start typing)
- Select the bold entry under "Java -> Editor -> Templates"
- In the right hand panel you'll see all the existing templates, and some buttons ... Click "New"
- The "name" is also the shortcut for your new template, so enter "jsni"
- Paste in the template text (copy from the code block above).
- Click ok to return to prefs, and ok again to return to the editor and try it out ...
To use your new template:
- Type "jsni" (without quotes) into a java editor and hit ctrl-space (or whatever your auto-complete shortcut is)
- The first option in the auto-complete suggestions should be your "jsni" template - hit return to use it
- Your template appears, and eclipse focuses the first part (the return type) for you to modify
- Modify each part of the template in turn and press tab to move to the next part
- Enjoy!
Recent releases of the Google Eclipse plugin include some nice jsni features that you definitely don't want to miss out on - including code-completion and syntax highlighting.
Comment on this postWhat makes a good developer?
At the beginning of the year I worked with our Operations Manager in Beirut - Bassel Beaini - to do annual reviews for our whole development (and UX) team there.
As part of the review process we gave the developers an updated job specification, which I wanted to be both prescriptive and aspirational - the idea being to describe the role each should currently be playing, to make very clear what would be needed to move to the next level, and at the same time to make everyone want to up their game and take it to the next level.
The end result, I guess, is my attempt at a technology agnostic description of what makes a good developer. Being a developer myself I'm fairly biased towards the technical aspects of the role and probably tend to somewhat overlook the human side of things (team-work, interaction with other parts of the business incl. non-programmers, etc). I'd love to hear constructive feedback on how I could improve these descriptions for next year :)
Here are the "aspirational" parts of the job descriptions I wrote for the top-tiers - architect/expert and senior developer:
Senior Developer
You are the kind of person who develops software for fun in your spare time - whether personal projects or open-source contributions. You are deeply interested in languages, paradigms, idioms, tools and technologies, and in solving difficult problems.
You take great pride in your work, and it shows clearly in the way your code speaks to others - simple, clean, thoroughly unit-tested and easily understood and maintained. You are able to recognize and fix many code-smells and can gently point them out to your less experienced colleagues during code-review. You are keen to develop your skills further through interaction with your colleagues - junior and senior - and by consistently executing any task, large or small, with the attitude that there is always something new to learn. You can quickly identify and fix problems from minimal descriptions.
You are accomplished at taking high level designs and specifications from Architects and implementing them successfully, including creating and assigning suitable sub-tasks to less advanced members of your team. You can articulately explain the reasons behind micro-architectural choices you make during implementation, and evaluate the pros and cons of such decisions.
You will have excellent understanding and wider knowledge of development tools and processes, and be able to clearly explain, demonstrate, and teach their usage to others, especially those junior to yourself who may have little or no prior experience. You will be so confident with and reliant upon these tools that you use them even for your personal projects, knowing that the benefits are well worth the extra up-front effort.
You will set an excellent example of engineering discipline to your peers and junior colleagues, and you understand and truly believe in the need for engineering discipline and processes in delivering high quality software. Your attitude toward any task is to produce the best solution you can and learn from the experience. You will actively seek feedback on your solutions from peers and senior colleagues, whether by code-review or less formal discussion.
Architect/Expert Developer
A passionate technologist, you demonstrate excitement, deep interest and knowledge of all aspects of development: languages; paradigms; patterns; idioms; platforms; performance; reliability; scalability; quality; tools and technologies. You relish the challenge of hugely complex problems.
Possessing true mastery of at least one modern programming language and paradigm, along with advanced knowledge of idioms and Design Patterns and when (or when not) to apply them, you will be able to recognize opportunities to improve code at a glance, and have the confidence and competence to take these opportunities to refactor towards better design.
You must be able to explain at length the reasons behind (micro)architectural decisions you make - or help others to make - so that others may learn from you. Your code has a finesse and indescribable quality that is the envy of all who read and work with it. You have exceptional ability to narrow down potential sources of a problem, home in on the root-cause, and propose a range of solutions and explain their pros and cons.
Your architectural skills allow you both to describe designs at a high level to the business, and also to home in on the complexities and details that allow a design to be implemented successfully. You are able to interpret and translate abstract ideas from more business oriented colleagues and customers, and from those ideas produce designs and specifications for developers to implement. You will be able to identify and separate the real requirements from the incidental details that inevitably form part of such brain-storming or business driven interaction.
You will have excellent understanding and wider knowledge of development tools and processes, and be able to clearly explain, demonstrate, and teach their usage to others, especially those junior to yourself who may have no prior experience. You will be aware of facets of these tools and processes that are not in daily use, such that you will be able to turn these tools even more to your advantage in specific situations. You will be constantly looking for new ways to streamline your working practices and those of the team through use of new and existing tools and technologies.
As one of the most senior members of the development team you will set an excellent example of engineering discipline to your colleagues, and will be passionate about achieving the very best quality and helping those around you to do so. You will recognize and evangelize the benefits of engineering disciplines such as source-code control, unit-testing, and code-review, and have a very self-critical view of what constitutes "done".
You will delight in tackling a range of tasks, recognizing the pleasure to be found in a polished solution to the smallest problem, as well as the challenges of a more significant undertaking, and you will enjoy mentoring and engaging in discussion about all aspects of development with your colleagues.
Join us...
If you're in Beirut, are a serious Java or Objective-C hacker, and would like to work with us, drop a comment, contact me or Bassel via linked-in, or tweet me (@steveliles)
Comment on this post