<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://www.h3rald.com/</id>
  <title>H3RALD - Articles (Atom Feed)</title>
  <updated>2010-01-22T14:40:36Z</updated>
  <link href="http://www.h3rald.com" rel="alternate"/>
  <link href="http://www.h3rald.com/atom/" rel="self"/>
  <author>
    <name>Fabio Cevasco</name>
    <uri>http://www.h3rald.com</uri>
  </author>
  <entry>
    <id>tag:www.h3rald.com,2010-01-22:/articles/refactoring-ruby-edition-review/</id>
    <title>Book Review: Refactoring - Ruby Edition</title>
    <published>2010-01-22T14:40:36Z</published>
    <updated>2010-01-22T18:02:06Z</updated>
    <link href="http://www.h3rald.com/articles/refactoring-ruby-edition-review/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="books" scheme="http://www.h3rald.com/tags/books/"/>
    <category term="review" scheme="http://www.h3rald.com/tags/review/"/>
    <content type="html">
<![CDATA[
<p>Refactoring, like testing, is an activity that should be very familiar to all programmers, especially Rubyists. Actually, programs written in Ruby don&#8217;t need as many refactorings as, say, Java programs. However Rubyists are traditionally more <span class="caps">TDD</span> oriented and they like writing clear and elegant code.</p>
<p><a href="http://www.informit.com/store/product.aspx?isbn=0321603508">Refactoring: Ruby Edition</a> is actually a rewrite of the more revolutionary &#8212; at the time &#8212; <a href="http://www.informit.com/store/product.aspx?isbn=0201485672">Refactoring: Improving the Design of Existing Code</a>, written by Martin Fowler &amp; others to teach Java programmers about refactoring. Jay Fields and others decided to <em>port</em> this historical title to Ruby to fill a gap: there was no authoritative book about refactoring for this language, so what&#8217;s better than translating the Bible on the subject?</p>
<p>If you already own the Java book you shouldn&#8217;t buy this one. This is not my personal opinion (I never read the original), it&#8217;s actually written in the Preface of the book itself. I really like honest authors, and luckily this seems to have become a trend, lately: programmers don&#8217;t like reading bullshit after all. By the authors&#8217; own admission, this book contains roughly the same material and the same examples of the original Java book, plus some slightly more Ruby-specific content.</p>
<h3>Getting started</h3>
<p style="float:right;"><img src="/img/pictures/refactoring-ruby-ed.jpg" alt="" /></p>
<p>The first chapter, <em>Refactoring, a first example</em>, is not a first chapter. Well, it is in a literal sense, but it doesn&#8217;t look like one: no theory, no padding, you&#8217;re immediately thrown in the middle of the battle, dealing with a small program in desperate need of refactoring. It literally contains quite a lot of code: the same program is rewritten over and over with changes in bold to teach you what refactoring means. The most intimidating thing is reading names of refactoring techniques capitalized and used in a natural way, like if the reader was supposed to know them already. In all fairness though, they are self-explanatory most of the time, e.g. <em>Replace Array with Object</em>.</p>
<p>What makes this chapter even more unusual is the clever usage of white space: <em>before</em> and <em>after</em> code snippets are shown on separate page, which makes it much more immediate to see the changes in code (but it won&#8217;t work very well if you bought the ebook instead of the hardback).</p>
<p>By contrast, the second chapter <em>Principles in Refactoring</em> is all about theory: it should have been the first chapter, but it&#8217;s better this way. Here you&#8217;ll learn the basics: a bit of history, when to refactor and when not to, and so on. I bet it was taken almost verbatim from the Java book; see for example: <em>&#8220;[&#8230;] If your building APIs for outsid consumption, as <strong>Sun</strong> does [&#8230;]&#8221;</em>.</p>
<p>Chapter 3, <em>Bad Smells in Code</em>, is probably the most important and useful chapter in the entire book. It&#8217;s somethig you should read over and over until you can spot a code smell right after coding.</p>
<blockquote>
<p>&#8220;You should use this chapter and the table on the inside back cover as a way to give you inspiration whn you&#8217;re not sure what refactorings to do.&#8221;</p>
</blockquote>
<p>Precisely what you have to do. Except that there is no table on the inside back cover, so I guess <a href="http://docs.google.com/viewer?url=http://www.industriallogic.com/papers/smellstorefactorings.pdf">this one</a> will have to do. Pity.</p>
<p>Chapter 4, <em>Building Tests</em>, is the usual, compulsory chapter about unit testing, i.e. the usual intro to Test::Unit. As I said, it&#8217;s essential for the book to make sense, but you can safely skip it if you know how to test already.</p>
<p>Finally, chapter 5 (<em>Toward a Catalog of Refactoring</em>) is a 2.5 page intro to the bulk of the book, nothing more than glue to ease the transition. I would have removed it completely, but that&#8217;s because I&#8217;m a merciless technical writer I guess.</p>
<h3>Diving in</h3>
<p>From chapter 6 onwards, specific refactoring techniques are described. Each chapter starts with a brief overview of the following sections (which should have been a list, but I&#8217;m just being pedantic now), so you know what to expect.</p>
<p>Each technique described has a very meaningful and immediate name that reflects its purpose, like Extract Method or Split Temporary Variable. A code example introduces the code smell and the proposed refactoring, followed by a <em>Mechanics</em> section with a list of actions to perform and an explanatory <em>Motivation</em> section.</p>
<p>Tipically, each refactoring has its own, self-contained code snippets. Depending on the complexity of the refactoring technique examined, the authors may spend half to five or six pages just to show all code iterations to get to the result. When things get too complicated, <span class="caps">UML</span> diagrams are used to make the technique easier to understand, but only when it&#8217;s strictly necessary.</p>
<p>Even if the original techniques were though for Java, the authors (in particlar Jay Fields, I guess) do a great job making sure that the Ruby code doensn&#8217;t look like Java code in disguise: the result of the refactoring always follows Ruby&#8217;s philosophy and idioms. I particularly liked the following:</p>
<ul>
	<li>Replace Dynamic Receptor with Dynamic Method Definition (Chapter 6), a nice example of metaprogramming.</li>
	<li>Decompose Conditional/Recompose Conditional (Chapter 9), very useful and very common</li>
	<li>Replace Nested Conditional with Guard Clause (Chapter 9), another way to deal with a very common problem with conditionals</li>
	<li>Extract Module (Chapter 11), very Rubyesque way to tidy up busy classes</li>
</ul>
<p>This doesn&#8217;t mean that <em>every</em> refactoring described in the book is a programmer&#8217;s epiphany, some of the techniques are indeed pretty obvious and some portion of code in need of refactoring indeed smell very, very bad! E.g.:</p>
<ul>
	<li>Inline Class (Chapter 7): Who on Earth would ever create a class containing a single method returning a telephone number?</li>
	<li>Replace Magic Number with Symbolic Constant (Chapter 8): Why would you use integers for constants? Didn&#8217;t Matz give us Symbols to avoid just that?</li>
</ul>
<h3>The big picture</h3>
<p>By the end of chapter 11 you should be familiar with nearly all the best possible way to get rid of code smells. That&#8217;s all good, but what happens if <em>the entire program</em> stinks? Chapter 12 (<em>Big Refactorings</em>) claims to have some answers to some common pitfalls. The techniques defined in this chapter are by no means sufficient to solve all problems caused by bad design, but they can help especially to rewrite legacy code, or programs developed by Ruby newbies:</p>
<ul>
	<li>Tease Apart Inheritance</li>
	<li>Convert procedural design to objects</li>
	<li>Separate domain from presentation</li>
	<li>Extract hierarchy</li>
</ul>
<p>They are basically all about reducing bloat and unnecessary complexity, and &#8212; to me, that is &#8212; they all sounded pretty obvious. <em>Of course</em> I&#8217;m going to separate domain from presentation! Didn&#8217;t Rails teach us anything at all? I must say I was somehow disappointed by this chapter. I was going to bet there was something slightly more advanced, maybe something about replacing traditional object instantiation with an internal <span class="caps">DSL</span>? Nope, sorry.</p>
<p>Chapter 13, on the other hand, is an excellent conclusion to the book: it really helps the reader to understand when to refactor and how to do so, depending on the situation.</p>
<h3>Conclusion</h3>
<p>This and <a href="http://www.h3rald.com/articles/design-patterns-in-ruby-review/">Design Patterns in Ruby</a> are now my favorite Ruby books. I believe they complete each other: Russ Olsen&#8217;s book is more about designing your programs properly from the start, while <em>Refactoring: Ruby Edition</em> can help to make things better at a lower level. <br />
Ruby developers don&#8217;t need to refactor as much as Java developers, mainly because of Ruby itself, nevertheless, this is an excellent read for anyone who wants to get serious about programming in Ruby, and is determined to do so by following the Ruby Way.</p>
<p>I&#8217;ll definitely keep this book near me when I&#8217;m coding: I do believe it is much more helpful when you start using it as a reference, when you already read about all the refactoring techniques and want to put them in practice. Also, I&#8217;ll probably re-read chapter 3 on a regular basis, to get accustomed to recognize code smells, and deal with them accordingly.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-11-17:/articles/the-merb-way-review/</id>
    <title>Book Review: The Merb Way</title>
    <published>2009-11-17T10:15:36Z</published>
    <updated>2009-11-17T12:27:04Z</updated>
    <link href="http://www.h3rald.com/articles/the-merb-way-review/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="books" scheme="http://www.h3rald.com/tags/books/"/>
    <category term="review" scheme="http://www.h3rald.com/tags/review/"/>
    <content type="html">
<![CDATA[
<p>When I first picked up this book I was surprised by its length. Somehow, after reading <a href="/articles/the-rails-way-review">The Rails Way</a>, I got stuck in my mind that <a href="http://my.safaribooksonline.com/9780321601636">The Merb Way</a> had to be almost equally voluminous. Instead, this book is about 300 page long, roughly as long as the sum of the chapters devoted to <em>ActiveRecord</em> in Obie Fernandez&#8217;s acclaimed Rails bible.</p>
<p>Apparently it only takes 300 pages to describe a web framework nowadays! I couldn&#8217;t help but feeling a bit skeptical at first. Even in the foreword, Obie Fernandez presents the book &ndash; and the whole <a href="http://www.merbivore.com">Merb</a> framework &ndash; with some initial skepticism: isn&#8217;t Ruby on Rails enough? Why do we need yet another Ruby web framework? And above all, seeing that Merb is going to eventually be <a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3">merged into Rails 3</a>, why on Earth do we need a book about Merb, <em>now</em>?</p>
<p>Needless to say, Foy Savas proved that both Merb and its book cannot be dismissed just like that.</p>
<h3>Getting started</h3>
<p style="float:right;"><img src="/img/pictures/therailsway.jpg" alt="" /></p>
<p>The book starts with the original <a href="http://pastie.org/14416">Merb Pastie</a>, a single page of Ruby code able to sort out <span class="caps">HTTP</span> requests, dispatch them to the appropriate controllers and render a web page. This piece of code is enough to convey what Merb is: a new breed of web framework, almost as simple as it can get but very poweful and flexible at the same time.</p>
<p>As you start diving in through the first chapter, you realize you&#8217;re reading about a <em>Hacker&#8217;s Web Framework</em>. That&#8217;s precisely what Merb is: a very versatile tool to get the job done, in the simplest way possible. Similarly, <em>The Merb Way</em> immediately feels like a <em>Hacker&#8217;s Handbook</em> rather than an ordinary guide on how to develop web applications. You won&#8217;t learn what <span class="caps">MVC</span> is by reading this book, and don&#8217;t expect to be taught what a <em>mixin</em> is; you are reading a book about a Ruby web framework that was born after the <em>Rails Revolution</em>, so it is safe (for the author) to assume that:</p>
<ul>
	<li>You know the Ruby programming language</li>
	<li>You know what Ruby on Rails is and you tried it out, at the very least</li>
</ul>
<p>The first few chapters are about the core functionalities provided by an an <span class="caps">MVC</span> framework: after a comprehensive first chapter about Merb&#8217;s fundamentals (from the layout of a Merb application to an overview of Merb internals) you are quite abruptly &#8220;introduced&#8221; to routing, controllers, views and models. These chapters do not aim to provide a comprehensive description of each component, they simply tell you: <em>here&#8217;s how Merb does this</em>.</p>
<p>Out of the first five chapters, favorite is definitely the one about <em>Models</em>. Although Merb is <span class="caps">ORM</span>-agnostic, DataMapper is the <em>de facto standard</em> for Merb applications, and it fully embrace the framework&#8217;s design and extreme flexibility without being <em>in the way</em> of your code.<br />
Foy does an excellent job in this chapter by strategically describing DataMapper&#8217;s code from the top to the very bottom, from the highest abstractions to raw <span class="caps">SQL</span> code, using a plethora of snippets taken from the actual Merb code.</p>
<h3>It&#8217;s about how Merb works, not how to work with Merb</h3>
<p>After reading the <em>Models</em> chapter I decided to go back and re-examine the previous chapters. I didn&#8217;t notice until then, but the author sneakily <em>smuggled</em> a consistent amount of Merb source code into this book. This is rather unusual for books about web frameworks: they normally tell you how to use the framework, not how it was built! While this can be disappointing for people used to read Rails books, it came as a very pleasant surprise to me.</p>
<p>About 40-50% of this entire book (and I&#8217;m not exaggerating) is Ruby source code. In a good way, it feels like a collection of strategically-positioned code snippets glued together with explanations of the most tricky bits and digressions on how the framework was <em>designed</em>. In other words, it probably contains just enough text to make sure that the average reader understands the code, but remember that the <em>average reader</em> of this book must know Ruby failry well.</p>
<p>There is no pointless prose in this book, no explanations of obvious methods, no fancy words, no useless boasting on how cool the framework is: just an objective description of how Merb works and of the key design decisions behind it. If I may, the only thing that doesn&#8217;t feel quite right with this book is its title: <em>Merb Internals</em> would have been a better choice. Once you realize this, the book suddenly makes sense, and can even make you a better Ruby programmer.</p>
<p><em>The Merb Way</em> does an excellent job in describing how to design a web framework, or any real-world Ruby application for that matter. It teaches you that modularity is the key to flexibility by showing how the Merb stack is organized. Sure, it doesn&#8217;t teach you how to create a blog in five minutes, but perhaps a thorough explanation of how anthentication is implemented (Chapter 9) will actually be useful in two months time, when you&#8217;ll have to create your own Merb plugin from scratch.</p>
<h3>Some constructive criticism</h3>
<p>The idea behind this book is clever but a bit dangerous. I flipped through the pages in front of my wife and asked her what was wrong with it. <em>&#8220;There&#8217;s too much code!&#8221;</em> she said, without hesitation. Precisely.</p>
<p>It is damn good Ruby code, but sometimes you wish there was more text describing how to use it in practice. Or maybe some code examples on <em>using</em> the framework on a real-world application. Not a chance. Of all that holy code, there&#8217;s not much featuring something other than Merb itself. Basically the exact opposite of all the other books about Rails or other web frameworks!</p>
<p>Even accepting the fact that you are not reading a book about developing web applications, there are two more things which could be improved:</p>
<ul>
	<li>Merb&#8217;s design is very intriguing, and you grasp the essentials by reading this book, but a few diagrams here and there and more in-depth digressions on the subjects would have been nice.</li>
	<li>Besides DataMapper, what I really wanted to read about were Slices and Parts &ndash; unfortunately the chapters about them are far too short and shallow. The reasoning behind this is that <em>their future may be uncertain</em> due to the Rails 3 merge. Pity.</li>
</ul>
<h3>Conclusion</h3>
<p>The death of Merb has been greatly exaggerated. Too bad I <a href="/articles/take-back-your-site-with-nanoc/">gave up web frameworks altogether</a> for my site, because after reading this book I would have gone for Merb <em>today</em> rather than waiting to see the wonders of Rails 3 <em>tomorrow</em>. Even a book with this title could have been written in a very different way, I would still recommend it if you want to become a better Ruby programmer by learning from the best: Merb code really stands out, even compared to Rails, and Foy Savas does a great job presenting and describing it.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-11-12:/articles/herald-vim-021/</id>
    <title>herald.vim 0.2.1 released</title>
    <published>2009-11-12T12:34:29Z</published>
    <updated>2009-11-12T13:24:02Z</updated>
    <link href="http://www.h3rald.com/articles/herald-vim-021/" rel="alternate"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="vim" scheme="http://www.h3rald.com/tags/vim/"/>
    <content type="html">
<![CDATA[
<p style="float:right;"><img src="/images/herald.vim/0.2.1_release.png" alt="" /></p>
<p><span class="dropcap">I</span> just updated the <a href="/herald-vim-color-scheme/">Herald Vim color scheme</a> to improve the readability of delimiters and search results.</p>
<p>Delimiters are now red (the same color as operators) instead of yellow, so that you can tell the start and end of a string or regular expression more easily. Additionally, search results are no longer highlighted with black text on an orange background for two reasons:</p>
<ul>
	<li>the orange background is a bit too strong</li>
	<li>the black foreground causes letters to become <em>completely hidden</em> by the <em>cursorline</em> and <em>cursorcolumn</em></li>
</ul>
<p>Search results now have a gray background and a yellow background, as shown in the screenshot on the right.</p>
<p>If you have any constructive suggestion on how to improve this color scheme, don&#8217;t hesitate to add a comment to this post!</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-11-05:/articles/journotwit-review/</id>
    <title>JournoTwit - The best way to organize your tweets</title>
    <published>2009-11-05T15:19:17Z</published>
    <updated>2009-11-05T16:26:32Z</updated>
    <link href="http://www.h3rald.com/articles/journotwit-review/" rel="alternate"/>
    <category term="review" scheme="http://www.h3rald.com/tags/review/"/>
    <category term="web20" scheme="http://www.h3rald.com/tags/web20/"/>
    <category term="internet" scheme="http://www.h3rald.com/tags/internet/"/>
    <category term="software" scheme="http://www.h3rald.com/tags/software/"/>
    <content type="html">
<![CDATA[
<p>Since I started using <a href="http://www.twitter.com">Twitter</a> on a regular basis, I felt overwhelmed by the endless stream of data generated by the people I was following.</p>
<p>The official Twitter page quickly became inadequate to manage my tweets, so I began to search for an alternative through the myriad of Twitter clients available out there, both web and desktop based. After trying out a few desktop clients, I decided to restrict the search to web clients only: between work and home, I may use up to 4 different computers and 3 different operating system, and I really didn&#8217;t fancy the idea of keeping the <em>same</em> client up-to-date everywhere &#8212; even if such client existed.</p>
<p>Over the past months I tried dozens of different web-based Twitter clients, and narrowed the list of <em>must-have</em> features to the following:</p>
<ul>
	<li>The interface should be simple to use and not too cluttered.</li>
	<li>I should be able to categorize tweets in columns (&agrave; la TweetDeck).</li>
	<li>I should be able to know, when visiting the site, how many <em>new</em> tweets I have to go through.</li>
	<li>I should be able to mark tweets as read.</li>
	<li>It should display media files (at least pictures) inline with the tweets.</li>
	<li>The interface should provide all the most common twitter actions like reply, retweet, follow/unfollow, shorten url, upload pictures etc. etc.</li>
</ul>
<p>The good news is that I found at least <em>one</em> web-based client able to do all this: <a href="http://www.journotwit.com">JournoTwit</a>.</p>
<h3>Introducing JournoTwit</h3>
<p>JournoTwit was born &ndash; as many software projects &ndash; to scratch an itch:</p>
<blockquote>
<p>Probably the last thing anyone was expecting me to do &mdash; even myself, was to create my own twitter client. However, I&#8217;ve been a little fed up with not having the features I wanted and running 5 or 6 accounts, I was getting annoyed at using several different applications just to have them logged in concurrently. [&#8230;] In under 24 hours I put together a twitter client that functioned enough for me to call it my one and only. A few more days and I added in enough features that I felt it was good enough for public consumption. It is however, not perfect and I have plenty of improvements on my to do list for it.</p>
</blockquote>
<p style="padding-left:3em;"><cite><a href="http://www.spodesabode.com/discussion/280/journotwit-the-twitter-client-thats-not-just-for-journalists/">JournoTwit&#8217;s introductory post</a></cite> by Andrew Spode Miller (<a href="http://twitter.com/spode">@spode</a>)</p>
<p>After months of <em>public consumption</em>, JournoTwit became a feature-packed Twitter client able to compete with a lot of mainstream alternatives &ndash; albeit remaining always relatively unknown to the masses. You can call it a <em>niche</em> Twitter client, able to satisfy a few basic needs:</p>
<ul>
	<li>The ability to manage multiple Twitter accounts at once.</li>
	<li>The ability to categorize all incoming tweets automatically, according to the type of information within them.</li>
	<li>The ability to keep track of unread tweets.</li>
</ul>
<p>These three features alone were enough to make JournoTwit my one and only Twitter client. And no, it&#8217;s not only for journalists and writers.</p>
<h3>Interface overview</h3>
<p>After logging in, JournoTwit looks like this:</p>
<p><img src="/img/pictures/journotwit/interface.png" alt="" /></p>
<p><b>Note:</b> I am using the <em> <a href="http://www.journotwit.com/edge/">edge</a> </em> version of JournoTwit, a sort of development snapshot with the latest features.</p>
<p>At the top, some more-or-less intuitive icons allow you to perform all the most common <em>global</em> actions:</p>
<ul>
	<li>Tweet</li>
	<li>Manual refresh</li>
	<li>Mark all columns as read</li>
	<li>Add new columns</li>
	<li>Quick search</li>
	<li>Edit settings</li>
	<li>Logout</li>
</ul>
<p>Next to this global toolbar, there&#8217;s a list of links, each corresponding to a column. Clicking a link toggles the visibility of the corresponding column.</p>
<p>In each column, tweets are displayed in different column according to their state:</p>
<ul>
	<li>Read</li>
	<li>Unread</li>
	<li>Selected</li>
</ul>
<p>You can select one tweet at a time by clicking the <strong>+</strong> icon. This toggles the tweet-specific actions:</p>
<ul>
	<li>Reply</li>
	<li>Send a direct message</li>
	<li>Save as favorite</li>
	<li>Retweet</li>
	<li>Translate</li>
</ul>
<p>Pretty intuitive and easy to use, so far.</p>
<h3>Default columns</h3>
<p>When you login, you&#8217;ll notice that all your tweets are <em>not</em> presented in the traditional, disorganized single-column stream layout. Instead, they are <em>sorted automatically</em> into different columns, according to their type:</p>
<dl>
	<dt>My Feed</dt>
	<dd>All the tweets <em>you</em> sent. By default, this column is minimized.</dd>
	<dt>No-Mention</dt>
	<dd>All tweets containing your username without the &#8220;@&#8221;, i.e. every time someone mentions you sneakily, without sending you a reply.</dd>
	<dt>Messages</dt>
	<dd>All the direct messages you sent and received.</dd>
	<dt>Mentions</dt>
	<dd>All the tweets containing your twitter username (with &#8220;@&#8221;), such as replies to your tweets.</dd>
	<dt>Statuses</dt>
	<dd>All the tweets posted by people you follow that do not contain any link or cannot be categorized through other columns.</dd>
	<dt>News</dt>
	<dd>All the tweets posted by people you follow containing links to articles or non-multimedia web pages.</dd>
	<dt>Retweets</dt>
	<dd>All the retweets posted by people you follow.</dd>
	<dt>Visual</dt>
	<dd>All the tweets posted by people you follow containing links to pictures or videos. Where possible, media is displayed inside the tweet.</dd>
	<dt>Audio</dt>
	<dd>Same as above, but for audio items.</dd>
	<dt>Chatter</dt>
	<dd>Attempts to collect all conversations involving you or people you follow.</dd>
</dl>
<p>Surprisingly, these default columns are enough to make your Twitter experience easier and more manageable, without configure a single setting. They&#8217;re obviously not perfect: some images are not resolved automatically, for example, but it works well otherwise.</p>
<p>Still this may not be enough for your needs or maybe simply not the right thing. No problem: JournoTwit is extremely flexible when it comes to organizing and sorting out your tweets.</p>
<h3>Adding new columns</h3>
<p>All columns except for <em>Mentions</em> and <em>Messages</em> can be modified as you see fit. These two columns cannot be modified simply because there&#8217;s nothing you <em>need</em> to modify it, if you think about it. But they can be deleted, of course (and re-created in a blink, if you delete them by mistake).</p>
<p>Let&#8217;s go through the slightly geeky process of creating a column.</p>
<p>When you click the <b>Add New Columns</b> icon on the top-left corner you&#8217;ll be prompted to further clarify whether you want to add a&#8230;</p>
<ul>
	<li>Set of Columns: i.e. the default columns provided by journotwit <em>or</em> a single column containing all the tweets. Useful if you mess things up and you want to start over again.</li>
	<li>Preset Column: choose from many different columns according to your needs, from different tweet types to memes (#followfriday, #musicmonday, etc.).</li>
	<li>Custom Column: create your own personal column, according to your specific needs.</li>
</ul>
<p>Because the overwhelming majority of my readers is composed by geeks, I&#8217;ll just describe how to create a custom column, so that you can fully understand the power of this tool, in the right hands.</p>
<h3>Adding a custom column</h3>
<p style="float:right;"><img src="/img/pictures/journotwit/custom_column.png" alt="" /></p>
<p>The creation of a custom column doesn&#8217;t take long, but there are quite a few things you can configure. First off, you have to specify whether you want the column to collect <em>local</em> or <em>global</em> tweets: local means the people you follow, while global means everyone on the planet. Simple enough.</p>
<p>Then comes the juicy geeky part: search terms and tags. Simply type a valid <a href="http://search.twitter.com/operators">Twitter Search query</a> in the textbox, so something like this:</p>
<p><code>from:jonobacon OR #ubuntu -jaunty</code></p>
<p>&#8230;will hopefully fetch all tweets posted by <a href="http://www.twitter.com/jonobacon">@jonobacon</a> or tweets about Ubuntu, but not related to the Jaunty Jackalope release. You can also add more text box and thus perform more search queries within the same column.</p>
<p>Then you can filter by tweet type, enabling or disabling Statuses, Visual, Links, Audio, ReTweets and Chatter. Useful to remove the noise (if you follow <a href="http://www.twitter.com/brentspiner">@brentspiner</a>, make sure you disable <em>ReTweets</em>&#8230;).</p>
<p>Finally, you only have to configure a few more settings:</p>
<ul>
	<li>Whether you want to be alerted with a <em>beep</em> when there are new tweets in this column.</li>
	<li>Whether you want the column to display tweets, a tag cloud or even an image slideshow.</li>
	<li>The name of the column.</li>
</ul>
<p>That&#8217;s all. Simple enough. As a side note, the &#8220;No-Mention&#8221; column is nothing but a custom column in disguise: if you try to edit it, you&#8217;ll see it&#8217;s nothing but a search for &#8220;<em>username</em> -<em>@username</em> -from:<em>username</em>&#8221;.</p>
<h3>Other features and advanced settings</h3>
<p>For the tweakers, JournoTwit also exposes the a set of global settings you can modify to enhance your experience or disable annoying behaviors (depends how you look at it):</p>
<h4>Behavior</h4>
<ul>
	<li>Unhide column when new tweets arrive? (default: yes)</li>
	<li>Hide columns on Mark as Read? (default: yes)</li>
	<li>Play alert sounds? (default: yes)</li>
	<li>Animate when new items arrive? (default: yes)</li>
	<li>Default #hashtags and search bar to a local search? (default: no)</li>
	<li>Ignore Tag Coulds when marking all as read? (default: yes)</li>
	<li>Ignore Slide Shows when marking all as read? (default: yes)</li>
	<li>Warn when deleting columns? (default: yes)</li>
	<li>Automatically translate tweets using Google Translate? (default: no)</li>
	<li>Show &#8220;Did You Know?&#8221; messages on refresh? (default: yes)</li>
	<li>Slide show transition time(s) (default: 5)</li>
</ul>
<h4>Display Adjustment</h4>
<p>If you are unsatisfied by JournoTwit&#8217;s default look and feel, you can change the fond size, the color theme (there are 18 possible choices) and even match the color of the icons with the current theme.</p>
<h4>Black Listing</h4>
<p>Straight from the contextual help:</p>
<blockquote>
<p>&#8220;Here you globally black list a #hashtag, such as #microsoft, or a search phrase such as &#8220;Windows 7&#8221;. Remember to separate them with a space and that you can block on a per column basis too.&quot;</p>
</blockquote>
<p>This is just what you need when you want to filter out pointless tweets. Use with care though!</p>
<h3>Conclusion</h3>
<p>Maybe it&#8217;s just me being a geek, but I think JournoTwit nailed it when it comes to making Twitter more productive: everything <em>just works, and fast</em>, unlike some of its more feature-boasting competitors. I have been using it on a daily basis for weeks, and I&#8217;ve never missed a single tweet since (unless <em>I explicitly wanted to do so</em>).</p>
<p>That being said, there are a few small features I&#8217;d like to see:</p>
<ul>
	<li>I&#8217;d like to be able to mark <em>single tweets</em>, not entire columns, as read. In this way, when I go on vacation and come back, I can catch up with unread tweets more gradually, like I do with Google Reader.</li>
	<li>I&#8217;d like to use shortcut keys to navigate the interface, like with Google Reader.</li>
	<li>I&#8217;d like to configure tweets so that they only show up in one column, not in more than one (for example in Chatter, My Feed, and Mentions at the same time).</li>
	<li>Support for Twitter Lists&#8230;</li>
</ul>
<p>I already told <a href="http://twitter.com/spode">@spode</a> about some of these, and he said he&#8217;ll look into it, we&#8217;ll see what happens. Anyhow, just <a href="http://www.journotwit.com">give it a try</a>, and see if you like it!</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-10-27:/articles/getting-started-with-lithium/</id>
    <title>Getting Started with Lithium</title>
    <published>2009-10-27T14:48:00Z</published>
    <updated>2009-10-29T10:50:08Z</updated>
    <link href="http://www.h3rald.com/articles/getting-started-with-lithium/" rel="alternate"/>
    <category term="li3" scheme="http://www.h3rald.com/tags/li3/"/>
    <category term="php" scheme="http://www.h3rald.com/tags/php/"/>
    <category term="tutorial" scheme="http://www.h3rald.com/tags/tutorial/"/>
    <content type="html">
<![CDATA[
<p>So <a href="http://li3.rad-dev.org/">Lithium</a> is now officially out, and its 0.1 release can be freely <a href="http://rad-dev.org/lithium/versions">downloaded</a> from the official web site or by cloning the Lithium git repository. The good news is that although not many web hosts offer <span class="caps">PHP</span> 5.3, you can try it out youself, locally and with minimum effort.</p>
<h3>Requirements</h3>
<p>According to the <a href="http://rad-dev.org/wiki/guides/setup">Lithium Wiki</a>, to develop applications with Lithium you need:</p>
<ul>
	<li>A web server, like Apache or <span class="caps">IIS</span></li>
	<li><span class="caps">PHP</span> 5.3.0 or higher</li>
	<li>Git (not required, but all example projects are on git repos, so you may as well have it)</li>
</ul>
<p>For this tutorial, more specifically, you need to download (just download, don&#8217;t install anything!):</p>
<ul>
	<li><a href="http://code.google.com/p/mongoose/">mongoose</a>, a tiny, standalone (as <em>in one single file</em>), cross-platform web server.</li>
	<li><a href="http://www.php.net/downloads.php#v5"><span class="caps">PHP</span> 5.3.0</a>, not the installer, the zip package.</li>
	<li><a href="http://rad-dev.org/lithium/versions">Lithium</a> (version 0.1, at the time of writing)</li>
	<li>The <a href="http://rad-dev.org/li3_docs">li3_docs plugin</a>.</li>
</ul>
<p>To get the li3_docs plugin you need to <a href="http://rad-dev.org/users/add">register</a> on rad-dev.org, and clone the li3_docs git repository. If you don&#8217;t have git installed or you don&#8217;t want to read <a href="http://spheredev.org/wiki/Git_for_the_lazy">another awesome tutorial</a> to install it and learn how to use it, I&#8217;ll save you the hassle and let you download the plugin from <a href="/files/li3_docs.zip">here</a>, for this time ony.</p>
<p><b>Note:</b> This tutorial assumes that you are on Windows. If you are not, some things may be a bit different depending on your platform.</p>
<h3>Setting up the environment</h3>
<p>Choose a directory on your sistem (let&#8217;s call it <b>D:\lithium_test</b> from now on). We&#8217;ll do everything in here, and you can move it anywhere you like afterwards, even on a <span class="caps">USB</span> stick, without breaking anything.</p>
<ol>
	<li>Unzip Lithium in <b>D:\lithium_test</b>, so that it contains the following files and directories:
	<ul>
		<li>app/</li>
		<li>libraries/</li>
		<li>.htaccess (it won&#8217;t actually be used in this tutorial)</li>
	</ul></li>
	<li>Unzip <span class="caps">PHP</span> 5.3.0 somewhere and copy the following files to the <b>D:\lithium_test</b> folder:
	<ul>
		<li>php5.dll</li>
		<li>php-cgi.exe</li>
		<li>php.ini (just get php.ini-development from the <span class="caps">PHP</span> package and rename it)</li>
	</ul></li>
	<li>Copy the mongoose-2.8.exe executable in <b>D:\lithium_test</b> and rename it to <b>mongoose.exe</b> for convenience.</li>
	<li>Create a <b>mongoose.conf</b> file containing the following lines:</li>
</ol>
<div class="highlight"><pre>cgi_interp      php-cgi.exe
cgi_ext         php
</pre>
</div><p>If you did everything correctly, your <b>D:\lithium_test</b> directory should contain the following:</p>
<ul>
	<li>app\</li>
	<li>libraries\</li>
	<li>.htaccess</li>
	<li>mongoose.exe</li>
	<li>mongoose.conf</li>
	<li>php-cgi.exe</li>
	<li>php.ini</li>
	<li>php5.dll</li>
</ul>
<h3>Running Lithium</h3>
<p>Double click <b>mongoose.exe</b> and point your browser of choice to <a href="http://localhost:8080/app/webroot/index.php">http://localhost:8080/app/webroot/index.php</a>. You should see the Lithium temporary homepage (yes, I expected something fancier too):</p>
<p><img src="/img/pictures/lithium/temp_homepage.png" alt="" /></p>
<p>Now, let&#8217;s see if we can get the li3_docs plugin running as well:</p>
<ol>
	<li>Unzip <b>li3_docs.zip</b> and copy the <b>li3_docs</b> folder in <b>D:\lithium_test\app\libraries\plugins</b>.</li>
	<li>Open <b>D:\lithium_test\app\config\bootstrap.php</b> and add the line: <code>Libraries::add('plugin', 'li3_docs');</code> at the end. I actually found this commented out already (line 80).</li>
</ol>
<p>Go to <a href="http://localhost:8080/app/webroot/index.php?url=docs">http://localhost:8080/app/webroot/index.php?url=docs</a>, you should see something like this:</p>
<p><img src="/img/pictures/lithium/li3_docs.png" alt="" /></p>
<p>Congratulation, you&#8217;re now running your first Lithium application!</p>
<h3>Fixing URLs</h3>
<p>Once the initial excitement wears off you&#8217;ll notice that none of the links on the docs page works.</p>
<p>That&#8217;s because the mongoose web server does not support <span class="caps">URL</span> rewriting (and Lithium needs it badly right now), so we have to change the way URLs are created. <a href="http://twitter.com/nateabele">@nateabele</a> gave me <a href="http://pastium.org/view/3a966c1446fcbd1d4f5a94d882256987">some tips</a> on how to do this; it&#8217;s very simple:</p>
<ol>
	<li>Create a directory called <b>action</b> in <b>D:\lithium_test\app\extensions</b>.</li>
	<li>Create a file called <b>Request.php</b>, containing the following:</li>
</ol>
<div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nx">namespace</span> <span class="nx">app</span><span class="err">\</span><span class="nx">extensions</span><span class="err">\</span><span class="nx">action</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Request</span> <span class="k">extends</span> <span class="err">\</span><span class="nx">lithium</span><span class="err">\</span><span class="nx">action</span><span class="err">\</span><span class="nx">Request</span> <span class="p">{</span>

	<span class="k">protected</span> <span class="k">function</span> <span class="nf">_base</span><span class="p">()</span> <span class="p">{</span>
		<span class="k">return</span>  <span class="s1">&#39;?url=&#39;</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span>
<span class="cp">?&gt;</span><span class="x"></span>
</pre>
</div><p>We&#8217;re basically extending the <code>\lithium\action\Request</code> with a custom class, telling Lithium how to create the base <span class="caps">URL</span>.</p>
<p>After doing so, open <b>D:\lithium_test\app\webroot\index.php</b> and change:</p>
<p><code>echo lithium\action\Dispatcher::run();</code></p>
<p>into:</p>
<code>echo lithium\action\Dispatcher::run(new app\extensions\action\Request());</code>
<p>In this case, we&#8217;re instructing the dispatcher to use our custom Request class instead of the default one.</p>
<p>Now everything should work as expected. Reload the docs page (<a href="http://localhost:8080/app/webroot/index.php?url=docs">http://localhost:8080/app/webroot/index.php?url=docs</a>) and verify that the links work by navigating to <code>Lithium</code>, then <code>action</code> and finally <code>Controller</code>.</p>
<p>Now you can use Lithium to display its own <span class="caps">API</span> locally (if things didn&#8217;t work out, there&#8217;s always <a href="http://li3.rad-dev.org/docs">http://li3.rad-dev.org/docs</a>).</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-10-24:/articles/too-many-cooks-take-3/</id>
    <title>Too many cooks... take #3</title>
    <published>2009-10-24T18:26:59Z</published>
    <updated>2009-10-24T19:34:18Z</updated>
    <link href="http://www.h3rald.com/articles/too-many-cooks-take-3/" rel="alternate"/>
    <category term="cakephp" scheme="http://www.h3rald.com/tags/cakephp/"/>
    <category term="rant" scheme="http://www.h3rald.com/tags/rant/"/>
    <category term="php" scheme="http://www.h3rald.com/tags/php/"/>
    <category term="li3" scheme="http://www.h3rald.com/tags/li3/"/>
    <content type="html">
<![CDATA[
<p>Like <a href="http://www.h3rald.com/articles/too-many-cooks-take-2/">its predecessor</a>, this is another rant about the (end of the) <a href="http://www.cakephp.org">CakePHP framework</a>. Not that I particularly enjoy writing about the misfortune of others, but after reading <a href="http://bakery.cakephp.org/articles/view/the-cake-is-still-rising">this official announcement</a> I felt compelled to post.</p>
<p>It has been two years since my last post on this subject and yes, the cake is still rising, but at what price? Will it still taste sweet now that two of its main ingredients are not part of it anymore? As <a href="http://cakebaker.42dh.com/2009/10/23/the-end-of-cakephp/">Daniel</a> puts it, <em>probably the best thing to do now is to drink tea and to wait until the dust settles&#8230;</em></p>
<p>As far as I&#8217;m concerned, what really matters is that Garrett Woodworth (former CakePHP Project Manager) and Nate Abele (former CakePHP Lead Developer) are <em>gone</em>. They realized they had enough Nuts over the years and they decided to switch to a more <a href="http://irc.cakephp.org/logs/link/1110092#message1110102">Lithium-rich</a> diet. More helthy and depression-proof, too!</p>
<p>Stupid metaphors and painful jokes aside, this is probably the best piece of news the CakePHP community received in a long time: the birth of <em>a fork of the CakePHP framework</em>, more precisely of the so-called Cake3 branch.</p>
<p><em>Cake3</em>? I didn&#8217;t keep up-to-date with the buzz, so I didn&#8217;t know anything about this until today, when I decided to finally start catching up.</p>
<blockquote>
<p>&#8220;Cake 3.0, on the other hand, is pretty different from the existing core code in a few notable ways. Mainly, it&#8217;s been re-written from the ground up for <span class="caps">PHP</span> 5.3.&#8221;</p>
</blockquote>
<p style="padding-right:6em;">from <a href="http://debuggable.com/posts/Cake_3_interview_with_Nate_Abele:4a665a5e-5bfc-4e42-96ee-6d284834cda3">Cake 3 interview with Nate Abele</a>, debuggable.com</p>
<p>Of course, in these three years of my full immersion in the Ruby language, I almost completely forgot about <span class="caps">PHP</span> too. <span class="caps">PHP</span> 5.3 means namespace and closures, i.e. the Rubyist&#8217;s daily bread. A more modular CakePHP, properly object-oriented, with an ActiveRecord-like <span class="caps">API</span> for models (finally!) is definitely worth a look, especially if it&#8217;s Nut-free as well.</p>
<p>The new framework will be called <strong>Lithium</strong> (sounds more professional already), and it&#8217;s due to launch next monday, here: <a href="http://li3.rad-dev.org/">http://li3.rad-dev.org/</a> (at the time of writing, this link is password-protected).</p>
<p>Personally, I am <em>very</em> excited about this new project. It should have happened three years ago, really, but there&#8217;s no point in being greedy: the time has finally come. I would like to (pre-)thank Garrett and Nate for their (upcoming) amazing work, I&#8217;ll definitely keep a closer eye on it.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-09-15:/articles/take-back-your-site-with-nanoc/</id>
    <title>Take back your site, with nanoc!</title>
    <published>2009-09-15T11:32:51Z</published>
    <updated>2010-02-28T13:01:52Z</updated>
    <link href="http://www.h3rald.com/articles/take-back-your-site-with-nanoc/" rel="alternate"/>
    <category term="website" scheme="http://www.h3rald.com/tags/website/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="writing" scheme="http://www.h3rald.com/tags/writing/"/>
    <content type="html">
<![CDATA[
<p>Back in 2004, when I bought the h3rald.com domain, this site was static. At the time I hardly knew <span class="caps">HTML</span> and <span class="caps">CSS</span>, nevermind server-side languages, so I remember creating a <em>pseudo-template</em> for the web site layout and using it whenever I wanted to create a new page, to preserve the overall look-and-feel. This was a crude and inefficient strategy, of course: whenever I changed the layout I had to replicate the change in all the pages of the site &ndash; the whole eight of them.</p>
<p>Five years later, after rebuilding this web site <a href="/h3rald/">seven times</a> using different backends (<span class="caps">PHP</span> + CakePHP, Ruby + Rails + Typo, etc.), I decided to make it static again, this time with a twist. It all started when I read a <a href="http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html">post</a> by Tom Preston-Warner (<a href="http://www.github.com">GitHub</a> co-founder) that I finally decided to give it a try. Today, the 8th release of this web site is 100% static: if you load any page, there&#8217;s no server-side interpretation going on, you&#8217;re just browsing a plain <span class="caps">HTML</span> page, at most with a few <span class="caps">AJAX</span> calls. But let&#8217;s start from the beginning&#8230;</p>
<h3>Why I don&#8217;t need a blog platform</h3>
<p>There&#8217;s nothing inherently wrong with blog platforms like Wordpress: they allow <em>anyone</em> to publish content on the web using a user-friendly administration area. They were built with one thing in mind: make publishing content on the web something as simple as possible, even for people who don&#8217;t know anything about <span class="caps">HTML</span>, let alone server-side scripting.</p>
<p>What about people who <em>do</em> know about web development though? Do they still need a blog platform? Depends. If you are comfortable with editing files using a text editor, if you enjoy using the command-line on a daily basis, if you like programming and <em>hacking</em> a little bit, if you don&#8217;t really care about fancy and user-friendly administration backends&#8230; <em>then you probably don&#8217;t</em>.</p>
<p>All you need is a system to transform a bunch of source files into a web site. The good news is that such system exists &ndash; and you&#8217;re also spoiled for choices!</p>
<h3>Introducing site compilers</h3>
<p>The first <em>site compiler</em> I discovered was <a href="http://webby.rubyforge.org/">Webby</a>:</p>
<blockquote>
<p>[&#8230;] Webby works by combining the contents of a page with a layout to produce <span class="caps">HTML</span>. The layout contains everything common to all the pages &mdash; <span class="caps">HTML</span> headers, navigation menu, footer, etc. &mdash; and the page contains just the information for that page. You can use your favorite markup language to write your pages; Webby supports quite a few.</p>
</blockquote>
<p>There are quite a few applications like Webby, such as:</p>
<ul>
	<li><a href="http://nanoc.stoneship.org/">nanoc</a></li>
	<li><a href="http://snk.tuxfamily.org/lib/rassmalog/doc/guide.html">Rassmalog</a></li>
	<li><a href="http://www.jekyllrb.com/">Jeckyll</a></li>
	<li><a href="http://webgen.rubyforge.org/">WebGen</a></li>
	<li><a href="http://rog.rubyforge.org/">Rog</a></li>
	<li><a href="http://rote.rubyforge.org/">Rote</a></li>
	<li><a href="http://hobix.com/">Hobix</a></li>
	<li><a href="http://rakeweb.rubyforge.org/wiki/wiki.pl">RakeWeb</a></li>
	<li><a href="http://www.apeth.com/RubyFrontierDocs/default.html">RubyFrontier</a></li>
	<li><a href="http://staticmatic.rubyforge.org/">StaticMatic</a></li>
	<li><a href="http://staticweb.rubyforge.org/">StaticWeb</a></li>
	<li><a href="http://www.zenspider.com/ZSS/Products/ZenWeb/">ZenWeb</a></li>
	<li><a href="http://yurtcms.roberthahn.ca/">YurtCMS</a></li>
	<li><a href="http://nanoblogger.sourceforge.net/">NanoBlogger</a></li>
</ul>
<p>There are probably even more, with different features, but they all try to solve the same problem: provide a way to generate static web sites in an automated way.</p>
<p>I spent some time reading about each one of them, <a href="http://github.com/h3rald/h3rald/issues/closed#issue/1">evaluating the pros and cons</a> and in the end I decided to go for <a href="http://nanoc.stoneship.org/">nanoc</a>, simply because it was the only one that seemed to fit all my needs.</p>
<h3>A quick overview of nanoc</h3>
<p>nanoc is a nifty tool written in Ruby suitable for <em>[&#8230;] building small to medium-sized websites</em>. In other words, anything which doesn&#8217;t involve some fancy user interaction. For what concerns blogs, the only user interaction is <em>comments</em> &ndash; but that&#8217;s fine, because there&#8217;s more than one web service for that, such as <a href="http://disqus.com/">Disqus</a> or <a href="http://intensedebate.com/">IntenseDebate</a>.</p>
<h4>Some details on the project</h4>
<p>Compared to the alternatives, nanoc is one of the most mature and most maintained, having hit just a few weeks ago its 3.0 release. Its creator, Denis Defreyne, uses it for his own <a href="http://stoneship.org/">web site</a> and is involved with the project on a daily basis, both coding and offering support to nanoc users like myself who regularly ask questions on the <a href="http://groups.google.com/group/nanoc">nanoc user group</a>.</p>
<p>Denis also seems very concerned about keeping documentation up-to-date &ndash; something that really impressed me from a technical writer&#8217;s point of view. The <a href="http://nanoc.stoneship.org/tutorial/">tutorial</a> he put together will get you started in no time, and the <a href="http://nanoc.stoneship.org/manual/">manual</a> will explain everything else you may possibly want to know. When release 3.0 came out he even put together a <a href="http://nanoc.stoneship.org/migrating/">migration guide</a>. If this is still not enough and you don&#8217;t mind spending some time extending the system, nanoc&#8217;s <a href="http://nanoc.stoneship.org/doc/3.0.0/">RDoc documentation</a> is very comprehensive compared to other Ruby projects.</p>
<h4>Sites, Items and data sources</h4>
<p style="float:right;"><img src="/img/pictures/nanoc-structure.png" alt="" /></p>
<p>nanoc ships with a really neat command line tool that can do most of the work for you. <code>Nanoc3 create_site h3rald</code> will create a new web site in a folder called h3rald. The contents of this folder are laid out according to a particular logic (<em>convention over configuration</em>, remember?) So:</p>
<ul>
	<li><strong>content</strong> &ndash; your articles, pages, stylesheets, images, &#8230;all the site content and assets.</li>
	<li><strong>layouts</strong> &ndash; the site layouts (and partial layouts)</li>
	<li><strong>lib</strong> &ndash; place your custom ruby code and vendor libraries here</li>
	<li><strong>output</strong> &ndash; your &#8220;compiled&#8221; site, ready to be deployed</li>
	<li><strong>config.yaml</strong> &ndash; your site&#8217;s configuration file. The only one (and it&#8217;s just a few lines)</li>
	<li><strong>Rakefile</strong> &ndash; place any custom Rake task here</li>
	<li><strong>Rules</strong> &ndash; defines the rules for compilation, layout and routing</li>
</ul>
<p>Here&#8217;s the default <code>config.yaml</code> file:</p>
<div class="highlight"><pre><span class="nn">---</span> 
<span class="l-Scalar-Plain">data_sources</span><span class="p-Indicator">:</span> 
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">items_root</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">/</span>
  <span class="l-Scalar-Plain">layouts_root</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">/</span>
  <span class="l-Scalar-Plain">type</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">filesystem_compact</span>
  <span class="l-Scalar-Plain">output_dir</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">output</span>
</pre>
</div><p>A <em>data source</em> in nanoc defines where data is retrieved from to create the web site. By default, the <a href="http://nanoc.stoneship.org/doc/3.0.0/Nanoc3/DataSources/FilesystemCompact.html">filesystem_compact</a> data source requires that you create two files in the /content folder for each article or page of your web page:</p>
<ul>
	<li>One containing the actual content of the page</li>
	<li>Another for the page&#8217;s arbitrary metadata</li>
</ul>
<p>By personal preference, I chose the <a href="http://nanoc.stoneship.org/doc/3.0/Nanoc3/DataSources/FilesystemCombined.html">filesystem_combined</a> data source, which allows you to combine the content and the metadata of a page in a single file.</p>
<p>The source code for this very article, for example, starts like this:</p>
<div class="highlight"><pre>-----
type: article
tags:
- website
- ruby
- programming
- writing
date: 2009-09-15 13:32:51.049000 +02:00
permalink: take-back-your-site-with-nanoc
title: &quot;Take back your site, with nanoc!&quot;
toc: true
-----
Back in 2004, when I bought the h3rald.com domain, this site was static. At the time I hardly 
knew HTML and CSS, nevermind server-side languages, so I remember creating a _pseudo-template_ for
 the web site layout and using it whenever I wanted to create a new page, to preserve the overall look-and-feel. 
This was a crude and inefficient strategy, of course: whenever I changed the layout I had to replicate the change
 in all the pages of the site &amp;ndash; the whole eight of them.
</pre>
</div><p>At run time, the content goes through a Textile filter and the metadata is used in layouts, to generate tag links automatically, for example.</p>
<h4>Layouts, filters, and helpers</h4>
<p>Layouts in nanoc are similar to layouts and views in Rails, but much simpler. The same applies to helpers. Here&#8217;s a snippet from my <a href="http://github.com/h3rald/h3rald/tree/master/layouts/default.erb">default layout</a>:</p>
<div class="highlight"><pre>        &lt;div id=&quot;container&quot;&gt;
          &lt;!-- CONTENT START --&gt;
          &lt;div id=&quot;content&quot; class=&quot;clearfix&lt;%= (@item[:permalink] == &#39;home&#39;) ? &#39; home&#39; : &#39; standard&#39; %&gt;&quot;&gt;
            &lt;h2&gt;&lt;%= @item[:title] %&gt;&lt;/h2&gt;
            &lt;%   case @item[:type]
                when &#39;article&#39; then%&gt;
                &lt;div id=&quot;content-header&quot;&gt;
                  &lt;%= render &#39;article_meta&#39;, :article =&gt; @item %&gt;
                &lt;/div&gt;
              &lt;% end %&gt;
              &lt;hr /&gt;
              &lt;div id=&quot;content-body&quot;&gt;
                &lt;%= yield %&gt;
              &lt;/div&gt;
              &lt;div id=&quot;content-footer&quot;&gt;
                &lt;div class=&quot;share&quot;&gt;
                  &lt;script type=&quot;text/javascript&quot; src=&quot;http://w.sharethis.com/button/sharethis.js#publisher=6e34d60c-b14e-4c19-9b2f-7c35a9f0ab09&amp;amp;type=website&amp;amp;linkfg=%23a4282d&quot;&gt;&lt;/script&gt;
                  &lt;% if @item[:feed] then %&gt;
                  &lt;a href=&quot;&lt;% @item[:feed_url] || @item[:feed]+&quot;rss/&quot; %&gt;&quot; type=&quot;application/rss+xml&quot; rel=&quot;alternate&quot;&gt;&lt;img src=&quot;/images/theme/feed-icon-14x14.png&quot; alt=&quot;#&quot;/&gt;H3RALD - &lt;%= @item[:feed_title]%&gt;&lt;/a&gt;
                  &lt;% end %&gt;
                &lt;/div&gt;
                &lt;%= render &#39;article_buttons&#39; if @item[:type] == &#39;article&#39; %&gt;
              &lt;/div&gt;
            &lt;/div&gt;
</pre>
</div><p>This source code snippet shows quite a few features of nanoc&#8217;s layouts:</p>
<ul>
	<li>You can access the metadata of the page which is being rendered using the <code>@item</code>, so <code>@item[:title]</code> returns the page&#8217;s title, for example.</li>
	<li>Layouts can be nested, and behave like Rails&#8217;s partials. The <code>render</code> takes a string parameter (the name of the layout to render) and an optional hash parameter to pass variables to the layout.</li>
	<li>The <code>yield</code> method is used to include the content of a page.</li>
	<li>Layouts support any kind of filter, like <span class="caps">ERB</span> for example. Go crazy.</li>
</ul>
<p>Helpers can be used in layouts to perform common tasks, like creating links, feeds, navigation elements and so on. Check the <a href="http://nanoc.stoneship.org/doc/3.0.0/">source code docs</a> for more info, and of course feel free to create your own as you see fit.</p>
<p>Finally, filters are used to filter content markup. nanoc ships with <a href="http://nanoc.stoneship.org/manual/#list-of-built-in-filters">almost everything you need</a>, from Textile to Haml to RDoc, but nobody forbids you to create your own, and it&#8217;s dead easy.</p>
<h4>Rules and tasks</h4>
<p>While tasks (as in Rake tasks) do not constitute a huge part of nanoc (but as usual, you may need to create your own to perform custom operations), Rules became, as of version 3, one of the key concepts to grasp in order to make everything work. Rules are stored in the <code>Rules</code> file of your nanoc site, they can be used to:</p>
<ul>
	<li>Define routes, i.e. where pages are deployed in the output folder.</li>
	<li>Define how pages are compiled, which filters to apply to a particular set of pages, which layouts to use, etc.</li>
	<li>Define how layout are handled, which filters to apply to a particular layout, etc.</li>
</ul>
<p>You can find more information in the <a href="http://nanoc.stoneship.org/manual/#rules">manual</a>, along with other important information, but for now, let&#8217;s say you should be familiar with <em>most</em> of nanoc&#8217;s jargon and how it works. Let&#8217;s see what you can do with it, in practice.</p>
<h3>Migrating from your blog platform</h3>
<p>As of version 7, h3rald.com has been powered by the <a href="http://www.typosphere.org">Typo</a> blog platform. If you are not familiar with it, let&#8217;s just say it&#8217;s a sort of Wordpress built on top of Rails: database backend, pretty admin front-end, tags, comments, and all sort of things a blog may need. While Typo is pleasant enough to use, it has all the inherent disadvantages of any other similar platform:</p>
<ul>
	<li>It relies on a database</li>
	<li>It relies on server-side scripting to render pages</li>
	<li>It uses a complex caching mechanism to produce, ultimately, semi-static pages</li>
	<li>It may be subject to exploits, attacks, high server loads, and similar</li>
	<li>You can&#8217;t really customize it beyond a certain point</li>
	<li>You have to upgrade your backend frequently, and often is not as painless as you may expect</li>
	<li>You can&#8217;t use versioning tools like git for your content, as it&#8217;s stored in a database</li>
</ul>
<p>I&#8217;m not claiming that nanoc is blogging&#8217;s silver bullet (it was not created for that), but for sure:</p>
<ul>
	<li>It <em>does not</em> rely on a database</li>
	<li>It <em>does not</em> rely on server-side scripting to render pages (not in real-time, anyway)</li>
	<li>It <em>does not</em> need a complex caching mechanism simply because it produces static pages</li>
	<li>It is definitely less prone to nasty things</li>
	<li>It&#8217;s extremely flexible and hackable with very little effort</li>
	<li>You don&#8217;t have to upgrade all the time, but it is <em>really</em> painless if you decide to</li>
	<li>You can use git and similar: your content is in plain old text files</li>
</ul>
<p>Rants are beside the point, suffice to say I recently convinced myself that switching from Typo to nanoc was a <em>good thing</em>, so let&#8217;s see how it worked out.</p>
<h4>Posts, pages and comments</h4>
<p>Out of Typo&#8217;s MySQL database, I just wanted to get the following data:</p>
<ul>
	<li>Pages and posts</li>
	<li>Tags</li>
	<li>Comments</li>
</ul>
<p>Following the approach used by <a href="http://github.com/mojombo/jekyll">Jekyll</a>, I decided to use the simple and powerful <a href="http://sequel.rubyforge.org/">Sequel</a> gem. I&#8217;m sorry to disappoint you, but the whole migration process can be summarize with the following Rake task:</p>
<div class="highlight"><pre>  <span class="n">task</span> <span class="ss">:migrate</span><span class="p">,</span> <span class="ss">:db</span><span class="p">,</span> <span class="ss">:usr</span><span class="p">,</span> <span class="ss">:pwd</span><span class="p">,</span> <span class="ss">:host</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="p">,</span> <span class="n">args</span><span class="o">|</span>
    <span class="k">raise</span> <span class="no">RuntimeError</span><span class="p">,</span> <span class="s2">&quot;Please provide :db, :usr, :pass&quot;</span> <span class="k">unless</span> <span class="n">args</span><span class="o">[</span><span class="ss">:db</span><span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="n">args</span><span class="o">[</span><span class="ss">:usr</span><span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="n">args</span><span class="o">[</span><span class="ss">:pwd</span><span class="o">]</span>
    <span class="n">db</span> <span class="o">=</span> <span class="no">Sequel</span><span class="o">.</span><span class="n">mysql</span> <span class="n">args</span><span class="o">[</span><span class="ss">:db</span><span class="o">]</span><span class="p">,</span> <span class="ss">:user</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="o">[</span><span class="ss">:usr</span><span class="o">]</span><span class="p">,</span> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="o">[</span><span class="ss">:pwd</span><span class="o">]</span><span class="p">,</span> <span class="ss">:host</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="o">[</span><span class="ss">:host</span><span class="o">]</span> <span class="o">||</span> <span class="s1">&#39;localhost&#39;</span>
    <span class="c1"># Remove all existing pages!</span>
    <span class="n">dir</span> <span class="o">=</span> <span class="no">Pathname</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">Dir</span><span class="o">.</span><span class="n">pwd</span><span class="o">/</span><span class="s1">&#39;content&#39;</span><span class="p">)</span>
    <span class="n">dir</span><span class="o">.</span><span class="n">rmtree</span> <span class="k">if</span> <span class="n">dir</span><span class="o">.</span><span class="n">exist?</span>
    <span class="n">dir</span><span class="o">.</span><span class="n">mkpath</span>
    <span class="c1"># Prepare page data</span>
    <span class="n">dataset</span> <span class="o">=</span> <span class="n">db</span><span class="o">[</span><span class="ss">:contents</span><span class="o">].</span><span class="n">where</span><span class="p">(</span><span class="s2">&quot;state = &#39;published&#39; || type = &#39;Page&#39;&quot;</span><span class="p">)</span>
    <span class="n">total</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">count</span> 
    <span class="n">c</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="n">total_tags</span> <span class="o">=</span> <span class="o">[]</span>
    <span class="n">dataset</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span>
      <span class="nb">puts</span> <span class="s2">&quot;Migrating [</span><span class="si">#{</span><span class="n">c</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">total</span><span class="si">}</span><span class="s2">]: &#39;</span><span class="si">#{</span><span class="n">a</span><span class="o">[</span><span class="ss">:title</span><span class="o">]</span><span class="si">}</span><span class="s2">&#39;...&quot;</span>
      <span class="n">meta</span> <span class="o">=</span> <span class="p">{}</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;tags&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">get_tags</span> <span class="n">a</span><span class="o">[</span><span class="ss">:keywords</span><span class="o">]</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;comments&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">get_comments</span> <span class="n">db</span><span class="p">,</span> <span class="n">a</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;permalink&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">a</span><span class="o">[</span><span class="ss">:permalink</span><span class="o">]</span> <span class="o">||</span> <span class="n">a</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;title&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">a</span><span class="o">[</span><span class="ss">:title</span><span class="o">]</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;type&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">a</span><span class="o">[</span><span class="ss">:type</span><span class="o">].</span><span class="n">downcase</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;date&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">a</span><span class="o">[</span><span class="ss">:published_at</span><span class="o">]</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;toc&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="kp">true</span>
      <span class="n">meta</span><span class="o">[</span><span class="s1">&#39;filters_pre&#39;</span><span class="o">]</span><span class="p">,</span> <span class="n">extension</span> <span class="o">=</span> <span class="n">get_filter</span> <span class="n">db</span><span class="p">,</span> <span class="n">a</span><span class="o">[</span><span class="ss">:text_filter_id</span><span class="o">]</span>
      <span class="n">contents</span> <span class="o">=</span> <span class="n">convert_code_blocks</span> <span class="n">meta</span><span class="p">,</span> <span class="n">a</span><span class="o">[</span><span class="ss">:body</span><span class="o">]+</span><span class="n">a</span><span class="o">[</span><span class="ss">:extended</span><span class="o">].</span><span class="n">to_s</span>
      <span class="n">write_page</span> <span class="n">meta</span><span class="p">,</span> <span class="n">contents</span><span class="p">,</span> <span class="n">extension</span>
      <span class="n">c</span> <span class="o">=</span> <span class="n">c</span><span class="o">+</span><span class="mi">1</span>
    <span class="k">end</span>
  <span class="k">end</span>
</pre>
</div><p>That&#8217;s it. Well, almost: you can find the <code>get_comments</code>, <code>get_tags</code> and <code>get_filter</code> methods in a separate <a href="http://github.com/h3rald/h3rald/tree/master/lib/utils.rb">utility file</a>. Nothing special really, just a few convenience methods wrapping queries or simply processing data. Note how all information, including tags and legacy comments, is saved in each page&#8217;s metadata. The <code>write_page</code> method simply creates a file in the <code>/contents</code> folder.</p>
<h4>Filters and highlighters</h4>
<p>On my old site, I used mainly Textile and Markdown to write posts. However, some of my really old articles used BBCode, whose corresponding filter is not available in nanoc. No worries, I soon found out that creating a new nanoc filter came down to this:</p>
<div class="highlight"><pre><span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;bb-ruby&#39;</span>

<span class="k">class</span> <span class="nc">BbcodeFilter</span> <span class="o">&lt;</span> <span class="no">Nanoc3</span><span class="o">::</span><span class="no">Filter</span>
  <span class="n">identifier</span> <span class="ss">:bbcode</span>

  <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
    <span class="n">content</span><span class="o">.</span><span class="n">bbcode_to_html</span>
  <span class="k">end</span>

<span class="k">end</span>
</pre>
</div><p>Yes, that&#8217;s it. Granted, the <code>bb-ruby</code> gem does all the work, but notice how easy it is to just plug in new Ruby code into nanoc&#8217;s architecture!</p>
<p>The next big challange was code highlighting. After a quick research, I found at least a half dozen of possible solutions to highlight source code. Some were javascript based, others were based on a server-side language like <span class="caps">PHP</span>, Ruby or Python. Again, I looked at Jekyll for inspiration and discovered they integrated the <a href="http://www.pygments.org">Pygments</a> <em>Python</em> library. Why use a Python library for code highlighting in a Ruby-based project? Because there&#8217;s nothing to stop you (if you can run Python on your server, that is), because it looks very neat and because it supports a lot of different programming languages.</p>
<p>Lazy as I am, I more or less dropped <a href="http://github.com/h3rald/h3rald/blob/master/lib/albino.rb">Chris Wanstrath&#8217;s Ruby wrapper</a> into my <code>/lib</code> folder (I just used Open3 instead of Open4 for Windows compatibility), and monkey-patched nanoc&#8217;s filtering helper as follows:</p>
<div class="highlight"><pre><span class="k">module</span> <span class="nn">Nanoc3::Helpers::Filtering</span>

  <span class="k">def</span> <span class="nf">highlight</span><span class="p">(</span><span class="n">syntax</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
    <span class="c1"># Seamlessly ripped off from the filter method...</span>
    <span class="c1"># Capture block</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">capture</span><span class="p">(</span><span class="o">&amp;</span><span class="n">block</span><span class="p">)</span>
    <span class="c1"># Reconvert </span>
    <span class="n">data</span><span class="o">.</span><span class="n">gsub!</span> <span class="sr">/&lt;%/</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
    <span class="c1"># Filter captured data</span>
    <span class="n">filtered_data</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&lt;notextile&gt;&quot;</span><span class="o">+</span><span class="no">Albino</span><span class="o">.</span><span class="n">colorize</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">syntax</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot;&lt;/notextile&gt;</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="k">rescue</span> <span class="n">data</span> 
    <span class="c1"># Append filtered data to buffer</span>
    <span class="n">buffer</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="s1">&#39;_erbout&#39;</span><span class="p">,</span> <span class="n">block</span><span class="o">.</span><span class="n">binding</span><span class="p">)</span>
    <span class="n">buffer</span> <span class="o">&lt;&lt;</span> <span class="n">filtered_data</span>
  <span class="k">end</span>

<span class="k">end</span>

<span class="kp">include</span> <span class="no">Nanoc3</span><span class="o">::</span><span class="no">Helpers</span><span class="o">::</span><span class="no">Filtering</span>
</pre>
</div><p>There you go, another thing sorted.</p>
<h4>Tags and Feeds</h4>
<p>Adding tagging support was a tiny bit more tricky. nanoc supports content tagging out-of-the-box though metadata and a simple helper, but I wanted to create tag pages (with feeds). Nothing too difficult though, it all came down to a simple Rake task:</p>
<div class="highlight"><pre>  <span class="n">task</span> <span class="ss">:tags</span> <span class="k">do</span>
    <span class="n">site</span> <span class="o">=</span> <span class="no">Nanoc3</span><span class="o">::</span><span class="no">Site</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span>
    <span class="n">site</span><span class="o">.</span><span class="n">load_data</span>
    <span class="n">dir</span> <span class="o">=</span> <span class="no">Pathname</span><span class="p">(</span><span class="no">Dir</span><span class="o">.</span><span class="n">pwd</span><span class="p">)</span><span class="o">/</span><span class="s1">&#39;content/tags&#39;</span>
    <span class="n">dir</span><span class="o">.</span><span class="n">rmtree</span> <span class="k">if</span> <span class="n">dir</span><span class="o">.</span><span class="n">exist?</span>
    <span class="n">dir</span><span class="o">.</span><span class="n">mkpath</span>
    <span class="n">tags</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="c1"># Collect tag and page data</span>
    <span class="n">site</span><span class="o">.</span><span class="n">items</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
      <span class="k">next</span> <span class="k">unless</span> <span class="nb">p</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="ss">:tags</span><span class="o">]</span>
      <span class="nb">p</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="ss">:tags</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
        <span class="k">if</span> <span class="n">tags</span><span class="o">[</span><span class="n">t</span><span class="o">]</span>
          <span class="n">tags</span><span class="o">[</span><span class="n">t</span><span class="o">]</span> <span class="o">=</span> <span class="n">tags</span><span class="o">[</span><span class="n">t</span><span class="o">]+</span><span class="mi">1</span>
        <span class="k">else</span>
          <span class="n">tags</span><span class="o">[</span><span class="n">t</span><span class="o">]</span> <span class="o">=</span> <span class="mi">1</span> 
        <span class="k">end</span>
      <span class="k">end</span>
    <span class="k">end</span>
    <span class="c1"># Write pages</span>
    <span class="n">tags</span><span class="o">.</span><span class="n">each_pair</span> <span class="k">do</span> <span class="o">|</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="o">|</span>
      <span class="n">write_tag_page</span> <span class="n">dir</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span>
      <span class="n">write_tag_feed_page</span> <span class="n">dir</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="s1">&#39;RSS&#39;</span>
      <span class="n">write_tag_feed_page</span> <span class="n">dir</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="s1">&#39;Atom&#39;</span>
    <span class="k">end</span>
  <span class="k">end</span>
</pre>
</div><p>Again, you can find all the other simple utility methods in my <a href="http://github.com/h3rald/h3rald/tree/master/lib/utils.rb">utility file</a>.</p>
<p>When it came to feeds, I decided to create a new method for the Blogging helper to create <span class="caps">RSS</span> feeds, although nanoc does come with an Atom feed generator:</p>
<div class="highlight"><pre>  <span class="k">def</span> <span class="nf">rss_feed</span><span class="p">(</span><span class="n">params</span><span class="o">=</span><span class="p">{})</span>
    <span class="nb">require</span> <span class="s1">&#39;builder&#39;</span>
    <span class="nb">require</span> <span class="s1">&#39;time&#39;</span>
    <span class="n">prepare_feed</span> <span class="n">params</span>
    <span class="c1"># Create builder</span>
    <span class="n">buffer</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
    <span class="n">xml</span> <span class="o">=</span> <span class="no">Builder</span><span class="o">::</span><span class="no">XmlMarkup</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:target</span> <span class="o">=&gt;</span> <span class="n">buffer</span><span class="p">,</span> <span class="ss">:indent</span> <span class="o">=&gt;</span> <span class="mi">2</span><span class="p">)</span>
    <span class="c1"># Build feed</span>
    <span class="n">xml</span><span class="o">.</span><span class="n">instruct!</span>
    <span class="n">xml</span><span class="o">.</span><span class="n">rss</span><span class="p">(</span><span class="ss">:version</span> <span class="o">=&gt;</span> <span class="s1">&#39;2.0&#39;</span><span class="p">)</span> <span class="k">do</span>
      <span class="n">xml</span><span class="o">.</span><span class="n">channel</span> <span class="k">do</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">title</span> <span class="vi">@item</span><span class="o">[</span><span class="ss">:title</span><span class="o">]</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">language</span> <span class="s1">&#39;en-us&#39;</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">lastBuildDate</span> <span class="vi">@item</span><span class="o">[</span><span class="ss">:last</span><span class="o">][</span><span class="ss">:date</span><span class="o">].</span><span class="n">rfc822</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">ttl</span> <span class="s1">&#39;40&#39;</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">link</span> <span class="vi">@site</span><span class="o">.</span><span class="n">config</span><span class="o">[</span><span class="ss">:base_url</span><span class="o">]</span>
        <span class="n">xml</span><span class="o">.</span><span class="n">description</span>
        <span class="vi">@item</span><span class="o">[</span><span class="ss">:articles</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span>
          <span class="n">xml</span><span class="o">.</span><span class="n">item</span> <span class="k">do</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">title</span> <span class="n">a</span><span class="o">[</span><span class="ss">:title</span><span class="o">]</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">description</span> <span class="vi">@item</span><span class="o">[</span><span class="ss">:content_proc</span><span class="o">].</span><span class="n">call</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">pubDate</span> <span class="n">a</span><span class="o">[</span><span class="ss">:date</span><span class="o">].</span><span class="n">rfc822</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">guid</span> <span class="n">url_for</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">link</span> <span class="n">url_for</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">author</span> <span class="vi">@site</span><span class="o">.</span><span class="n">config</span><span class="o">[</span><span class="ss">:author_email</span><span class="o">]</span>
            <span class="n">xml</span><span class="o">.</span><span class="n">comments</span> <span class="n">url_for</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="o">+</span><span class="s1">&#39;#comments&#39;</span>
            <span class="n">a</span><span class="o">[</span><span class="ss">:tags</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
              <span class="n">xml</span><span class="o">.</span><span class="n">category</span> <span class="n">t</span>
            <span class="k">end</span>
          <span class="k">end</span>
        <span class="k">end</span>
      <span class="k">end</span>
      <span class="n">buffer</span>
    <span class="k">end</span>
  <span class="k">end</span>
</pre>
</div><p>Nothing too daunting, once you get used to Ruby&#8217;s <span class="caps">XML</span> builder. I followed a similar approach for my <a href="/archives">monthly archives</a></p>
<h4>3rd-party services</h4>
<p>Finally, the interactive bits. I basically turned to third-party services and a bit of jQuery for everything which required user-interaction or pulling data from other web sites. Here&#8217;s a list of services and APIs I currently use:</p>
<ul>
	<li><a href="http://intensedebate.com/">IntenseDebate</a>, for comments.</li>
	<li><a href="http://code.google.com/apis/ajaxsearch/web.html">Google <span class="caps">AJAX</span> Search <span class="caps">API</span></a> for internal site-wide search.</li>
	<li><a href="http://apiwiki.twitter.com/">Twitter <span class="caps">JSON</span> <span class="caps">API</span></a> to fetch tweets.</li>
	<li><a href="http://delicious.com/help/json">Delicious <span class="caps">JSON</span> <span class="caps">API</span></a> to fetch delicious bookmarks.</li>
	<li><a href="http://www.backtype.com/developers">BackType <span class="caps">JSON</span> <span class="caps">API</span></a> to fetch comments from other sites.</li>
	<li><a href="http://develop.github.com/">GitHub <span class="caps">JSON</span> <span class="caps">API</span></a> to fetch GitHub commits for most of my <a href="/projects">projects</a></li>
</ul>
<p>If you want to know how I integrated them, check out my <a href="http://github.com/h3rald/h3rald/tree/master/content/js">/js folder</a>, it was very simple, really.</p>
<h3>Conclusion</h3>
<p>I was very happy of switching to nanoc. It didn&#8217;t take me long, and I spent most of the time with non-nanoc issues (brushing up jQuery, <span class="caps">CSS</span>, graphics, etc.). Of course knowing the Ruby programming language helps, and if you&#8217;re not comfortable with hacking your way a little bit, then maybe it&#8217;s not for you.</p>
<p style="float:left;"><img src="/img/pictures/nanoc-compile.png" alt="" /></p>
<p>Personally, I&#8217;ve been waiting for something like nanoc for a long time: its simple and yet powerful architecture makes you able to do virtually anything with it. For the first time in a long time, I feel like I&#8217;m in complete control of my web site, I know every bits of it and if I want to change the way it works or looks I only have to touch a few files.</p>
<p>nanoc&#8217;s metadata is mindblowing for its simplicity and power: although you&#8217;re not dealing with a database, you can query your content in the easiest ways possible. Whenever I needed a way to easily access pages, filter them, add extra logic to them, I just added metadata. If you forget something, you don&#8217;t have to change your database tables, create new relationships or anything of the sort, you simply add metadata to pages.</p>
<p>Be warned that tweaking nanoc gets addictive very quickly: you soon end up creating silly little tasks for making things just the way you want. For me, adding a new article to my blog now just means this:</p>
<div class="highlight"><pre>$ rake site:article name=take-back-your-site-with-nanoc
$ vim content/articles/take-back-your-site-with-nanoc
... write &amp; close the file ...
$ Nanoc3 compile 
</pre>
</div><p>&#8230;Exactly what I need. Nothing more, nothing less.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-07-26:/articles/11-07-2009/</id>
    <title>11th of July 2009</title>
    <published>2009-07-26T10:54:00Z</published>
    <updated>2009-09-07T10:26:13Z</updated>
    <link href="http://www.h3rald.com/articles/11-07-2009/" rel="alternate"/>
    <category term="wedding" scheme="http://www.h3rald.com/tags/wedding/"/>
    <content type="html">
<![CDATA[
<ul>
	<li><a href="#prologue">Prologue</a></li>
	<li><a href="#party">The wedding party</a></li>
	<li><a href="#stag">The stag night</a></li>
	<li><a href="#preparations">The preparations</a></li>
	<li><a href="#ceremony">The ceremony</a></li>
	<li><a href="#reception">The reception</a></li>
	<li><a href="#honeymoon">The honeymoon</a></li>
	<li><a href="#photos">Photos</a></li>
	<li><a href="#trivia">Trivia</a></li>
	<li><a href="#quotes">Famous quotes</a></li>
</ul>
<h3 id="prologue">Prologue</h3>
<p>Roxanne and I arrived in Ireland on the 3rd of July, just over a week before the wedding day. We thought a week would have been more than enough to finish organizing our big day, and we were right: we spent a few days enjoying our holiday with relatives and going around to meet the photographer, the florist and all the others.</p>
<p>Slowly guests started arriving into the country from Italy, England, Romania etc. For some reason, everyone chose a different day to get to Killenaule, so we had people turning up right until the very day before.</p>
<p>In a similar fashion, I was waiting for my waistcoat to arrive until the last minute: it turns out that the guy I bought it from decided to send it through normal post about 10 days before &#8212; &#8220;They normally arrive in less than two weeks&#8221;, he wrote to me in his last email.</p>
<p>I ended up having to drive to Clonmel the afternoon before the wedding with half the wedding party in my car looking for a waistcoat. I eventually managed to rent one (with matching shirt and cravat) for <em>just</em> 40 Euro.</p>
<h3 id="party">The wedding party</h3>
<p>The following table lists all the members of the wedding party, for your own reference.</p>
<table>
	<tr>
		<th>Name </th>
		<th>Role </th>
	</tr>
	<tr>
		<td> Fabio Cevasco </td>
		<td> Groom </td>
	</tr>
	<tr>
		<td> Roxanne O&#8217;Mahoney </td>
		<td> Bride </td>
	</tr>
	<tr>
		<td> Matteo Lagomarsino </td>
		<td> Best man </td>
	</tr>
	<tr>
		<td> Simona Angheluta </td>
		<td> Maid of Honor </td>
	</tr>
	<tr>
		<td> Roberto Pischedda </td>
		<td> Head Usher </td>
	</tr>
	<tr>
		<td> Delia Angheluta </td>
		<td> Bridesmaid </td>
	</tr>
	<tr>
		<td> Zacharry O&#8217;Mahoney </td>
		<td> Usher </td>
	</tr>
	<tr>
		<td> Caspar O&#8217;Mahoney </td>
		<td> Usher </td>
	</tr>
</table>
<h3 id="stag">The stag night</h3>
<p>In Italy, England, US and in many other countries a &#8220;stag night&#8221; may end up in many different ways: dinner with friends, strip club, wild practical jokes to the groom, and so on. In Ireland, it generally means one thing: <em>drink</em>. It occasionally ends up badly (there are rumors a poor fellow who was thrown out in a river and got married with a broken nose), but generally everything turns out just fine: have a few pints, sing and dance, and have a couple of eggs in the morning. That normally does the trick &#8212; if you&#8217;re an Irishman.</p>
<p>I was well aware of my in-laws drinking habits, so I decided to take uncle Felix&#8217;s offer: &#8220;I&#8217;ll have a taxi ready for you whenever you want to sneak out of the pub, and make sure you do&#8221; &#8212; he said.</p>
<p>The evening started with a few pints at Laffansbridge, an old country pub in the middle of nowhere, probably one of the best places for a pint of Guinnes in the whole Tipperary. The little smart guy who runs it has one simple rule: at midnight the light goes off and no more drinks are served, so all 16 of us got into a minibus by then, heading for the next pub.</p>
<p><em>Quinn&#8217;s</em> is the family pub, in the sense that it is owned by Felix Quinn Jr, son of Felix Quinn Sr, brother of Anastasia Quinn, mother of James O&#8217;Mahoney, father of Roxanne O&#8217;Mahoney, my wife (families are still very large and very close, in Ireland). Being the family pub, <em>Quinn&#8217;s</em> doesn&#8217;t close at midnight; in fact, it often doesn&#8217;t close at all for family and friends (i.e. the entire village of Killenaule).<br />
As soon as we got in, Claire (wife of Felix, son of Felix, etc. etc.) greeted us with a full round of pints, and then another, and yet another&#8230;</p>
<p>Around the third round someone asked me if I could sing a song &#8212; a request I politely but firmly declined due to my total ignorance in Irish folk songs and my total inability to utter sounds in even the slightest musical way. Luckily, someone else volunteered and sang a beautiful ballad, perfectly in-tune, with no music backing at all: Irish people are amazingly musical when sober, imagine when drunk!</p>
<p>When people started getting into <em>their</em> fourth round (note the pronoun), I decided to try out an old trick to keep myself sober: I drank less than half a pint, and then pretended to drink the rest, leaving always something in my glass. In that way &ndash; I thought &ndash; I could pretend I didn&#8217;t need yet another pint. Unfortunately the pub owner spotted me straight away and said &#8220;That pint is stale&#8230; here, have another one, on the house!&#8221;. At that point I decided it was better for me &amp; the rest of the Italians to quietly sneak out.</p>
<p>I was at home (uncle Martin&#8217;s house) and in bed at about 1:30 AM. I almost didn&#8217;t sleep at all that night, as expected, so I wasn&#8217;t too bothered when the rest of the drinking comrades came back, singing and shouting at 4:30 am. Simona [the Maid of Honor and girlfriend of my brother-in-law Zac], on the other hand, wasn&#8217;t too amused when Zac turned up after drinking the (Irish) Nightly Guideline Drink Amount: approx. 10-11 pints of Guinness &#8212; those he could count, that is.</p>
<h3 id="preparations">The preparations</h3>
<p>This part of the day is best reported in chronological tabular form:</p>
<table>
	<tr>
		<th>Time </th>
		<th>Event </th>
	</tr>
	<tr>
		<td> 7:35 </td>
		<td> The groom <del>wakes up</del> decides to stop pretending to sleep. </td>
	</tr>
	<tr>
		<td> 8:00 </td>
		<td> The bridesmaids are up and about, ready to go to the hairdresser </td>
	</tr>
	<tr>
		<td> 9:00 </td>
		<td> Uncle Martin and the rest of the gang slowly regain consciousness. The groom spends about half an hour trying to explain uncle Martin that he&#8217;s his only hope to collect and bring back the flowers for the church (_&quot;Ahhhh you want <em>me</em> to do it&#8230; you could have said so since the beginning!&quot;_). </td>
	</tr>
	<tr>
		<td> 9:45 </td>
		<td> The groom takes the bridesmaids into town, to the hairdresser </td>
	</tr>
	<tr>
		<td> 10:00 </td>
		<td> The groom attempts to gather his groomsmen for the first time </td>
	</tr>
	<tr>
		<td> 10:15 </td>
		<td> The groom starts having a chat with the best man and the head usher. The other ushers are <em>somewhere around</em>. </td>
	</tr>
	<tr>
		<td> 10:30 </td>
		<td> The groom realizes that one of the ushers (Zac) has the most terrible hangover on Earth and the other (Caspar) slept solidly from 3 am (while still in the pub) until now </td>
	</tr>
	<tr>
		<td> 11:00 </td>
		<td> The groom attempts to gather his groomsmen for the second time, this time telling them it&#8217;s time to get ready (he&#8217;s not taken seriously) </td>
	</tr>
	<tr>
		<td> 11:30 </td>
		<td> The groom attempts to gather his groomsmen for the third and final time, now everyone is starting to try out their suits </td>
	</tr>
	<tr>
		<td> 11:45 </td>
		<td> For some weird reason auntie Noelle decides to call the groom and tell him that the florist is not accepting checks, after 5 minuts of absolute panic, she says we&#8217;re going to get the flowers anyway and there&#8217;s nothing to worry about. </td>
	</tr>
	<tr>
		<td> 12:00 </td>
		<td> All groomsman are dressed. It starts raining. </td>
	</tr>
	<tr>
		<td> 12:30 </td>
		<td> Zac decides he needs some fresh air and takes a walk outside in his morning suit, regardless of the heavy rain and the groom&#8217;s prayers </td>
	</tr>
	<tr>
		<td> 13:10 </td>
		<td> The groomsmen go to the church. </td>
	</tr>
	<tr>
		<td> 14:00 </td>
		<td> Guests start arriving </td>
	</tr>
	<tr>
		<td> 14:20 </td>
		<td> The brides arrives and the ceremony starts. </td>
	</tr>
</table>
<h3 id="ceremony">The ceremony</h3>
<p>The wedding ceremony was very suggestive, almost magic. As soon as I looked at Roxanne in her wedding dress all worries faded away, and we both enjoyed the wedding rite. I must say I also don&#8217;t remember much of the whole ceremony, but I&#8217;m told it&#8217;s a common thing to happen.</p>
<p>As the ceremony started, we sat down without looking at the audience, so I didn&#8217;t feel paranoid and enjoyed listening to the priest&#8217;s speech, the readings and the songs. Canon Liam Ryan embodies the typical Irish priest: about 70-year-old, tall, extremely talkative, cheerful and very charismatic. He shocked us all during the reharsal telling us what we&#8217;d have had to do the day after, and it felt like a lot of work. The groomsmen and the bridesmaids were terrified: <em>&#8220;So I have to help you sit down, move the chair&#8230; like that&#8230; then&#8230; go back&#8230; no, wait, what was that again?&#8221;</em>. Matteo and Roberto couldn&#8217;t believe the whole choreography involved in the event: it&#8217;s nothing like that in Italy, but they were glad they were part of it in the end.</p>
<p>It all happened exactly like Father Ryan predicted, he even guessed almost all the few mistakes we made: &#8220;You have to walk slowly in front of the bride&#8221; &ndash; he said to Delia, the bridesmain &ndash; &#8220;and if you <em>think</em> you&#8217;re going slow while you&#8217;re doing it, you&#8217;re probably going <em>way too fast</em>&#8221;. But nobody noticed, really, and nobody cared: they were all too excited to mind that, and everyone&#8217;s eyes were on Roxanne, anyway. She was really, really gorgeous and her dress was fabulous. It felt unreal, at times: we both felt we were in one of those movies&#8230;</p>
<p>The most peculiar thing about the whole ceremony was perhaps the different languages involved: English, Italian, Gaelic and Latin. I doubt there was a single person among us who could understand the entirety of the mass, but it was very evocatory. The whole mass was predominantly in English, with the following exceptions:</p>
<ul>
	<li>The First Reading was in Latin (my mum read it superbly &#8212; she&#8217;s a Latin teacher!)</li>
	<li>The Second Reading was in Italian</li>
	<li><em>Our Father</em> was sung in Gaelic</li>
</ul>
<p>By our own common decision, we didn&#8217;t ask for a professional video of the ceremony, only <a href="#photos">photos</a>. Nevertheless, my uncle captured most of the ceremony (and the most embarassing bits of the dancing after the <a href="#reception">reception</a>) using my dad&#8217;s video camera.</p>
<h3 id="reception">The reception</h3>
<p>When the ceremony ended it was still raining heavily, so after an endless amount of pictures taken we went straight into our Rolls. Technically, that was not <em>our</em> Rolls of course: we rented it from a local car hirer, and it was worth every penny. A lot of people get married in a VW Beatle or in a Mercedes at most, but Roxanne and I really love old cars, so when we saw <a href="http://www.alleventslimos.com/Wedding/rolls_silver_cloud.html">Ruby</a>, a red 1961 Silver Cloud II, we just had to get it. Champagne and chauffeur included, of course.</p>
<p>The chauffeur was a very jolly and chatty fellow from Waterford, and drove that beauty of a car for a very long time. Unfortunately though his sat nav decided to stop working and he wasn&#8217;t really <em>local</em>, so erhm&#8230;, well, let&#8217;s just say we were really lucky that at least <em>the bride</em>knew her way around. We made it safe and sound to Raheen House in no time: so fast that everyone else arrived about 10-15 minutes afterwards.</p>
<p><a href="http://www.raheenhouse.ie/">Raheen House</a> is a very charming <span class="caps">XIX</span> century Georgian House. One of those places you normally see only in movies: tapestries on the walls, old armchairs, stuffed heads over the doors (an african buffalo, a huge deer, an antelope, and some more)&#8230; you get the picture. Unfortunately it can only accomodate 120 people, so it isn&#8217;t a very popular location for wedding receptions in Ireland, because the number of people invited at Irish weddings ranges from 150 to 300. We were about 60 in total, nevertheless the dining hall looked quite full and lively, with 7 big tables covering all the room.</p>
<p>As soon as we got there, my best man was informed by the staff that he <em>had to</em> introduce the bride and groom. <em>&#8220;What? No, wait! What do I say&#8230; how&#8230; what? Fabio, come back!&#8221;</em> he freaked out, but as soon as I wrote down the two lines he was supposed to say in English everything was OK. Not only did he introduce us properly, he also made a <em>terrific</em> speech: he obviously gave it a lot of thought and it sounded just perfect.</p>
<p>After he spoke, it was my dad&#8217;s turn. Now, my dad speaks perfect French but never got a chance to learn and practice English (yet), so not only he had to write down his entire speech, he also had to annotate the pronunciation of <em>every</em> word. He managed fine though. It felt a little bit long, but he said really wonderful and touching words about Roxanne and I, our respective families, and countries. I&#8217;ll publish it soon on the Internet, for posterity&#8217;s sake.</p>
<p>The last three speeches were Jim&#8217;s (the father of the bride), who did great as always, without reading anything, right on the spot. And so did Roxanne and I: we basically just said a few words thanking all the guests for coming, and half of them for helping us with the wedding as well. Every speech (except mine and Roxanne&#8217;s) was characterized by subtle and very discreet exhortations to produce progeny (<em>&#8220;get on with it!&#8221;</em>), but other than that they were fine.</p>
<p>After all the traditional obligations, we finally started our dinner. The food was delicious and extremely tasty: Raheen House is renown for that, as we were told, but we honestly weren&#8217;t 100% sure until we started trying it. And there was also <em>plenty</em> of it, so everyone felt really satisfied towards the end of the meal. So satisfied that we decided to postpone the cake till later (see below) and indulge with wine instead.</p>
<p>Wine, right. They were going to charge us 20€ per bottle for some weird Chilean or Australian stuff. Silly and almost offending, especially considering that my family has been producing wine for family and friend&#8217;s use for at least three generations! This was my dad&#8217;s primary concern until we left for Ireland: &#8220;You sort the restaurant out, because I&#8217;m going to bring some bottles, no matter what&#8221;. He shipped over <em>96</em> special bottles of our 2005, 2006, 2007 and 2008 vintages. Ninety-six. We used about 25 of them for the meal and the rest of the evening, then we gave one to almost every guest, three to the staff of the restaurant, a few more to other hotel and B&amp;B owners, six to each uncle of the bride, etc. etc. None came back to Italy, that&#8217;s for sure.</p>
<p>Right after the meal the band came in, and we got ready to dance. Roxanne and I had to start with our First Dance, of course, then everyone else slowly joined in. The group was playing a mixture of traditional Irish music, ballads and rock &#8216;n&#8217; roll: they were amazing, and especially the Italian&#8217;s were really impressed.</p>
<p>Not as impressed as when they noticed uncle Martin dancing. I&#8217;ve never seen <em>anyone</em> in my life dancing so vigorously and wildly in my life. He has his own special technique that cannot be described with words. I&#8217;ll try to post a video of him soon. He really felt the rythm and never missed a step. Like a whirlwind he dragged everyone in, dancing with him: first his daughters and sons, then his brothers, the he thought he&#8217;d take my auntie for a spin, then the bride (well, mostly her dress), then even me! I don&#8217;t remember much, I think I was in the air at one point, and then all over the place&#8230;</p>
<p>Everyone of course joined in and started drinking and dancing for the whole evening. When the band performed the last two songs, I just remember a <em>huge</em> circle of nearly all the guests holding hands dancing around Roxanne and I, then coming closer, then far, then closer again. It was definitely the wildest night in our whole life.</p>
<h3 id="honeymoon">The honeymoon</h3>
<p>The day after we slowly recovered. We didn&#8217;t sleep much, but we managed to get up and have breakfast with some of the guests at the hotel, before they started heading back. Then we decided to go shopping in town: it was basically Roxanne and I, plus her brothers, her parents, and my parents. Not much of a honeymoon, as my mum pointed out, but we didn&#8217;t mind.</p>
<p>After spending the following day saying goodbye and thanks to all the relatives, we finally headed to Co. Galway, in Connemara. We booked three nights in the fabulous <a href="http://www.abbeyglen.ie/">Abbeyglen Castle</a>, highly recommended. Our superior room had a fireplace, a four-poster bed and jacuzzi bath: the bare essentials for a honeymoon really. Roxanne and I really enjoyed those three days, finally alone in the most breathtaking and romantic area of Ireland. Three days weren&#8217;t enough, really, but we&#8217;ll eventually go back there hopefully: maybe Sir Paul Hughes, proprietor of the castle, will still remember <em>&#8220;the bride and groom&#8221;</em>, as he kept calling us throughout our brief, but very pleasant stay.</p>
<p>Exactly as auntie Noelle said, everything was over in a blink: the ceremony, the reception, the honeymoon&#8230; everything went back to normal, eventually. It took a while to get used to our normal life: we had to go on a shopping spree before we went back to work&#8230; let&#8217;s say the money we got as present from most of the guest was well spent in a 42&quot; <span class="caps">LCD</span> HD TV, surround sound system, etc. etc.</p>
<p>&#8230;And we still have our other half of the honeymoon, too! Probably Miami Beach and Bahamas, next November.</p>
<h3 id="photos">Photos</h3>
<p>Our wedding photos were taken by <a href="http://www.patmccoole.ie/">Pat McCoole</a>, who did a truly amazing job portraying the magic of our special day.</p>
<p><embed type="application/x-shockwave-flash" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&hl=en_US&feat=flashalbum&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fh3rald%2Falbumid%2F5359762418204291649%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></p>
<h3 id="trivia">Trivia</h3>
<ul>
	<li>On the wedding day, it rained non-stop from 12 am to 7 pm.</li>
	<li>The groom drove for a total of 1758.7 Km in 14 days.</li>
	<li>On his stag night, the groom only drank 2.5 pints of Guinness (almost everyone else had 10, on average).</li>
	<li>The night before the wedding, the groom slept only from 5:30 to 7:30.</li>
	<li>Only the middle tier of the wedding cake was eaten on the wedding day. The top tier was eaten during the following days by relatives and the bottom tier was shipped to Italy, together with the Bride&#8217;s dress.</li>
	<li>The father of the bride decided to change into more comfortable clothes right after the ceremony. He borrowed a waistoat and a jacket for the speech.</li>
	<li>Uncle Martin danced with a lot of people after the meal, including the bride, her father, and the groom.</li>
	<li>When he arrived at the church, the groom immediately realized he left the mass booklets and the confetti in the back of his car, at home. They were eventually brought to the church by a cousin of the bride just a few minutes before she arrived.</li>
	<li>At the very start of the ceremony, the groom told the priest to tell the best man to get a mass booklet so that he and the bride can follow the mass properly. After 30 seconds of lip-reading and signalling, the best man understood and fetched one of the infamous booklets.</li>
	<li>The bride forgot her change of clothes in uncle John&#8217;s car, who had to drive in early in the morning or she would have had her breakfast in her wedding dress.</li>
</ul>
<h3 id="quotes">Famous quotes</h3>
<blockquote>
<p>&#8220;This journey feels like going to Lourdes: you come back and your life changed forever.&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8212; The best man, when he arrived in Killenaule.</p>
</blockquote>
<blockquote>
<p>&#8220;Is there a garage around?&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; Auntie Isa while waving a car mirror, when she arrived in Killenaule</p>
</blockquote>
<blockquote>
<p>&#8220;Do I really have to do a speech? Are you sure?&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; The best man, when he met the groom in Ireland.</p>
</blockquote>
<blockquote>
<p>&#8220;My preciousssss!&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; The best man, when he was given the rings in custody.</p>
</blockquote>
<blockquote>
<p>&#8220;She&#8217;s the most calm and organized bride in history.&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; Auntie Noelle, about the bride on the wedding day.</p>
</blockquote>
<blockquote>
<p>&#8220;You could tell he was panicking on the phone&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; Auntie Noelle, about the groom on the wedding day.</p>
</blockquote>
<blockquote>
<p>&#8220;Potatoes, potatoes, potatoes&#8230;&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; The father of the bride to the groom, during the traditional handshake of the wedding rehearsal.</p>
</blockquote>
<blockquote>
<p>&#8220;Potatoes, potatoes, potatoes&#8230;&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; The groom to the father of the bride, during the traditional handshake of the wedding ceremony.</p>
</blockquote>
<blockquote>
<p><strong>Best man:</strong> &#8220;[&#8230;] this is the first time for me to speak in public, in front of an <em>English</em> audience [&#8230;]&#8221;<br />
<strong>Audience:</strong> &#8220;Irish! <span class="caps">IRISH</span>!!!&#8221;<br />
<strong>Best man:</strong> &#8220;&#8230;oh, right, Irish! Sorry&#8230;&#8221;<br /></p>
</blockquote>
<blockquote>
<p>&#8220;I need another shirt!&#8221;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; Uncle Martin, after about 2 hours of continuous dancing with almost all the guests.</p>
</blockquote>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-06-29:/articles/log-jun-2009/</id>
    <title>Personal Log - June 2009</title>
    <published>2009-06-29T00:24:00Z</published>
    <updated>2009-09-06T18:10:47Z</updated>
    <link href="http://www.h3rald.com/articles/log-jun-2009/" rel="alternate"/>
    <category term="personal_log" scheme="http://www.h3rald.com/tags/personal_log/"/>
    <category term="vim" scheme="http://www.h3rald.com/tags/vim/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="wedding" scheme="http://www.h3rald.com/tags/wedding/"/>
    <content type="html">
<![CDATA[
<p>Welcome to yet another of my extremely boring, excessively fragmented <a href="/tags/personal_log">personal log</a> posts. I&#8217;m seriously thinking of dropping the whole series in favor of more frequent (and shorter) blog posts, starting from next year. This means you&#8217;ll probably have to read <em>another six</em> of these priceless gems, until december 2009.<br />
As usual, feel free to skim through as each of the following <em>sections</em> is almost completely unrelated to the others.</p>
<h3>H3RALD Web Site v8.0</h3>
<p>It&#8217;s the time of the year, again. It doesn&#8217;t happen <em>every</em> year but it&#8217;s definitely a trend (hence the high version number): I&#8217;m going to redesign &amp; redevelop my web site.</p>
<p>This time is not the usual &#8220;Let&#8217;s pick another language and another framework and start from scratch&#8221;, but a rather more radical shift, and yet at the same time less painful. The idea is to transform H3RALD.com into a 100% static web site, without losing anything in functionality (gaining, if anything!).</p>
<p><a href="/http://tom.preston-werner.com/">Tom Preston-Werner</a> is definitely <em>not</em> the first person to <a href="http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html">blog like a hacker</a>, and his very own <a href="http://www.jekyllrb.com/">Jekyll</a> is definitely not the first static web site generator our there, nevertheless, he inspired me to embrace what seems to be one of the latest trend in developer&#8217;s blogs.</p>
<p>The idea is simple: turn all the blog posts and pages into static content, and rely on third party web services for things like comments, search etc. For a rather extreme by very interesting example, see <a href="http://tagaholic.me/">Tagaholic</a>.</p>
<p>The advantages of this approach are many:</p>
<ul>
	<li>Free yourself from a database.</li>
	<li>Free yourself from a resource-hungry, server-side app (<a href="http://wiki.github.com/fdv/typo/">Typo</a>, in this case).</li>
	<li>Increase speed and reliability, without using caching or similar artifacts.</li>
	<li>Keep everything under version control.</li>
	<li>Don&#8217;t worry about breaking things when upgrading (even if the static content generator changes, it shouldn&#8217;t really break things).</li>
	<li>Unleash the power of client-side scripting (namely, JQuery).</li>
</ul>
<p>For now, I&#8217;m just brainstorming a little bit on <a href="http://github.com/h3rald/h3rald-website/issues">GitHub</a>, feel free to participate. The first step is obviously choosing a static content generator, and atm Jekyll seems to be slightly ahead of Webby. Opinions?</p>
<h3>Glyph</h3>
<p>Did you ever want to write a short manual or a book, or even a long article? If so, chances are you gave LaTeX a shot and either fully embraced its philosophy or totally refused it. Sadly, I belong to the second category: I believe sequential documents like manuals or books should be easier to create simply by using <span class="caps">HTML</span>.</p>
<p>Whever I have a chance to actually start working on it, Glyph will become a <em>document authoring framework</em>, i.e. a way to create visually appealing documents in a simple way. All the ingredients are there, it&#8217;s only necessary to glue them together in a pretty form:</p>
<ul>
	<li>Textile (and <a href="http://redcloth.org/">RedCloth</a>) to produce clean <span class="caps">HTML</span> code from a human-readable markup</li>
	<li>CSS3 to specify page rules</li>
	<li>A few rake scripts to produce a standalone <span class="caps">HTML</span> file, <span class="caps">TOC</span>, Index etc.</li>
	<li>An internal <span class="caps">DSL</span> for the document structure and metadata</li>
	<li><a href="http://www.liquidmarkup.org/">Liquid</a> for control flow, snippets and filters</li>
	<li><a href="http://www.princexml.com/">PrinceXML</a> to generate a <span class="caps">PDF</span> from <span class="caps">HTML</span></li>
</ul>
<p>This project is still in planning stage, feel free to have a look at the <a href="http://github.com/h3rald/glyph/issues">issues/features page</a> on GitHub. Feedback is appreciated, as usual.</p>
<h3>Vim files &amp; <em>the Stash</em></h3>
<p>If you read the previous two sections of this post, you may have noticed that I&#8217;m growing more and more fond of git (and GitHub). Besides the repositories I already mentioned earlier on, I also created a personal <a href="http://github.com/h3rald/stash">stash</a>, which I&#8217;m using mainly to store some of my Linux dotfiles, article drafts and &#8230;Vim customizations.</p>
<p>If you&#8217;re looking for a color scheme for Vim, check out my very own <a href="/herald-vim-color-scheme">herald.vim</a>, and tell me what you think.</p>
<h3>Getting ready for the Big Step</h3>
<p>This will probably be my last post as a free man, as I&#8217;m getting married (civilly) on July 2nd and (religiously) on July 11th. <br />
Luckily the photographer agreed to give us a CD with all the pictures taken on the big day, with no copyright restrictions attached to it (believe it or not, some photographers don&#8217;t allow you to republish <em>your own</em> photos unless you ask them first), so I&#8217;ll probably write a long post with pictures when we come back from our (half) honeymoon.</p>
<p>Everything is pretty much organized. We had troubles with the waistcoats we got from eBay: they were cut almost randomly to <em>resamble</em> waistcoats, but they weren&#8217;t so we had to re-order another lot of 7 sets (waistcoat, cravat <em>and</em> shirt this time) from another seller, this time UK-based. I seriously hope to get them in time.</p>
<p>On the 24th we&#8217;re having a party at our house. If you were invited, feel free to drop by, otherwise be prepared to be thrown out of the window (4th floor) by one of our ushers (Roxanne&#8217;s <em>big</em> brother). It&#8217;s probalby going to be about 30-40 people in the end, mainly because most of my office can&#8217;t come due to holidays they booked in advance.</p>
<p>What&#8217;s left to do now? Well:</p>
<ul>
	<li>Send the bomboniere over to Ireland</li>
	<li>Make sure my dad actually ships the 96 specially-bottled bottles of our own wine to uncle John, in Ireland.</li>
	<li>Make sure uncle John doesn&#8217;t drink all the 96 bottles of wine before the wedding reception.</li>
	<li>Make sure my best man understood that the speech he has do make <em>must</em> be in English, at least 3 minutes long and not too offensive to the groom.</li>
	<li>Pay a huge, colossal heap of money for the whole thing. It&#8217;s going to cost us (and my dad) quite a bit, in the end. But it&#8217;s a once-in-a-lifetime experience, after all (getting totally trashed in a fancy hotel with all your family, including 2nd and 3rd grade cousins).</li>
</ul>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-06-17:/articles/herald-vim-color-scheme/</id>
    <title>Herald (Vim Color Scheme)</title>
    <published>2009-06-17T04:11:00Z</published>
    <updated>2009-11-07T19:31:41Z</updated>
    <link href="http://www.h3rald.com/articles/herald-vim-color-scheme/" rel="alternate"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="vim" scheme="http://www.h3rald.com/tags/vim/"/>
    <content type="html">
<![CDATA[
<p>I use <a href="http://www.vim.org">Vim</a> a lot. It&#8217;s my editor of choice when I code (mainly in Ruby), and also when I write my blog post and articles (mainly in Textile).<br />
One thing I always liked about Vim was it powerful syntax highlighting: there&#8217;s probably a syntax highlighting file for every programming language ever created, even the new ones (<a href="http://force7.de/nimrod/index.html">Nimrod</a>? Sure, <a href="http://www.vim.org/scripts/script.php?script_id=2632">here</a>!).</p>
<p>Furthermore, Vim allows you to create color schemes, and that&#8217;s surprisingly easy to do. Everything you need to do is in the <a href="http://vimdoc.sourceforge.net/htmldoc/syntax.html">docs</a>, but that may put you off, so you can just start by editing an existing one &#8212; that&#8217;s what I did.h3. InfiniteRed Black</p>
<p>I&#8217;ve been using the <a href="http://blog.infinitered.com/entries/show/8">ir_black</a> color scheme for near enough a year. It&#8217;s an excellent color scheme, recommended especially for writing Ruby code:</p>
<p><img src="/images/herald.vim/ir_black_vim_example.png" alt="" /></p>
<p>I honestly thought this was the best Vim color scheme until I discovered Moria&#8230;</p>
<h3>Moria</h3>
<p>Recently I switched to <a href="http://www.vim.org/scripts/script.php?script_id=1464">moria</a>, mainly because I find it easier on the eyes. It&#8217;s a matter of taste, of course:</p>
<p><img src="/images/herald.vim/moria_vim_example.png" alt="" /></p>
<p>The trick is in the background: it&#8217;s not completely black. Still, I didn&#8217;t quite like the colors, so I decided to write my own&#8230;</p>
<h3>Herald</h3>
<p>Meet <strong> <a href="/files/herald.vim">herald.vim</a> </strong> (this is a direct link to the raw file, but you may also want to check my <a href="http://github.com/h3rald/stash/tree/master">stash</a> on GitHub or the <a href="http://www.vim.org/scripts/script.php?script_id=2684">script page</a> on Vim.org):</p>
<p><img src="/images/herald.vim/herald_vim_example.png" alt="" /></p>
<p>To sum up, here&#8217;s the <em>features</em> offered by this new color scheme:</p>
<ul>
	<li>It&#8217;s easier to differentiate syntax elements; in particular reserved words like <code>if</code> or <code>end</code>, constants (symbols) and identifiers (instance variables).</li>
	<li>Operators are highlighted and easier to notice.</li>
	<li>Dark gray background and black column/row selectors.</li>
	<li>Added highlight for titles (useful for Textile)</li>
	<li>Comments do not stand out, unlike in most color schemes</li>
	<li>Support for 256 color terminal (special thanks to <a href="http://www.frexx.de/xterm-256-notes/">Wolfgang Frisch</a> for providing all the info and tools required)</li>
</ul>
<p>So what do you think? Is it tool colorful perhaps? How would <strong>you</strong> improve it?</p>]]>
    </content>
  </entry>
</feed>
