Coolnamehere

May 4, 2008

Purpose

Filed under: Uncategorized — Tags: — coolnamehere @ 10:34 am

I’ve been thinking about it, and I decided that this would be my new geek blog. My Blogger account just hasn’t been cutting it for me for a while. Not that it’s a bad system, but it doesn’t seem quite as nice as WordPress.

There probably won’t be a lot of posts here any time soon. Work’s been keeping me very busy, and when I’m not busy I’m poking through How to Think Like a (Python) Programmer. That’s a fun book, incidentally. There’s no new educational matter if you already know Python, but I like the way it’s organized and the exercises are great fun.

I’ll eventually have something to write about and the time to write about it, though. I’m sure you’ll be on pins and needles waiting for it.

February 10, 2008

First Post

Filed under: Uncategorized — coolnamehere @ 12:54 pm

I’m just exploring different hosted blog systems right now. I have been thinking a lot about switching my site over to a blog-based system, which does mean transferring content and doing something about categories. My blogger account seems a little straitjacketed for all the stuff I’m thinking of, so now I’m looking at WordPress. Impressions so far? It’s pretty.

Hello world!

Filed under: Uncategorized — coolnamehere @ 12:50 pm

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!

February 1, 2008

Updating coolnamehere’s design

Filed under: coolnamehere, design — coolnamehere @ 6:07 pm

It’s time to revamp coolnamehere.

I’ve been using a tweaked version of the Greenery template at OSWD for a couple of years now, and I think it’s time for a change. This time I actually concocted my own design using one of my photos and Yahoo’s YUI (I had so much fun with YUI on my church site that I had to try it out on my own site).

Here’s a screenshot of the old design:

There are a lot of things I liked about this design. The grass image dividing the columns gave the site an attractive and natural touch that had been missing before. On the other hand, I felt the need to tweak it so that it would work in all the browsers I used. It’s nice, though. Much better than the designs I had been coming up with on my own.

The new design has been widely praised by my sample group of two incredibly non-biased people: my wife and my brother. Okay, I will concede that they may have a bias. I like it in general, though. It’s very … Seattle. Clouds, water, scotch bloom.

The design is still in progress. For starters, I hate the navtree menu. That navtree is starting to look a little cumbersome, actually, and is making me rethink how I want to handle navigation through the site. Maybe a simple subpage listing such as the one generated by ZenWeb. I’m also looking at new publishing options, and the one that is most attractive to me right now is Blosxom. It’s relatively old. It is also ridiculously easy to use and fairly straightforward to enhance.

Oh, and I need to sort through the CSS, and probably the content itself. Oh well, at least all the pages are in order.

January 30, 2008

PHP’s extract and compact functions

Filed under: php, tidbit — coolnamehere @ 6:51 pm

I’ve been brushing up on my PHP basics lately. Why? Well, it never hurts to
revisit things you think you already know. There is a good chance you will
discover something you didn’t know after all. For example: this time I
learned about PHP’s extract and compact functions.

extract takes an associative array and creates local variables on the fly, named for the keys in the array and with the corresponding values matched up. compact is the corresponding function for taking a collection of variables and stuffing them into an associative array.

<?php

    $book = array(
        "title"     => "Dad's Own Cookbook",
        "author"    => "Bob Sloan",
    );

    extract($book);
    echo $title . " was written by " . $author . "\n";

    $first = "Brian";
    $last  = "Wisti";
    $keys  = array("first", "last");
    $my_name = compact($keys);
    print_r($my_name);
?>

Running this code:

$ php -f extract-compact.php
Dad's Own Cookbook was written by Bob Sloan
Array
(
    [first] => Brian
    [last] => Wisti
)

extract is the more immediately useful of the two for my purposes, because
it simplifies a common tactic I use for creating local variables based on
database lookups.

Instead of manually creating local variables, like this:

<?php

    # ...
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
        $author = $row["author"];
        $title  = $row["title"];
        # ...
    }
