robert hahn

a darn good web developer

April 08, 2009

Spring Cleaning (yes, I’m back)

Um, wow. It’s been awhile since I last posted anything!

During my quiet time, I’ve been busy; I’ve had a few web contracts that I worked on at night. I went to work at a cool new company called Primal Fusion as a software developer. You’ll want to check that out!

Things have finally settled down enough that I wanted to do some serious housecleaning on my site. I was getting irritated with the blogging engine I was using (Typo), irritated about the HTML I used for the beachboy theme (it never looked fine on all browsers) and I was yearning to return to the world of static website generators.

So, this site has been redesigned and re-staged. I’ve tried as much as possible to keep the links the same, but if you’ve got a 404 on a page that used to be there, please let me know about it.

The new publishing engine is a ruby-based static site generator called nanoc, which so far I’ve been very pleased with. The system provides me with a solid set of features for building a static site, and was easy to extend with features I’ve wanted to build in.

Take the homepage for example. You’ll see a mashup of my Delicious feed, Twitter feed, and my article feed sorted in order. It was only a few lines of code to build, including caching the feeds.

As per my usual, I’ve returned to a low-key presentation – the intial launch of this site doesn’t even have any javascript!

So if you’ve been subscribed to me, thank you for waiting so long!

permalink

August 16, 2007

The Ideal REST Framework.

Granted, I haven’t been spending all my time looking at everyone’s favorite framework, but from the ones I do know about, it seems really odd that we have an impedance mismatch between HTTP and the classes/methods we use in our framework. I want to spend a few posts exploring how I think a framework should be put together, so that it conforms as much as possible to REST. My code samples will be in Ruby, but I don’t see any reason why you can’t build this in any other language.

Naturally, I start where the HTTP request gets handed off to what we think of as the controller in most frameworks. It seems as though we ought to have a superclass that defines the uniform interface. It would look like this:

class HTTPResource
    def get; end
    def post; end
    def put; end
    def delete; end
    def method_missing m
        @status = 405
        "Method Not Allowed"
    end
end

With it, you would instantiate the resources you want to expose. In this case, I want to build, um, how about a Media Release administration tool, where you can add, edit, and post PRs. Let’s expose a resource called Release.

class Release < HTTPResource
  def get; end
  def put; end
  def delete; end

  private

  def post;end
end

Well, I’m sure you’re tempted to say that you can post a Release, and I’d agree with you, but I wanted to set it up this way to show you something cool: by making post private, any calls to that method would instead be handled by the superclass’ method_missing method, and return a 405 Method Not Allowed. Wow, that’s convenient.

There’s a lot of stuff missing. HTTPResource really ought to get some context together, like a collection of HTTP headers and ready access to query variables. I haven’t yet thought about how that’s going to work yet – it could be that we need instance variables, or it could be that we need classes.

But one thing I thought was pretty cool about this is that this structure seems so simple and natural, you could easily write a commandline script that included these class definitions, and manipulate your app as easily from a script as from a browser. I’m sure you could do it with other frameworks too, but it looks obvious how you’d write such a tool. That seems like a win when it comes times to write tests – just call Release.new.get, for example, and test what gets returned.

permalink

July 22, 2007

Three Methods for simulating render_component in Camping

If you have used the Camping microframework for any length of time, you might have quickly found out that there’s no feature available like render_component, which is found in Ruby on Rails. render_component allows you to call a controller method (with its associated view) for the purposes of rendering a portion of your page. For example, you might want a page that primarily displays data for one employee, and show a list of employees in a side column - ideally, you’d like the controller responsible for generating a list of employees to continue to be responsible for that, even if you’re in the controller for displaying employee data. So I ended up working out three different methods for solving this problem.

Let’s go back to my running example here: I’ve got this employee management app, where people might want to add or delete employees, and on almost every page, I need to see a list of employees’ names, each linked to their profiles, on a side column. The controller class for retrieving this list could look something like this:

class Employees < R
  def get
    @employees = Employees.find :all, :order => "name asc"
    render :employee_nav_list
  end
end

Method 1: Calling methods from other classes

My first cut at trying to build render_component was the hardest thing I had to solve. The Employees class, with its get method for generating the list was already written, so what I really wanted to do was somehow instantiate the class and call get. In my previous article, we learned that the return values of these methods are always a string; if I could somehow instantiate that class, and call its get method, then I’d have a string containing a chunk of HTML that I can store in an instance variable to be used in my current view.

Calling Employees.new.get, unfortunately, wasn’t that simple. Hints to what the Employee’s constructor looked like was kind of buried in the Camping microframework itself, and after poring over the code and testing things out, I was able to come up with the following module:

module Component_Support
  def render_component( classname, method, payload, args )
    classname.new( payload, @env, method.to_s ).send(method.to_sym, *args)
  end
end

To use this, you’d have a bit of code in your app that looks like this:

module YourApp
  include Component_Support
end

