Building Small Sites with Webby

Webby is ideal for a content archive, a small business or governmental website, and even small catalogs that link to PayPal for commerce. Here, learn how to use Webby to create a site fast.

I recently converted a closet into a large bookshelf to accommodate my burgeoning collection of ancient geek artifacts—programming books, computer equipments, and toys. At the outset, I marched off to Home Depot to buy supplies and realized I needed a level to align screws horizontally and vertically. Levels come in all sizes and materials, and since I use one so rarely, I elected for a $7, yand-long, plastic knock-off. Sure, it looked like something Bob the Builder would use, but it got the job done, and I used the extra cash to buy Do-It-Yourself Home Repair with Bob the Builder to tackle a separate lighting project.

Website development tools are as varied as real tools. For example, there are any number of ways to launch a blog: you can write plain HTML; you can install and run specialized blog software; you can prop up and customize a content management system such as Drupal or Radiant; and you can build your own authoring software based on your favorite programming language and framework.

What tool to choose depends on the needs of your site and your own aptitudes. For some scenarios, custom development is the only option; for others, an off-the-shelf but extensible package akin to Drupal is apropos; and for yet others, a hosted solution such as WordPress suffices. And for a good number of sites—especially those for small businesses—static HTML is a viable option.

Static HTML may seem like an anachronism, but it has advantages: a static site deploys with nothing but (S)FTP; there are no moving parts other than the Web server; and the entire site is plain text. Of course, you have to edit HTML and CSS directly, but even that is tolerable.

Tolerable, yes. Advised? Hardly. There are real benefits to segregating text from template, as is customary for dynamic, database-driven sites: You can maintain style separately, generate multiple pages from a single blueprint, and readily edit content without the distraction of a complex page.

Webby bridges the gap between an entirely static site and a dynamic site. With Webby, you create whole HTML documents or snippets of content as source; Webby copies or transforms the source into a complete collection of static pages ready to deploy as a website. Webby is ideal for a content archive that rarely changes but expands in small increments, a small business or governmental website (a “brochure site”), and even small catalogs that link to PayPal for commerce.

Here, let’s build a small site with Webby to see how the application works. Webby is written in Ruby and uses rake (the Ruby flavor of make) extensively, but you don’t need mad Ruby skills to use it. Webby is provided as two, self-contained command-line utilities, webby-gen and webby. The former is a convenience to initialize Webby projects; the latter generates the website from source.

Installing Webby

To use Webby, you must install Ruby and RubyGems and install Webby and a number of helpers. Ruby and RubyGems are widely available as distribution packages. For example, for Ubuntu or other Debian-like distributions, you can use Aptitude.

$ sudo apt-get install ruby1.8 ruby1.8-dev rubygems1.8

Once RubyGems is installed, you can install Webby and the supplemental gems that process additional markup languages.

$ sudo gem install webby haml coderay ultraviolet \
  RedCloth rdiscount bones cucumber

The gem command installs the named gems and all prerequisites. (On the test machine, the gems cucumber and bones weren’t automatically installed. If you have the two gems, omit both from the command-line.)

To check the install, run webby-gen -t and webby --help.

$ webby-gen -t
Available Templates
    blog, presentation, tumblog, website

$ webby --help
Usage: webby [options] target [target args]
…

Building a Webby Site

To build a Webby site, you can author static pages—HTML documents, style sheets, JavaScript code, and so on—and generate static pages from content and layouts. Combined, all the static pages, independent of origin, are processed, copied to a local staging directory, and pushed to the Web server.

Webby manages three kinds of resources or documents.

  • A file is static content and is copied verbatim to the staging area.
  • A page is a snippet of content expressed in HTML or any of the markup languages supported by Webby and supplemental filters. A page can be processed by none, one, or many filters before it is staged.
  • A layout wraps each page (as defined immediately above), providing the HTML wrapper and perhaps a header and a footer. A layout is used to unify the appearance of multiple pages.

All of these resources are stored in a Webby-specific hierarchy created by webby-gen. Each hierarchy represents one website.

  • The output directory is used to stage the website.
  • The content directory contains file and page resources. Every resource in this directory is copied from its location to a corresponding location in the output directory. For instance, the directory content/css is copied to output/css. File resources are copied as-is to the output directory. Page resources are processed once or many times and then copied.
  • The layouts directory contains layouts.
  • The tasks directory defines rake tasks, or convenient commands to generate, re-generate, and copy the website to a server, among other niceties.
  • The templates directory contains small documents that can be reused over and over again to bootstrap a page. webby-gen provides some templates initially, and you can create your own as well.

To begin, select one of the webby-gen templates to generate a new site skeleton. This example creates a blog.

$ webby-gen blog myblog
…

The command generates the hierarchy described earlier rooted at ./myblog and pre-populates the templates directory with a template for a posting, a monthly index, and an annual index. Each template has a header delimited by --- and a body. If you examine blog/post.rb, you should see something like this in the header:

---
title:      <%= title %>
created_at: <%= Time.now.to_y %>
blog_post:  true
filter:
  - textile
---