?>

I can save myself a little effort with extract.

<?php

    # ...
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
        extract($row);
        # ...
    }
?>

I realize that there may be an even easier way to do it, but just this will
make my life noticeably easier as long as I don’t abuse it. I would mainly
tuck a call like this off in a function and probably use it in conjunction with
a SQL query or something else where I knew exactly what names I would end up with.

Why didn’t I know about this before? Well, the manual approach was good enough.
And since what I had was good enough, I didn’t think of looking for a better
approach. Then again, finds like this are exactly why I do go back and review
what I thought I already knew.

January 12, 2008

SiteTemplate Hiccup

Filed under: ruby, sitetemplate, writers block — coolnamehere @ 10:49 am

I’m trying to work out the next part of my Site generation series. There’s two problems. Writing the code is more interesting than the blow-by-blow account of how the code was written. I suspect anybody reading this would be more interested in using the library I’m talking about rather than writing it. I don’t really know, though, since what traffic I get is coming read about my messing with the Google API in Python. I’m pretty sure this series is for my own amusement, so maybe I’ll work on the code and then write a nice post about how to use it. Well, it’s 3 am. I don’t need to decide right now.

January 8, 2008

REBOL 3 alpha released

Filed under: rebol — coolnamehere @ 10:16 pm

I just saw Petr Krenzelok’s giddy announcement on the REBOL mailing list that a public alpha of REBOL 3 is available today. I’ve been waiting to see this for a while and can’t even begin to describe how excited I am.

The official announcement is here. I just need to remember that it’s an alpha. Pieces aren’t going to work. Things will be strange. But it’s out there for the bold to play with.

Of course I gotta get some work done, but you can be sure I’ll be poking at this over the next couple of days.

January 7, 2008

PageTemplate for Site Generation Part 2

Filed under: pagetemplate, ruby, sitetemplate — coolnamehere @ 10:15 pm

I’ve got my code filtering
Markdown

and now I want to stuff that filtered content into an HTML page. I could just use
maruku#to_html_document, but I need the ability to add details like a title and
site-related links.

I could use a format similar to my Python blog
files
. I won’t really need
PageTemplate if I do that, though. Not for the content file, anyways. That’s okay, though. The Maruku filter
was more of a proof-of-concept, anyways. PageTemplate will be useful for fitting the generated content into an
actual template, though.

That means I’m starting over on my content files.

Given a content file that looks like this:

title: A Simple Page
--
This page intentionally left blank.

I want an object that makes the title available in some way (simple Hash style access is fine), and makes the
HTML-formatted content available. After a few minutes of fiddling and poking around, I end up with tests and
application code.

Article Test Code

#!/usr/local/bin/ruby

require 'test/unit'
require 'SiteTemplate'

class TC_Article < Test::Unit::TestCase
    def test_article_file()
        article_file = 'simple.txt'
        assert(article = Article.new(article_file))
        assert_equal(article_file, article.source_file)
        assert_equal('A Simple Page', article.metadata['title'])
        assert(article.content =~ %r{<p>This page intentionally left blank.</p>})
    end
end

The Application Code

#!/usr/local/bin/ruby

require 'rubygems'
require 'maruku'

# A single HTML page generated by a content file
#
# Content files usually look like this:
#
#    title: My Title
#    --
#    Article contents
class Article
    attr_reader :source_file, :metadata, :content
    def initialize(filename)
        @metadata = {}
        parse!(filename)
    end

    def parse!(filename)
        @source_file = filename
        content = ''
        in_content = false
        File.open(filename).each_line do |line|
            if in_content then
                content << line
            else
                if line =~ /^--$/ then
                    in_content = true
                    next
                end

                if line =~ /^(\w+?):\s*(.+)$/ then
                    key = $1
                    value = $2
                    @metadata[key] = value
                end
            end
        end

        @content = Maruku.new(content).to_html
    end
end