and then you’re free to call render_component wherever you like. Let’s break it down. render_component, here, takes 4 arguments:

classname
The name of the class you want to instantiate
method
The method you want to call in that class
payload
If you’re making a `GET` request, this should be empty. If you’re making a `POST` request, the payload should consist of `form-encoded` data (which typically looks like this: `name1=value&name2=value&name3=value…`)
args
These would be the regular arguments the method requires to execute, if there are any.

The body of the method instantiates the object correctly, calls the method that we’re interested in, and returns the result. If I was displaying an employee profile page, and I wanted to show that list of employees down the side, all I need to do is add the following line to my profile controller:

@employee_list = render_component(Employees, 'GET', '', '')

And I’ll have a nice fragment of HTML to include in my output.

Method 3: Define methods for sharing data

I don’t know about you, but up until recently, I built the classes in Camping using only get and post methods because I thought that was the way you were supposed to do it. It was “the rules”. It never occurred to me that I could easily add other methods if I needed to.

The thing is, it’s just a class, like any other, so if you really needed to, you could move code that’s common to both get and post methods into their own method calls and call them.

using the above code snippet, we could basically build something like this:

class Profile < R '/profile'
  def get
    # code specific to get

    @employee_list = build_emp_list

    render :profile
  end

  def post
    # code specific to post

    @employee_list = build_emp_list

    render :profile
  end

  private

  def build_emp_list
    @employees = Employees.find :all, :order => "name asc"
    render :employee_nav_list
  end
end

Method 3: Putting components in modules

As a variation on a theme, suppose you have a number of controller classes, and most of them needs to display the same type of data on a page. You’d like to be as DRY as possible, and you don’t want to use the render_component code up above – maybe because the component you want to render doesn’t properly belong to one of the controller classes. All you’d need to do is make two changes to code that looks like method 2:

Here’s an example:

module MyApp::Controllers
  module Employee_Components

    # some components defined here...

    def build_emp_list
      @employees = Employees.find :all, :order => "name asc"
      render :employee_nav_list
    end
  end

  class Profile < R '/profile'
    include Employee_Components

    def get
      # code specific to get

      @employee_list = build_emp_list

      render :profile
    end

    def post
      # code specific to post

      @employee_list = build_emp_list

      render :profile
    end
  end
end

Conclusion

So, with this article, you’re well equipped to add render_component functionality to your Camping apps, which will help in making your code more DRY. Which method you use should depend on how you can best make your code readable. If the code you want to reuse resides in a related class, then I’ve provided you with a means to instantiate that class and call the method. If the only time you require this method is in one class, define it as its own function. Otherwise, some clever module management might do the trick.

permalink

July 21, 2007

Camping Without the View

It’s possible to construct a web application using the Camping microframework without using the *::Views module. Most of the time, you would be crazy to do so, since the *::Views module makes it very easy to print out HTML responses using _why’s Markaby markup engine.

There is a strong use case for not using *::Views– if you want to return data that is not supposed to be formatted as HTML (like XML or JSON), you’ll probably find that it’s more work than it really ought to be, to print out that response.

The Model-less, View-less Camping App.

That’s right. I’m going to show you a camping app that does not use either the *::Views or the *::Models modules, that is perfectly legit:

#!/usr/bin/env ruby

require 'rubygems'
require 'camping'

Camping.goes :HelloWorld

module HelloWorld::Controllers
  class Index < R '/'
    def get
      %Q(
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head><title>My small page</title></head>
      <body>
        <h1>Hello, world!</h1>
      </body>
      </html>
      )
    end
  end
end

If you save this program as hello_world.rb, then run camping hello_world.rb, it will run fine, and if you point your browser to http://localhost:3301/, you will see the friendly greeting.

What’s going on? Let’s rewrite the application to something more familiar:

#!/usr/bin/env ruby

require 'rubygems'
require 'camping'

Camping.goes :HelloWorld

module HelloWorld::Controllers
  class Index < R '/'
    def get
      render :hello_world
    end
  end
end

module HelloWorld::Views
  def hello_world
    html do
      head do
        title "My small page"
      end
      body do
        h1 "Hello, world!"
      end
    end
  end
end

If you run this hello_world.rb app, you’ll get almost the same output. There is almost no magic involved here; in the get function, we have a render statement that performs the necessary work to call the hello_world function in the HelloWorld::Views module. What’s not obvious here (except to seasoned Rubyists, I suppose) is that there is an implicit return in the hello_world function; it returns a string containing the HTML to be printed. There is also an implicit return happening in the controller, where the results of the render statement (the Hello, world page) is returned to its caller.

So the dirty secret is out: as long as the methods in your controller classes return a string, whatever is in that string is what’s going to be returned to the browser.

Why do we want to do this, again?

Most of the time, you want to use the *::Views module, because, most of the time, you want to return HTML to the browser.

Knowing what we know now, we have the ability to do a couple of useful and interesting things:

I’m going to get into more of this in future articles.

permalink

