In the last tutorial, we saw how to install Hobix, and how to setup in order to produce our blog (using default configuration values). Today, let’s dig in hobix configuration files and architecture in order to better understand what happens under the hood..
.hobixrc (note the leading dot):
misc> cat /home/sleeper/.hobixrc --- weblogs: dev-null: /home/sleeper/weblog/dev-null/hobix.yaml dev-null-test: /home/sleeper/weblog/dev-null-test/hobix.yaml bloggie: /home/sleeper/weblogs/bloggie/hobix.yaml post upgen: true username: sleeper personal: name: Frederick Ros url: http://sl33p3r.free.fr/blog/ email: sl33p3r@free.fr use editor: true misc>
As you can see it links all the blogs it’s managing to a given configuration file (generally named hobix.yaml).
It also stores additional information like your username, real name, and all the things you answered to the question it asked you during installation.
ls -l weblogs/bloggie/ total 4 drwxr-xr-x 5 sleeper users 152 jan 20 01:02 entries -rw-r--r-- 1 sleeper users 551 jan 20 00:23 hobix.yaml drwxr-xr-x 7 sleeper users 320 jan 20 01:03 htdocs drwxr-xr-x 2 sleeper users 368 jan 20 00:21 skel
We can see 3 directories and a file hobix.yaml.
hobix.yaml is the configuration file for this blog, and will be reviewed in the next section.
Directories are:
htdocs : this is the default directory where your generated blog’s files goentries : this is where your article files (entry) are located. It can be subdivided into directories to indicate sectionsskel : this is where the templates for your blog are located. We will see it in more detailed in few minutes.Besides these 3 directories, you can also have another directory called lib where all the 3rd party scripts (or you’re own) are located.
entries directory:
misc> ls -l weblogs/bloggie/entries/ total 4 drwxr-xr-x 2 sleeper users 72 jan 20 00:30 about drwxr-xr-x 2 sleeper users 176 jan 20 00:30 blog -rw-r--r-- 1 sleeper users 276 jan 20 01:03 index.hobix drwxr-xr-x 2 sleeper users 80 jan 20 01:03 misc misc>You can see that our
bloggie currently has 3 sections:
about : this is one of the default sectionsblog : this is one of the default sectionsmisc : this is the section we have added in last tutorial.and if we look in misc section for example:
misc> ls -l weblogs/bloggie/entries/misc/ total 4 -rw-r--r-- 1 sleeper users 198 jan 20 01:03 GoodMorning.yaml misc>
We found there the post we wrote in last tutorial.
So basically, we’ve learn that:htdocs holds your generated blog. This is there that you eventually will want to copy images or CSS files.skel holds your templates (Yiiikkss … it means we can tune our beloved bloggie)entries holds your post, and is partitioned to reflect the logical sections of your blog.The most interesting file (as a blog author) is hobix.yaml. It’s the heart of the blog configuration and tuning.
Let’s look at it:
misc> cat weblogs/bloggie/hobix.yaml
--- !hobix.com,2004/weblog
title: A test weblog
link: http://bloggie
tagline: To test .. for ever
period: 00:60:00
authors:
sleeper:
name: Frederick Ros
url: http://bloggie
email: jdoe@nowhere.org
linklist: !hobix.com,2004/linklist
links: !omap
-
hobix: http://hobix.com/
-
del.icio.us: http://del.icio.us/
sections:
about:
ignore: true
sort_by: id
requires:
- hobix/storage/filesys
- hobix/out/quick
- hobix/out/erb
- hobix/out/rss
- hobix/out/okaynews
- hobix/out/atom
misc>
OK. Amongs all the fields we can see some simple to understand:
title the blog title as you entered it when configuringlink link to your blog.tagline the sub title you enteredauthors list of authors for this blog, with their email and link to their web page. Currently there’s only one author.period indicates the frequency of the blog update. It is expressed in secondslinklist this is basically an ordered list (the !omap stuff) of links. This can be used as content for a generated sidebar holding the links you want to share with others.sections denotes the special directories that will act as hidden categories. Adding content there won’t add it in your frontpage as another post for example. In our case, the about section acts as a hidden categories, and will be ignored.requires this is the list of plugins your blog requires. You can add other plugins depending on your needs. Note that some of the plugins can have configuration values too. As you can see, by default our blog will need all the syndication related plugins, as well as the erb and quick ones (for templating purpose).entries), output (htdocs), templates (skel) and plugins (lib) directories.
You can set these directories to other values, using the following fields:
entry_path to set the path where posts can be foundoutput_path to set the path of the directory where generated files will goskel_path to set the path of the template directorylib_path to set the plugins directory pathNote that the path can be relative ones (in this case their are relative to the directory where hobix.yaml is located), or absolute ones.
Hobix allow you full templating of your generated blog. As you can see, it proposes default values for this templates (the one we currently use), but also allow the user to use several way of templating its blog.
All the templates that will be used are located in the skel directory.
skel directoryAs said before this directory stores the templates. Let’s have a look at its default content:
misc> ls -l weblogs/bloggie/skel/ total 0 -rw-r--r-- 1 sleeper users 0 jan 20 00:21 entry.html.quick -rw-r--r-- 1 sleeper users 0 jan 20 00:21 index.atom.atom -rw-r--r-- 1 sleeper users 0 jan 20 00:21 index.html.quick-summary -rw-r--r-- 1 sleeper users 0 jan 20 00:21 index.xml.rss -rw-r--r-- 1 sleeper users 0 jan 20 00:21 index.yaml.okaynews -rw-r--r-- 1 sleeper users 0 jan 20 00:21 monthly.html.quick-archive -rw-r--r-- 1 sleeper users 0 jan 20 00:21 section.html.quick-archive -rw-r--r-- 1 sleeper users 0 jan 20 00:21 yearly.html.quick-archive misc>
OK. First on size. As you perhaps noticed, all of this template files are empty (size is 0). This is due to the fact that these files act as a hint on what Hobix will have to generate, and eventually on how it should generate it. In our case (null size) they are just acting as hint, and the default templates are used.
As you can see, all of these file names follow the same patternfile-extension1-extension2.
The file part is a hint on the content of the file to be generated:
entry generates all the archived posts in htdocs/category/entry-id.extension1index generates a file containing the last 10 entries in htdocs/index.extension1daily generates a daily archive of entries (htdocs/year/month/day/index.html)monthly generates a month archive of entries (htdocs/year/month/index.html)yearly generates a yearly archive of entries (htdocs/year/index.html)sections generates a per-section index (htdocs/category/index.html)The extension1 indicate the extension to use for the generated file.
extension2 indicates the plugin that will process the file. This can be (for example):
erb : the file will be parsed through ERb to produce output file. See ERb section belowredrum : this is basically ERb + RedClothquick, quick-summary, quick-archive) : ERb templates broken in YAMl chunks. They have huge advantage when trying to design a consistent blog.atom / rss / okaynews : to generate syndication formats.and others as you can add plugins …
<% ... %> and <%= ... %>.
Code between <% and %> will be executed as the page is read, and variable between <%= and %> will be output to the page.
Besides that every templates is given 3 variables when it is evaluated. These 3 variables can be used in Ruby chunks:
weblog : This is the Hobix::Weblog object, and as thus it contains all the information of the hobix.yaml file, and even more (as it also contains the list of entries and so on)page : is an Hobix::Page object; which holds information about the currently generated page. This can for example be used to produce arrows on your HTML page to next or previous entry.entries (or entry) : contains one or more Hobix::Entry object, which are used for this page. If the prefix of the template name is entry (for example entry.html.erb), only one entry is passed, in the @entry variable. For all other templates (for example index.html.erb) the entries variable is passed, as an Array of Hobix::Entry objects.For example, if you put the following in an index.html.erb file in your skel directory:
<% entries.each do |e| %>
<div class="titleBar">
<div class="entryTitle"><%= e.title %></div>
<div class="entryDate"><%= e.created.strftime( "%m %d %Y" ) %></div>
</div>
<div class="entryBody">
<%= e.content.to_html %>
</div>
<% end %>
You will be generated something like
<div class="titleBar">
<div class="entryTitle"> Entry tile </div>
<div class="entryDate">01 25 2005</div>
</div>
<div class="entryBody">
My dear blog, ....
</div>
for each of the entries present in the entries variable.
Redrum, as said before, is ERb + RedCloth. So the same rules applies, except that you can use RedCloth instead of HTML.
Quick templates are the cleverest thing that ever existed in the templating world. ;) Technically speaking they are ERb templates (again !!) splited into YAML chunks.
The enormous advantage they have is that you can express some kind of inheritance, and redefine only the part you need, for all you blog or only for specific pages.
This is the templating system we’ll use for tuning our blog.
Let’s look at the default Quick template:
--- %YAML:1.0
# Full page formatting
page: |
<+ doctype +>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<title><+ title +></title>
<+ head_tags +>
<style type="text/css">
<+ css +>
</style>
</head>
<body>
<div id="page">
<+ banner +>
<div id="content">
<+ sidebar +>
<+ blog +>
</div>
</div>
</body>
</html>
# Headers and titling
doctype: |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
head_tags:
css: |
@import "/site.css";
title: <%= weblog.title %>
banner: |
<div id="banner">
<h1 class="title">
<a href="<%= weblog.link %>"><%= weblog.title %></a></h1>
<div class="tagline"><%= weblog.tagline %></div>
</div>
# Sidebar components
sidebar: |
<div id="sidebar">
<+ sidebar_list +>
</div>
sidebar_list: ['sidebar_archive', 'sidebar_links',
'sidebar_syndicate', 'sidebar_hobix']
sidebar_archive: |
<div class="sidebarBox">
<h2 class="sidebarTitle">Archive</h2>
<ul>
<% months = weblog.storage.get_months( weblog.storage.find ) %>
<% months.each do |month_start, month_end, month_id| %>
<li><a href="<%= month_id %>"><%=
month_start.strftime( "%B %Y" ) %></a></li>
<% end %>
</ul>
</div>
sidebar_links: |
<div class="sidebarBox">
<h2 class="sidebarTitle">Links</h2>
<%= weblog.linklist.content.to_html %>
</div>
sidebar_syndicate: |
<div class="sidebarBox">
<h2 class="sidebarTitle">Syndicate</h2>
<ul>
<li><a href="/index.xml">RSS 2.0</a></li>
</ul>
</div>
sidebar_hobix: |
<div class="sidebarBox">
<p>Built upon <a href="http://hobix.com">Hobix</a></p>
</div>
# Blog content
blog: |
<div id="blog">
<+ entries +>
</div>
entries: |
<% entries.each_day do |day, day_entries| %>
<+ day_header +>
<% day_entries.each do |entry| %>
<+ entry +>
<% end %>
<% end %>
day_header: |
<h2 class="dayHeader"><%= day.strftime( "%A, %B %d, %Y" ) %></h2>
# Entry appearance
entry: |
<div class="entry">
<+ entry_title +>
<+ entry_content +>
</div>
<div class="entryFooter"><+ entry_footer +></div>
entry_title: |
<h3 class="entryTitle"><%= entry.title %></h3>
<% if entry.tagline %><div class="entryTagline"><%=
entry.tagline %></div><% end %>
entry_content: |
<div class="entryContent"><%= entry.content.to_html %></div>
entry_footer: |
posted by <%= weblog.authors[entry.author]['name'] %> |
<a href="<%= entry.link %>"><%=
entry.created.strftime( "%I:%M %p" ) %></a>
A little bit long, but .. hey .. this is the template of your blog.
Each YAML chunk has a name (for example entry_title), and can be used through the construct <+ name +> (so in our example <+ entry_title +>).
If you look at the files in skel you will find that we’re using index.html.quick-summary. It’s using the exact template we just saw, except that the entry summary is displayed (if it exists) instead of the entry content. In our case we won’t see any difference by using index.html.quick-summary, or index.html.quick.
index.html.quick-summary, and create an empty index.html.quick.
misc> touch weblogs/bloggie/skel/index.html.quick misc> rm weblogs/bloggie/skel/index.html.quick-summary
OK. So now, let’s suppose we’re not happy with the day header of each entry as it appears on the index page. It is currently defined, in the default template, as:
day_header: |
<h2 class="dayHeader"><%= day.strftime( "%A, %B %d, %Y" ) %></h2>
which will produce something along:
<h2 class="dayHeader">Tuesday, February 08, 2005</h2>
Let’s pretend we want to be more terse, and display the day header as something like:
On 2005/01/25 :
To do so, let’s edit our index.html.quick, and change day_header into:
day_header: |
<h2 class="dayHeader">On <%= day.strftime( "%Y/%m/%d" ) %>:</h2>
Let’s also suppose we do not want to have the tag-line displayed, and the title to be all uppercase. By modifying the banner from
banner: |
<div id="banner">
<h1 class="title">
<a href="<%= weblog.link %>"><%= weblog.title %></a></h1>
<div class="tagline"><%= weblog.tagline %></div>
</div>
to
banner: |
<div id="banner">
<h1 class="title">
<a href="<%= weblog.link %>"><%= weblog.title.upcase %></a></h1>
</div>
in our index.html.quick, we should do the trick.
So let’s now regenerate bloggie:

Note that if you look at a given entry (for example GoodMorning), you can notice that the changes we made are not taken into account (which is normal as GoodMorning is generated using the entry.html.quick template).

Now what if you want to define a style for all of your pages ?? This is simple: you need to redefine the default Quick template, in a place which is page independent … in hobix.yaml !!
So if we want our title to be uppercase on all of our pages, we change the line :
- hobix/out/quick
in hobix.yaml to add configuration :
- hobix/out/quick:
banner: |
<div id="banner">
<h1 class="title">
<a href="<%= weblog.link %>"><%= weblog.title.upcase %></a></h1>
</div>
and remove this definition from index.html.quick (as it is now empty). We then regenerate bloggie and check that everything is OK (both on index.html and on GoodMorning.html pages):

and

Yipeee !! Super-simple isn’t it ???
OK, so now play with this and define your own style … In next tutorial we’ll try to go even further ;)