24 February 2010

About this Blog

Style

Each post is uniquely styled within a grid.

Sinatra

Generates static pages and graphics. Styles code samples.

No SQL

Not even a database! File-based metadata.

Haml

Powers article templates and markup.

SASS/CSS

Comprehensive and reusable styling.

JavaScript

Taking it further…custom behavior & graphics.

Style

Before there were blogs we had websites. Beautiful, random websites that felt more like a zine — one page looking nothing like the one before or after it.

Greg Storey, Airbag Industries1

Many developments in computer science have nothing to do with the capabilities of computers, but with the way we use them.

A few years ago, an article on Airbag Industries1 inspired me to think about writing a blog with a unique design per post.

There are many benefits:

  • It encourages creativity both at the computer and away from it
  • It’s like a code kata for design
  • You can easily experiment with cutting-edge CSS3 features or just learn CSS2
  • You’ll learn how to build a style foundation for other designs in other applications

On the downside, it takes more time than simply writing prose.

Building an art-directed blog may seem as easy as dropping an extra CSS link tag into every blog post, but a little extra work upfront makes it a lot easier.

First, I started with a layout grid in CSS. Grids have been used extensively in print design but have only recently become popular in website design. I like Tyler Tate’s 1kb grid2 because it’s the simplest thing necessary to accomplish the task.

In standard website design, elements can be placed anywhere on a page. In contrast, a grid defines boundaries in regular increments, limiting the possibilities. Instead of stifling creativity, it encourages experimentation by making it easier to think about a finite number of widths for text or images.

I use a 12 column grid (double-click anywhere on this page to see it). Twelve columns are easily divided into other increments: 12 · 6+6 · 2+5+5 · 4+4+4 · 3+3+3+3

Sinatra

The Sinatra web framework has a beautiful REST API, can be extremely powerful, and is super fast.

It’s easily deployed with Phusion Passenger alongside my other Rack-based web applications.

I started with the Nesta4 blog engine and enhanced it with the additional CSS and graphic generation features I needed. All pages are cached statically with Sinatra::Cache5 for even greater speed. Although this blog could be generated with a static site generator, I find it more natural to write it in a dynamic style.

One example is the generation of text headline images with the Textorize6 renderer from Thomas Fuchs. I reference the images by URL in my CSS files. Sinatra generates the graphic on the fly when that URL is accesed (then caches it). Sinatra keeps URLs at the forefront of the web developer’s mind — where they should be!

Other resources are generated at the view level when needed. Code snippets are formatted by the Pygments7 command-line script via a special RedCloth tag implemented as a Haml filter.

textorize

Textorize (right half) renders text edges smoothly.

No SQL

heading: About this Blog
heading-font: Klavika-BoldCondensed
heading-color: #000
heading-background: transparent
published: December 30 2019 at 6pm
categories: meta design
summary: An article about...
format: haml

.column.article
  %h2 Bacon

  :custom
    Haml and textile together...

It’s much eaiser to debug a visual design in development on the local machine, check the whole thing into Git, and deploy when ready. No need to write an authentication system or an article preview mechanism.

Article files are stored on disk with a bit of YAML-esque metadata at the top. Each article can be in Textile format, or can use the full power of Haml for more complicated markup.

Early on I needed to store information about the title’s font size and color. Later I needed to add other custom fields for additional tagging. With an ORM this would have meant writing a migration and installing a plugin to manage tags.

There was no such problem here! I just added a few key-value pairs to the article’s metadata and started using them in the application immediately.

Haml

Not only does each post get its own CSS, it can also specify its own HTML, via Haml8.

When I’m designing visually in the browser, I’m thinking primarily about blocks of text and images, and how they will be styled. I don’t want to be thinking about HTML boilerplate or need to hunt to find a matching end tag.

Haml decreases the mental distance between HTML and CSS. I work directly with CSS selectors no matter what file I happen to be in.

But Haml isn’t well suited to working with inline text. Fortunately, there’s Textile9 for that!

The differences between the basic syntaxes of Textile and Markdown are negligible. Where it pulls away from Markdown is when you add new tags of your own. You can write view helpers that take a simple string and turn it into a group of HTML tags. It’s not only faster to type, but I can build reusable elements for movie links, syntax-highlighted code snippets, pull quotes, and product boxes.

Textile enhancements are easily used inline within any Haml document. In RedCloth 4, the steps are:

  • Write a module with methods for each of the tags you want to use (such as movie at right).
  • In each method, examine the :text key in the options, then build and return an HTML string. I build links for the mov and m4v versions of each movie.
  • Write a Haml filter. The name of your module will be used as the name of the filter.
  • Extend RedCloth with your custom module.
  • Add more methods to your tags module as needed.

The code samples at right were built this way. I specify a path to a source file and it runs it through pygmentize. It also prepends a link to the source file itself.