June 21, 2007

Setting HTTP Response Codes with Exceptions

A client of mine needed an admin tool for their site: a basic file upload script. Anyone who has ever written such a script knows that there are at least a good half dozen potential failure points when writing such a thing. Experience suggests that you should check at a minimum the following types of things:

For some of these tests, it may actually be pretty important to fail loudly enough for the user to notice. And of course, if we want to build RESTful web applications, it would be good to return the correct HTTP response code in a failure scenario.

While writing the script, using Camping, it suddenly occurred to me that with a bit of tooling, I could easily use Ruby’s exception handling tools to make my life easier, and to make the code maintainable. This technique can easily be applied to Rails applications too.

The setup

The Pickaxe, in its description of the Exception class, describes a #status method that is only available to the SystemExit exception. That looks like a useful idea, but I need the status baked into the base Exception class. Why? Well, if the script is going to die because a directory isn’t writable, or for some other reason I couldn’t anticipate, I need the script to return a 500 error code. Time to monkey patch Exception:

class Exception
    def status
        500
    end
end

Now let’s extend this for some other error scenarios, like a user attempting to upload a file larger than I’d like:

class ForbiddenException < RuntimeError
    def status
        403
    end
end

You should compile a big list of these exceptions into its own file and require it in your app.

In Your Application

Ok, so now you’re in Camping (or Rails), and you’ve got your file processing logic sitting in a class in the model, you have an ‘error’ view (among others) and you’re calling this code from the controller. In the model, you might have a #save method, and one of the things you’re going to do before you save your uploaded file is check the file size:

raise( ForbiddenException.new, "File Too Large!") if @file.size > 11000000

Now for the juicy bit: the controller logic:

class Index
    def Post
        file = FileUpload.new(...)

        page = :index

        begin
            @file = file.save
       rescue Exception => @e # oh, noes! my bad!
            @status = @e.status 
            page = :error
        end

        render page
    end
end

In Camping, the @status variable is reserved for setting the HTTP response code, and is smart enough to change it from 200 to 302 when you’re redirecting; that said, you can set it to other codes as we’re doing here.

And the view (the @e is being used here):

def error
    h1 "An Error has occurred"
    p @e
end

After getting this working, there’s two things I couldn’t believe:

  1. How easy it was to get this going
  2. That no one else thought to mention this

One of the niftiest (yes, I like to use the word nifty) things about this method is that you could catch different kinds of exceptions and customize the output accordingly:

def Post
    file = FileUpload.new(...)

    page = :index

    begin
        @file = file.save
    rescue ForbiddenException => @e # silly user!
        @status = @e.status 
        page = :forbidden_page
    rescue Exception => @e # oh, noes! my bad!
        @status = @e.status 
        page = :generic_error
    end

    render page
end

Conclusion

With only a handful of lines, I managed to create a system that easily handled error scenarios in a maintainable fashion, and passed them off to the correct view as required. Better still, I managed to easily ensure that the client was receiving the correct HTTP response code. Are there ways this could be improved still more? Let me know.

permalink

Annotated PDFs, Preview.app and Adobe Acrobat

A Question About Using 403 Forbidden

The 3 Rules of URI Design

The Web Needs Killlfiles

CSS Naked Day

Friday, April 13th: International Unicode Screen Name Day

Before Buying the JAWS Screen Reader, Consider:

Printing XML from Camping

5 Things You Didn't Know About Me

How to Use window.onload the Right Way

Why I Prefer Camping Instead of Rails

Yurt CMS 0.4.1 Released!

The Irony of Me Using Screen Readers

To Ajax, or Not To Ajax

Yurt CMS 0.3.1 Released!

How to Integrate ActionMailer with Camping

Yurt CMS 0.2.0 Released!

How to View Outlook Appointments in Mail.app

Introducing the Yurt CMS Project

Yikes! I Want to Launch a New Open Source Project! Help!

Typo Instance Updated; Feed Format Change Coming

The Point of Styling Feeds

To All the People Who Say "NO! CSS does NOT belong in feeds"...

More HTML, Fewer Keystrokes

Preprocessors and HTML Development

CSS Preprocessor – Take 2

CSS Preprocessor

A Brief Personal History of using WYSIWYG Editors for Web Pages

How I Used to Build Web Sites

Building Web Sites with Transparent PNGs

New theme: Beachboy; Revisited

New theme: Beachboy

Building User-Programmable Websites

Lisp: Second Impressions

Lisp: First Impressions

Learning a new language: Lisp

Update: How to Update Your Live Typo Blog with a Local Typo Instance

How to Update Your Live Typo Blog with a Local Typo Instance

JScript and VBScript in ASP: Which to use?

How to use JScript instead of VBScript in ASP

Using window.open() in an Accessible Way

Main Site Updated

Typo Garden Contest Entry

Welcome to my blog!

decorative image of trees

Copyright © 2009
Robert Hahn.
All Rights Reserved unless otherwise indicated.