This post originated from an RSS feed registered with Ruby Buzz
by Michael Neumann.
Original Post: My own Web Framework
Feed Title: Mike's Weblog
Feed URL: http://www.ntecs.de/blog-old/index.rss?cat=ruby&count=7
Feed Description: Blogging about Ruby and other interesting stuff.
Yesterday evening, after my brother demonstrated me his good-looking Python
WebWare application, I decided to write my own Web Framework in Ruby. The
idea of this project is in my head for a very long time, it started to get
more concrete in a thread of mine on ruby-talk of subject WebShare (;-) but
then I lost it again for some time.
Then Armin asked me if I would like to do a presentation about Ruby and
the Web at EuRuKo04, but I couldn't decide on a single powerful
framework which rulez the world (in my eyes).
Why not Rails, IOWA or Borges?
I never got behind Rails and why
it should be so good (luckily I'm not the only one). IOWA instead I know for serveral years
and like it's underlying model. What I don't like in IOWA is listed below
(this should not seen as criticism):
The build-in templating stuff that you can't get around,
that IOWA components are in some ways different than pure Ruby classes,
it's code layout (yeah, in this way I'm an aesthet),
the use of class-variables and too much magic like "inherited" or
import instead of require,
but most importantly, that I don't understand all details of the code
The Borges framework is very nice
and powerful, but has had some severe problems with memory leaks in the
past, probably due to using continuations (I am not sure whether they were
able to fix all these issues). Borges is a port of Seaside 2 from Smalltalk (IIRC,
IOWA was a port of Seaside 1). Currently, there seems to be no further
activity in improving Borges and make in en par with Seaside. Furthermore I
heard on a mailing list that it is very slow due to continations or
whatever else, and as such not suitable for larger applications. And you
can't migrate sessions between processes, at least not in Ruby, as
Continations are not serializable.
My goals
In short, I wanted something that looks like Borges, but with the
underlying model of IOWA. And of course which is developed in Ruby and for
Ruby from the first second on.
I pretty exactly knew how a component in MyWebFramework (put in better
name) should look like.
require 'web'
class MainPage < Web::Component
def setup
@body = "<html><body><p>hello world</p>%s</html>"
@counter_list = (0..10).map {Counter.new(self)}
end
def render
@body % (@counter_list.map {|c| c.render}.join("<br>"))
end
end
class Counter < Web::Component
def setup
@counter = 0
end
def render
%{ <a href="#{ action_url(:dec) }">--</a> #{ @counter }
<a href="#{ action_url(:inc) }">++</a> }
end
def inc
@counter += 1
end
def dec
@counter -= 1
end
end
Of course you could use templates, too. I quickly implemented this in a few
lines of very tricky Ruby code.
require 'rdoc/template'
module Templating
def template
file = caller.first.split(':').first
file = file[0..(-1-File.extname(file).size)] + ".tmpl"
template = File.read(file)
TemplatePage.new(template)
end
def render_on(r)
template.write_html_on(r, render_template)
end
end
Now let's look at how the templated version of the Counter component would
look like. You don't even have to specify the name of the template.
class TemplatedCounter < Counter
include Templating
def render_template
{'dec' => action_url(:dec),
'inc' => action_url(:inc),
'counter' => @counter}
end
end
The template should be in the same directory as the component. Of course
only if you use my approach shown here, which I like very much, as this
allows to put each component in it's own directory, together with it's
template, and you don't need to setup template paths etc.