Section 19.6. Web Development with IOWA


19.5. An Introduction to Wee

According to announcements from its creator Michael Neumann, Wee is "a framework for very dynamic, component-oriented, stateful web applications, largely inspired by Seaside." The name comes from the claim that Wee makes Web Engineering Easy.

The simplest way to install Wee is to use rubygems (gem install wee). The version at the time of writing was 0.10.0. The Wee documents explain that although the code is pretty stable, there is a chance of some issues when using continuations, and that, overall, you may not want to use the framework for mission-critical applications.

However, even with those caveats, Wee is well worth exploring for its component model, and because continuations are an interesting but underexplored area in mainstream web development. The creator says that he was influenced by ideas presented in Seaside, a continuations-based web framework written in Smalltalk by Avi Bryant.

The Wee gem installation includes a number of varied examples. One is a web-based browser into ObjectSpace; another shows some basic Ajax using the Prototype JavaScript library. There's also an example showing how to use Wee with Nitro.

At the heart of Wee is the idea of components. These are like widgets in a GUI. Wee components are thoroughly reusable, encapsulating state, presentation, and behavior, though you may prefer to have them delegate to external templates or models.

19.5.1. A Simple Example

Installing Wee creates a simple application generator script called, naturally, wee. Running wee create my-demo will create a directory named my-demo off the current path and populate it with a simple WEBrick-based application.

The created app does little more than track the number of times a link has been clicked. The server file, run.rb, sets up the application components and main class and starts the application under WEBrick.

require 'wee' require 'wee/utils' require 'wee/adaptors/webrick' # Your components require 'components/main' app = Wee::Utils.app_for do   Main.new.add_decoration(Wee::PageDecoration.new('Wee')) end Wee::Utils::autoreload_glob('components/**/*.rb') Wee::WEBrickAdaptor.register('/app' => app).start


The class Main will be called as the main application component. Components need to implement a render method to emit their markup. The call to add_decoration(Wee::PageDecoration.new('Wee')) alters the rendering pipeline such that the results of Main#render will be wrapped in an HTML header and footer.

Next, automatic file reloading is set up, so you can change code and retry the application without restarting WEBrick. Finally, an instance of WEBrick is started to serve the application from the URL path '/app'. The default port is 2000; you can pass a different port number as a parameter to start:

Wee::WEBrickAdaptor.register('/app' => app).start(:Port => 8787 )


The Main component defines the render method to produce the markup.

class Main < Wee::Component   def initialize     super()     # Put your own initialization code below...   end   def render     r.anchor.callback(:click).with { r.h1("Welcome to Wee!") }     r.text "#{ @clicks || 'No' } clicks"   end   def click     @clicks = (@clicks || 0) + 1   end end


Wee allows you to use Ruby syntax to define the HTML to emit in a manner similar to Jim Weirich's XML Builder library and the XML generator in Nitro. However, in Wee this syntax also allows you to connect a link with an action (in this case, the click method). When a user clicks the link generated by Wee, the application knows that it should invoke click.

19.5.2. Associating State with URLs

This example, as is, tracks the current value of @click but does not tie it to a URL. If you run the program, you'll see that Wee is generating a fairly lengthy URL that is, essentially, a GUID (globally unique identifier). The URL stays the same except for a trailing slash and an integer. Each time you click the Welcome to Wee link that integer increases.

If you manually edit the URL in the browser, you'll get the same page; the displayed click count does not change. There is no association between URLs and server state. (Make sure that your browser is not caching pages when you try this.)

We can change this, though, with a simple addition to main.rb. Add the following method to Main:

def backtrack_state(snap)   super   snap.add(self) end


Then restart the application. After clicking the link a few times, manually edit the URL in the browser to reload a previous page. The click count should reflect the value of @click at the time that URL was rendered.

To try this using Wee's continuation code, add the following after the calls to require in run.rb:

require 'wee/continuation'


There's much more to Wee than can be covered here. For more information, consult these references:

  • Wee project page (http://rubyforge.org/projects/wee/)

  • Nemo project page (http://rubyforge.org/projects/nemo/)

  • Seaside (http://seaside.st/)

One interesting feature is the capability to nest components and chain the behavior, allowing you to assemble websites from reusable UI widgets. You should also take a look at Nemo, an implementation of Mewa (Meta-level Architecture for Web Applications) in Wee.




The Ruby Way(c) Solutions and Techniques in Ruby Programming
The Ruby Way, Second Edition: Solutions and Techniques in Ruby Programming (2nd Edition)
ISBN: 0672328844
EAN: 2147483647
Year: 2004
Pages: 269
Authors: Hal Fulton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net