David Area translated this page to Spanish.

1. Back story

I came across a cool way to throw together a site and thought I'd do a real quick writeup on how to put it all together. It's a simple process that allows me to produce content efficiently without having to use heavy weight tools (frameworks or GUIs) to get the job done. Finally I can focus on content without having to resort to a WYSIWYG tool and still get nicely formatted pages. But first, some background.

I have developed websites in Python (CGI and Django), PHP, Perl, .NET, Java (Struts, WebWork, Java Server Faces) and finally Ruby on Rails. However, I don't always have the need to do a full-blown, database backed website that uses a complicated framework. Sometimes simple HTML will suffice.

But, as a code slinger, having to repeat anything more than once gives me an uneasy feeling. In creating static HTML documents there's a lot of repetition. A style sheet will probably refer to the same colors many times for example. HTML documents will have a consistent footer. Also, I'm approaching my lifetime maximum of HTML slung. I really don't want to do it anymore. It's also worth mentioning that using a gooey tool is not an option for me.

Given that background and these goals what's a boy to do? Well for me personally I came up with a duct-tape solution that seems to do the trick.

Here are the tools:

2. Towards a solution

I've been sitting on a domain name for a long time and finally decided to start putting content up. I had no need for a fancy framework or a database, just simple HTML done intelligently.

I started with a cascading style sheet. I like to steal inspiration online but I feel strongly that I want to start from scratch, I enjoy the creative process even if it is just color schemes. Really, how often do developers get to play with color schemes. A typical page will have a handful of colors. The background, the main font color, maybe a flair color for links and wherever you want someones attention and so on.

So you get your style sheet ready and you want to attempt various schemes. To do this normally you'd have to change the same value in multiple places in the file. This is painful. I want to define something once and refer to it multiple times.

3. Enter m4

m4 is a macro language present on most Unix machines. It allows you to do some simple macro definitions at the top of your CSS and then refer to those in multiple places throughout.

Here's how the top of my style.css looks:

  define(`std_flair_color',      `#aa0000')
  define(`std_dark_color',       `#666666')
  define(`std_light_color',      `#dddddd')
  define(`std_background_color', `#eeeeee')
  define(`std_font', `Tahoma, Arial, Helvetica, sans-serif;')
  define(`navlist_width', `130')
  define(`banner_height', `30')
  define(`footer_height', `13')
  
  h1 {
  font-weight: bold;
  font-size: 150%;
  color: std_dark_color;
  background-color: std_light_color;
  border-left: 8px solid std_dark_color;
  border-bottom: 1px solid std_flair_color;
  }

It should be obvious what's going on here. You can see how easy it is to play with the colors. To tweak any of the shading is a simple matter of changing it in one place.

You can use m4 for more than this. There is some overlap between m4 and txt2tags, they both can pull other files into the current document. But I wanted to go with txt2tags for the bulk of my work.

4. txt2tags

txt2tags is another useful tool that you can find on various Unices. The tool scoops up text files that follow a simple markup convention and turns them into some sort of tagged format; HTML, XHTML, SGML on and on. The markeup format it uses is very similar to what most wikis would have you type.

For example some simple markup like this:

  //italics// and  **bold** 

Becomes:

italics and bold

It also accepts other directives to include other files into the current document. With a switch I tell txt2tags to only create an HTML snippet and not an entire document. Now with that I can put that document inside of a structure, like a header, navigation area and footer.

Here's how the include looks for the footer:

  %!include(html): ''../html/footer.html''

You can also do find and replace on the included HTML document. For example, in a text file that I write I can define the title of the page. When the header gets pulled in txt2tags replaces the title for me.

Here's a longer snippet of t2t markup to give you a better idea:

  You could **bold** //italicize// or __underline__ words.
  - bullets are also
  - super easy to
  - put together
  - links [are easy too http://neidetcher.com]
  - or you can just type the url and txt2tags knows what to do with it: http://neidetcher.com
  - even email addresses get handled correctly demian0311@gmail.com

The above markup is rendered like this:

You could bold italicize or underline words.

5. make to the rescue

So this is all good but there are lots of command line things to do. Normally I'd reach for ant to automate my programming tasks in the Java world but for now make is the perfect tool.

We probably all know make. Graybeard programmers tell of the frustration in dealing with a tool where whitespace is important (I'm a huge Python fan myself). But make works, it does the job. Shut up and use it.

Here's what my make file looks like:

  all: compile
  
  clean:
          rm -rf dist/
          rm -rf assemble/
          mkdir -p assemble/html
          mkdir -p dist
          mkdir dist/css
          mkdir dist/resource
  
  compile: clean
          cp -Rf src/html/* dist
          cp -Rf src/resource dist
          m4 src/css/style.css > dist/css/style.css
          m4 src/html/header.html > assemble/html/header.html
          m4 src/html/footer.html > assemble/html/footer.html
          txt2tags -t html --no-headers src/text/*.t2t 
          mv src/text/*.html dist
  
  dist: compile
          tar -cvf neidetcher.com.tar dist/
          gzip neidetcher.com.tar

While we're at it, this is what the directory structure looks like for my project:

  |-- assemble
  |-- bin
  |-- dist
  |   `-- (all the output goes here)
  |-- makefile
  `-- src
      |-- css
      |   `-- style.css
      |-- html
      |   |-- footer.html
      |   |-- header.html
      |-- resource
      |   |-- buzz_free_guide_to_soa.pdf
      |   `-- tdd_and_beyond.pdf
      `-- text
          |-- code.t2t
          |-- contact.t2t
          |-- main.t2t
          |-- resume.t2t
          |-- static_site_creation.t2t
          `-- writing.t2t

6. Conclusion

Here are some general points about what we're left with