The header contains settings represented as key: value pairs. Some keys are special, such as filter; otherwise, you can create your own keys. A value can be fixed or can be generated dynamically via ERB.

Here, the blog post template assigns a title and a time stamp when a new blog post is made. The title variable (within <% and %>) is passed in from Webby when the template is instantiated. The (arbitrary) key blog_post is set to true, intended as a flag to denote this type of page as a post. filter is a special, reserved key that can list no, one, or many filters to apply in sequence in the order listed. The default filter is ERB, but you can use any of the filters installed earlier, too. Each key is accessible to code embedded in the body of the template.

To create a new post, use webby and give the posting a title.

$ webby blog:post dinojr
[13:15:02]  INFO: creating content/blog/2009/index.txt
[13:15:02]  INFO: creating content/blog/2009/06/index.txt
[13:15:02]  INFO: creating content/blog/2009/06/23/dinojr.txt

The new posting is found at content/blog/2009/06/23/dinojr.txt and the build automatically generates two indices, one for the year and one for the month. The indices are updated automatically every time you build the site.

Open dinojr.txt in your favorite text editor. It should now look like this:

---
title:      Dinojr
created_at: 2009-06-23 13:15:02.398335 -04:00
blog_post:  true
filter:
  - textile
---

Edit the header and insert - haml at the head of the list of filters. (Since Haml is sensitive to whitespace, it must run first.) Next, change the body of the post to include Textile and Haml markup.

---
title:      Dinojr
created_at: 2009-06-23 13:15:02.398335 -04:00
blog_post:  true
filter:
  - haml
  - textile
---

%h2 Dinosaur, Jr. on the *Farm*

.story
    %p
        J Mascis and company have released a second studio album
        after reforming in 2007.

To generate the site, run Webby again with build task.

$ webby build
update  output/blog/2009/index.html
update  output/blog/2009/06/index.html
update  output/blog/2009/06/23/.dinojr.txt.swp
update  output/blog/2009/06/23/dinojr.html

The new posting, dinojr.txt, is filtered first through Haml and then Textile; that intermediate result is then wrapped in the default layout, since no specific layout was specified. Finally, the result is copied to its destination, nicely organized in blog by year, month, and day of month. Ignoring the preamble of the resulting HTML file, dinojr.html, the output should resemble this:

<h2>Dinosaur, Jr. on the <strong>Farm</strong></h2>
  <div class='story'>
    <p>
      J Mascis and company have released a second studio album
      after reforming in 2007.
    </p>
</div>

After a build, the contents of the output directory can be copied to the docroot of your website. Webby offers commands to deploy the code via rsync or ssh.

To deploy the site, edit the Sitefile and include your login name, the host name of the Web server, and the target directory.

SITE.user = 'martin'
SITE.host = 'example.org'
SITE.remote_dir = '/var/www/martin/' 

Now run webby deploy:ssh.

$ webby deploy:ssh

Webby Whirlwind

Webby has a lot more features. You can run Webby in “daemon” mode to constantly refresh output. You can use rsync instead of ssh, if you prefer. And you even embed ERB in templates to be carried over into a page. For example. look at the template for the monthly index.

<%%
  articles = @pages.find(:all,
    :in_directory => @page.dir,
    :recursive => true,
    :sort_by => "created_at",
    :reverse => true, :blog_post => true)
  articles.delete(@page)
  paginate(articles, 10) do |page|
-%>
  <div class="article">
    <h1><%%= link_to_page(page) %>
      <span class="date">(<%%= page.created_at.strftime('%Y-%m-%d') %>)
      </span>
    </h1>

    <div class="body">
      <%%= render(page) %>
    </div>
  </div>
<%% end -%>

<%%= link_to("Prev", @pager.prev) if @pager.prev? %>
<%%= link_to("Next", @pager.next) if @pager.next? %>

Anything marked with %% in the template is copied to each new page instance as ERB. Hence, the monthly index created by webby build looks like this:

---
title:      2009
created_at: 2009-06-23 13:15:02.392017 -04:00
filter:     erb
dirty:      true
---
<h2><%= h(@page.title) %></h2>

<%
  articles = @pages.find(:all,
    :in_directory => @page.dir,
    :recursive => true,
    :sort_by => "created_at",
    :reverse => true, :blog_post => true)
  articles.delete(@page)
  paginate(articles, 10) do |page|
-%>
<div class="article">
  <h1><%= link_to_page(page) %>
    <span class="date">(<%= page.created_at.strftime('%Y-%m-%d') %>)
    </span>
  </h1>

  <div class="body">
    <%= render(page) %>
  </div>
</div>
<% end -%>

<%= link_to("Prev", @pager.prev) if @pager.prev? %>
<%= link_to("Next", @pager.next) if @pager.next? %>

Webby enumerates all the blog posts in the same directory as the index page resource and emits a new page for each ten blog posts. The code at bottom creates a series of links to tie the suite of index pages together.

The documentation for Webby is a little sparse, but the system is fairly small and easy to deduce. If you search Github for Webby, you can find useful examples to bootstrap your own effort.

Happy tinkering!

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62