The end result is a text system customized for writing about code, but it looks great, too! I can’t imagine using a CMS that was any less powerful than this.

.column.article

  %h2 Custom Filter Sample
 
  :custom_red_cloth

    movie. http://example.com/movie.mov

    source. /tutorials/code.rb

    buy. http://peepcode.com/products
module CustomTags
  
  def movie(opts)
    my_text = opts[:text]
    # Build an HTML string around my_text
    # ...
    return my_text
  end
  
end
module Haml
  module Filters

    # Renders custom textile.    
    module CustomRedCloth
      include ::Haml::Filters::Base
      lazy_require 'custom_tags'

      def render(text)
        red_cloth = ::RedCloth.new(text)
        red_cloth.hard_breaks = false
        red_cloth.extend CustomTags
        red_cloth.to_html
      end
    end
  end
end

SASS/CSS

@import ../page_util
@import ../pygments_pastie

+masthead-reset
+dark-logo
+dark-masthead-menu

!base_color = #d1e3ff

.prose
  +grid_6
  float: left
  margin:
    left = !grid_gutter_width
    top  = !line_height*5

Archives page with screenshots

In a recent copy of Print Magazine11, someone talked about designing a “style sheet” for the magazine back in the 70’s. For some reason, the extra space jolted my brain into thinking differently. Style. Sheet.

A stylesheet isn’t supposed to be a receptacle into which one tosses a bunch of unrelated visual directives. It’s a coherent guideline for how things should look. It should be planned and reusable. And like backend code, it may take several iterations of use in the real world to get it right.

SASS is a huge part of achieving that concept in this blog.

People get emotional when they hear about SASS. Either they see it as a threat to traditional CSS (used only by hacks who haven’t taken the time to learn it) or they welcome it as the best thing to happen to the Internet.

After working with this blog for a few months, I’m in the second camp.

As an example, any page can be designed with a light or a dark background. A few mixins at the top automatically adjust the page background, logo color (implemented as an image sprite), and menu colors. All these are contained in the stylesheet and don’t require any modification of the page’s HTML.

The technical parts of the grid and vertical rhythm are also wired into my SASS stylesheets. I can give elements meaningful names in HTML, then specify +grid_6 in SASS to make the element six columns wide (alternately, I could have used arguments like grid(6)).

Variables like grid_gutter_width and line_height are available to the whole application. I rarely type a number; instead I use meaningful variables to add margins or manipulate elements into position.

And if I’m going to spend that much time in the powder room, I want to show it off. The archives page uses webkit2png.py10 to take a screenshot of each page and display it in a grid.

JavaScript

A unique design for each post is great, but how about unique JavaScript for each post?

For my Rails 3 upgrade screencast, I wanted to show a timeline of Rails release dates. I’ve recently become enamored with RaphaelJS12 and it took only a few lines of code to import a JavaScript file for posts that want one.

I wrote a custom Timeline function that plots dates as large dots.

Conclusion

As with many features of this blog, it will take a while to figure out how to use them all fully. In the meantime, it’s a great learning experience and a fun output for creativity.

I haven’t published the source yet and may never. But now you have the ideas…implement them on your own blog!

In an earlier post, RaphaelJS was used to chart Rails release dates.

jQuery(function () {

  var paper = Raphael("graph", 940, 81),
    timeline;

  timeline = new Timeline(paper, [
    {date:"06/25/2004", version:"0.5"},
    {date:"12/13/2005", version:"1.0.0"},
    {date:"12/07/2007", version:"2.0.0"},
    {date:"6/10/2010",  version:"3.0 ?"}
  ]);

});

1 Airbag Industries wrote on the old days when blogs were designed like zines.

2 The 1kb grid is the simplest thing necessary to get the job done. I convert it to SASS with the included css2sass command.

3 With a hack to ruby-mode in Emacs, I can easily jump to any Sinatra URL handler in a file.

4 Nesta is a minimal blog engine by Graham Ashton (but easy to extend). It’s built on the Sinatra web framework.

5 Sinatra::Cache source code

6 Textorize text renderer

7 Pygments is the best syntax highlighter out there. When you view diffs and code at GitHub, you’re viewing pygments. Pipe code to it on the command line.

8 The Haml template engine is available for Ruby and other languages.

9 Textile is a syntax for formatting prose.

10 webkit2png.py is a capable screenshot capturing script for Mac OS X. There’s a Ruby port, but the original works well enough that I don’t see the need. I’ve wrapped it in the osxscreenshot gem.

11 Print Magazine is a classic (over 70 years in publication). Baseline Magazine is a more academic European counterpart. I recently bought a subscription to both.

12 RaphaelJS is a JavaScript-based SVG drawing library.

13 The Plainview web browser is a full-screen browser, useful not only for HTML-based presentations.