It’s a really simple, slow parser, but it works. I won’t try to optimize it before I’ve actually figured out
what it’s supposed to be doing.

The Template

The next target is stuffing this content into a template. That’s easy. Here’s the template:

simple.html Template File

<html>
    <head>
        <title>[%var title%]</title>
    </head>
    <body>
        <h1>[%var title%]</h1>
        [%var content%]
    </body>
</html>

I could assemble my page manually if I felt like it. As a matter of fact, let’s do that in one of the tests.

Manual Page Generation Test

require 'PageTemplate'

class TC_HTML_Page < Test::Unit::TestCase
    def test_manual_page_generation()
        article_file = 'simple.txt'
        template = PageTemplate.new()
        template.load('simple.html')
        article = Article.new(article_file)
        template['title'] = article.metadata['title']
        template['content'] = article.content
        assert_match(%r{<title>A Simple Page</title>}, template.output)
    end
end

Do I really want to manually apply even that little bit of code, though? No, I don’t.

Automatic Page Generation Test

class TC_HTML_Page < Test::Unit::TestCase
    def test_standard_page_generation
        article_file = 'simple.txt'
        template_file = 'simple.html'
        assert(html_page = HTML_Page.new(:article => article_file, :template => template_file))
        assert_match(%r{<title>A Simple Page</title>}, html_page.to_html)
        assert_match(%r{<p>This page}, html_page.to_html)
    end
end

Automatic Page Generation Code

require 'PageTemplate'

class HTML_Page
    def initialize(opts = {})
        @article = Article.new(opts[:article])
        @template = PageTemplate.new()
        @template.load(opts[:template])
    end

    def to_html()
        @template['title'] = @article.metadata['title']
        @template['content'] = @article.content
        return @template.output
    end
end

Saving a File

Okay, now I have article files with content and metadata being consumed, formatted, and handed off to
PageTemplate for wrapping into a pretty HTML page. The only thing remaining at this stage is to actually
write the file.

Test Writes

require 'fileutils'

class TC_HTML_Page < Test::Unit::TestCase

    def test_standard_page_generation
        article_file = 'simple.txt'
        template_file = 'simple.html'
        output_file   = 'test/out.simple.html'
        FileUtils::rm_rf(output_file)
        assert(html_page = HTML_Page.new(
            :article     => article_file,
            :template    => template_file,
            :o utput_file => output_file))
        assert_match(%r{<title>A Simple Page</title>}, html_page.to_html)
        assert_match(%r{<p>This page}, html_page.to_html)

        html_page.write_to_file
        assert(saved_html = File.open(output_file).read())
        assert_match(%r{<title>A Simple Page</title>}, saved_html)
        assert_match(%r{<p>This page}, saved_html)
        FileUtils::rm_rf(output_file)
    end
end

Code to Make the Writes Happen

Oh heck, just take the whole thing. This is what my SiteTemplate.rb file looks like right now.

#!/usr/local/bin/ruby

require 'rubygems'
require 'fileutils'
require 'maruku'
require 'PageTemplate'

# A single HTML page generated by a content file
#
# Content files usually look like this:
#
#    title: My Title
#    --
#    Article contents
class Article
    attr_reader :source_file, :metadata, :content
    def initialize(filename)
        @metadata = {}
        parse!(filename)
    end

    def parse!(filename)
        @source_file = filename
        content = ''
        in_content = false
        File.open(filename).each_line do |line|
            if in_content then
                content << line
            else
                if line =~ /^--$/ then
                    in_content = true
                    next
                end

                if line =~ /^(\w+?):\s*(.+)$/ then
                    key = $1
                    value = $2
                    @metadata[key] = value
                end
            end
        end

        @content = Maruku.new(content).to_html
    end
end

# Takes an Article and a PageTemplate and mushes them together
# Note: This version still assumes that needed metadata will
# be available. This is not a safe assumption.
class HTML_Page
    def initialize(opts = {})
        @article = Article.new(opts[:article])
        @template = PageTemplate.new()
        @template.load(opts[:template])
        @output_file = opts[:output_file]
    end

    def to_html()
        @template['title'] = @article.metadata['title']
        @template['content'] = @article.content
        return @template.output
    end

    def write_to_file()
        FileUtils::mkdir_p(File.dirname(@output_file))
        File.open(@output_file, 'w') { |f| f.print to_html }
    end
end

Wrapup

This stage is done. We’ve taken some article files that look a lot like my blog files and turned them into
fully-fleshed HTML files. They will fit into a PageTemplate that’s been defined by the site maintainer,
guaranteeing a standard look for the site.

My next post on this topic will deal with putting an HTML_Page into the context of a larger site.

January 6, 2008

PageTemplate for Site Generation

Filed under: pagetemplate, ruby — coolnamehere @ 3:25 pm

So I was looking at my Python Blogger client and I started thinking. First, I thought that I could probably do the same thing in Ruby. Of course, the fact that my question in the RubyForge forum for gdata-ruby suggests that I might have to do a little more work doing this in Ruby. Then again, maybe the package author has just been really busy. Goodness knows I have let PageTemplate site idle for years at a time even though I still haven’t actually stopped developing it.

That, of course, set me off on yet another thought. What if I tried to define my posts in a PageTemplate file and used filters to handle the dirty work? Well, that might be a little challenge. But what if I used this approach to generate a whole Web site? Okay, yeah. That may have come out of nowhere for you. The truth is that I love static site generation tools, from ZenWeb to WebMake. These tools appeal to me because coolnamehere is pretty much a static site and I love anything which can give that pile of pages a common format without making heavy server demands. Honestly, loading up PHP just so I can have a templated site seems like overkill.

Let’s see if I can build a site like coolnamehere with Ruby and PageTemplate. I plan to borrow heavily from ZenWeb, since there are a lot of things to like about the ZenSpider approach. I especially like
building a site from a collection of pages and a chain of filters. Hey, PageTemplate has filters thanks to Greg Millam. Why don’t I try using them?

Start Small

I am going to start small, by teaching SiteTemplate about Maruku.

It took me a bit of time to get that much done, because I needed to relearn how PageTemplate initializes. Note to self: don’t ever go a full year without using your own library.

The test is simple: create a template using the Maruku filter. Compare the output of that template
with the text minus PageTemplate directives and fed into Maruku. The test passes if they look alike,
or close enough.

#!/usr/local/bin/ruby

require 'rubygems'
require 'test/unit'
require 'sitetemplate'

class TC_MarukuFilter < Test::Unit::TestCase
   require 'maruku'

   def test_maruku_filter
       content = "This is a paragraph"

       # template_file contains the text "[%filter :maruku%]This is a paragraph[%end%]"
       template_file = "maruku.txt"
       maruku_doc = Maruku.new(content)
       pt = PageTemplate.new()
       pt.load(template_file)
       assert_equal(maruku_doc.to_html + "\n", pt.output,
           "Check if Maruku filter ran successfully")
   end
end

Then the code I needed to make that test pass:

#!/usr/local/bin/ruby
# Utility for generating a static site with PageTemplate

require 'rubygems'
require 'maruku'
require 'pagetemplate'

class PageTemplate
   class DefaultPreprocessor
       class << self
           def maruku(text)
               return Maruku.new(text).to_html
           end
       end
   end
end

I cut corners by adding the maruku filter method to PageTemplate’s DefaultPreprocessor. PageTemplate’s internals need a little work, since this isn’t the prettiest way a person might want to add filters. It works well, but it’s not pretty.

That works well enough. Next time I’ll try a template filter, which puts the Maruku output into a template file of my choosing. That way we get the standard look for pages.

January 5, 2008

Another Link

Filed under: link, ruby, windows — coolnamehere @ 2:31 am

This blog may well be the single best resource ever created for those of use who are learning how to automate Windows with Ruby.

Older Posts »

Blog at WordPress.com.