Introducing Lego

For a while now Mathias and I have been hacking away on our very own web framework called Lego.
But why? I hear you cry, why yet another one, what’s wrong with Rails, Merb, Ramaze, Sinatra, Camping, Rango, Waves, Mack, and so on and so on.
Well, they’re all great but we believe they aren’t dumb enough!
Lego however is about as dumb as it gets, all it knows is how to handle the request/response cycle and leaves the rest up to plugins.
The downside of this approach is that it takes a little bit more work to get it up and running the upside is that you get exactly what you want, nothing more, nothing less.

I’m intrigued, tell me more

So at it’s core there’s lego-core which contains only the bare essentials, a way to set up a controller that rack can run, and a way to extend the various parts of lego.

Future plans include a lego-more gem already setup with commonly used plugins so you easily can get up and running quickly and a central repository of available lego plugins.

A simple application

Provided that you have lego-core installed (gem install lego-core) put the following in a config.ru file:

1
2
3
4
5
6
require 'rubygems'
require 'lego-core'

class MyApp < Lego::Controller; end

run MyApp

Run it with rackup and point your browser to http://localhost:9292/ and you should be met by a plain old ‘404 – Not found’, not terribly exiting right? But that’s pretty much all lego-core gives you :)

So what about those plugins?

The lego extension system allows you to hook into various parts of the execution chain, namely:

View – For action and view related stuff
Controller – For defining controller dsl’s
Router – Rules for how lego should match routes, must have a self.match_route method which takes a route and an env parameter and return either a two element array containing the env and a hash of match data (or an empty hash if no match data is available) or false

At it’s core, a plugin is a module that responds to register who’s responsibility is to register with lego, following is a simple plugin example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
module SamplePlugin

  # Register is called by lego when plugin is loaded

  def self.register(lego)
    lego.add_plugin :view, View
    lego.add_plugin :router, Matcher
    lego.add_plugin :controller, Routes
  end

  # A plugin module we load as a view helper

  module View
    def h1(content)
      "<h1>#{content}</h1>"
    end
  end

  # A very simply route helper

  module Routes
    def get(path, &block)
      add_route(:get, {:path => path, :action_block => block})
    end
  end

  # A very simple route matcher

  module Matcher
    def self.match_route(route, env)
      (route[:path] == env['PATH_INFO']) ? [env, {}] : false
    end
  end
end

It’s about time for a real example!

As we showed you earlier, lego-core gives you a way to set up an application but it don’t know how to map routes to action so let’s expand on the previous application with our newly gained knowledge of lego’s extension system:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
require 'rubygems'
require 'lego-core'

module Routes
  def self.register(lego)
    lego.add_plugin :controller, SinatraController
    lego.add_plugin :router,     SimpleRouter
  end

  # implements a basic Sinatra inspiered dsl
  module SinatraController
    def get(path, &block)
      add_route(:get, {:path => path, :action_block => block})
    end
  end

  # Implements a very basic mather rule
  module SimpleRouter
    def self.match_route(route, env)
      (route[:path] == env['PATH_INFO']) ? true : false
    end
  end
end

# define an application
class MyApp < Lego::Controller
  plugin Routes
 
  get "/" do
    "Hello from /"
  end
end

run MyApp

As before, run it with rackup and point your browser to http://localhost:9292/ and this time you should be greeted by “Hello from /”.

Don’t repeat yourself

If you have a plugin you want to use in every application, then consider defining it globally:

1
2
3
4
5
6
7
8
9
  Lego.plugin MyPlugin

  # or group multiple plugin calls in a config block

  Lego.config do
    plugin MyViewPlugin
    plugin MyControllerPlugin
    plugin MyRouteMatcherPlugin
  end

Configuration options

Lego also comes with a very simple configuration handler, it basically provides two methods, set and options, lets look at them in action:

1
2
3
4
5
6
7
8
9
class MyApp < Lego::Controller
  plugin Routes

  set :foo => "bar", :baz => "quux"

  get("/foo") { options :foo }
 
  get("/bar") { options :bar }
end

As with plugins you can use set globally:

1
2
3
4
5
6
7
8
  Lego.set :foo => "bar"

  # or group multiple set calls in a config block

  Lego.config do
    set :foo => "bar"
    set :baz => "quux"
  end

Wrapping up

In conclusion Lego is a ‘Use what you want’ framework that tries to stay out of your way as much as possible and thank’s to it’s modular design, you are free to use your favourite technologies and tools.

Please note that it’s still in a highly experimental stage!

Posted in Programming, Projects, Ruby, gems at January 13th, 2010. No Comments
Tagged with , , , , . Written by: Patrik Hedman

So in order to save your fingers the pain I updated the ffmpeg gem today. You see, previously you had to do this:

1
2
3
convert "finding_that_nemo_dude.avi", :to => "finding_that_nemo_dude.flv" do
  ...
end.run

Doesn’t look to bad, right? Well, maybe not, but if you pay attention you would notice some repetition here, since the only thing different about the filenames is the extension. So, to keep things nice and dry you can now do this instead:

1
2
3
convert "finding_that_nemo_dude.avi", :to => :flv do
  ...
end.run

The old way still works if you really want a different filename all together or if you just really like to type :)

Posted in Ruby, Utilities, gems at August 15th, 2009. No Comments
Tagged with , , , . Written by: Patrik Hedman

FFmpeg is a great tool for recording, converting and streaming audio and video. It can, however, be quite cumbersome to use. For example consider the following command:

1
ffmpeg -i some_file.flv -ss 00:00:20 -t 00:01:30 -s hd1080 -aspect 16:9 some_file.avi

Now, even though this is a simple example, it’s still kind of hard to know exactly what it does, so you can imagine what it will look like once you need to accomplish more complex tasks. By contrast, here is the same example using my ffmpeg gem (gem install polly-ffmpeg):

1
2
3
4
5
6
7
8
9
10
require "rubygems"
require "ffmpeg"
include FFMpeg

convert "some_file.flv", :to => "some_file.avi" do
  seek       "00:00:20"
  duration   "00:01:30"
  resolution "hd1080"
  aspect     "16:9"
end.run

This is in my opinion much easier to understand and use.

For more information checkout the documentation and the source code

Posted in Ruby, Utilities, gems at August 5th, 2009. 2 Comments
Tagged with , , , . Written by: Patrik Hedman

In my last post I showed how you can install my suppress_validations gem on a per-project basis but that’s a bit cumbersome. Wouldn’t it be nicer if it always was available in the console on every project?
I think it would, so here’s how you can accomplish just that:

Edit your ~/.irbrc (or create it if you don’t already have one):

1
2
3
4
5
6
7
8
require "rubygems"

if ENV['RAILS_ENV']
  IRB.conf[:IRB_RC] = Proc.new do
    require "suppress_validations"
    include SuppressValidations
  end
end

And thats it, you can now fire up script/console and start suppressing validations

1
2
3
4
5
6
7
8
9
10
$ script/console
Loading development environment (Rails 2.3.2)
>> post = Post.new
=> #<Post id: nil, title: nil, body: nil, ...>
>> post.save
=> false
>> suppress_validations { post.save }
=> true
>> Post.last
=> #<Post id: 1, title: nil, body: nil, ...>
Posted in Rails, Ruby, gems at July 28th, 2009. No Comments
Tagged with , , , . Written by: Patrik Hedman

Validations on ActiveRecord models can really get in the way while trying things out in the console sometimes so the other day when I stumbled over this railscast episode: http://railscasts.com/episodes/62-hacking-activerecord I thought, hey, with some modification that could easily be turned into a plugin.

Install it with:

1
$ gem install polly-suppress_validations

then add this to your config/environment.rb file:

1
config.gem "polly-suppress_validations", :source => "http://gems.github.com", :lib => "suppress_validations"

and then unpack it with:

1
$ rake gems:unpack

or just install it as a plugin:

1
$ script/plugin install git://github.com/polly/suppress_validations.git

Now say we have a model like this:

1
2
3
class Post < ActiveRecord::Base
  validates_presence_of :title, :body
end

Now lets enter script/console and include the SuppressValidations module

1
2
3
4
$ script/console
Loading development environment (Rails 2.3.2)
>> include SuppressValidations
=> Object

However, trying to create a new post without the required attributes still fails as this example shows:

1
2
3
4
>> post = Post.new
=> #<Post id: nil, title: nil, body: nil, ...>
>> post.save
=> false

To suppress validations just wrap the call to post.save in a suppress_validations block, like so:

1
2
3
4
>> suppress_validations { post.save }
=> true
>> Post.last
=> #<Post id: 1, title: nil, body: nil, ...>
Posted in Projects, Rails, Ruby, gems at July 20th, 2009. No Comments
Tagged with , , . Written by: Patrik Hedman

Just released a new version of capistrano_colors. This is a total rewrite from the last version. This post show some of the bigger changes.
Read More…

Posted in Programming, Projects, Rails, Ruby, gems at January 4th, 2009. No Comments
Tagged with , , , , , . Written by: Mathias Stjernström

I got so tired of all the messy capistrano output so today I released my first public gem.

The name of the gem is capistrano_colors and the aim of the gem is to put some nice and shiny colors on capistrano output. The gem has only been tested with rails but should work wherever capistrano works.

Keep on reading to see some screenshots!
Read More…

Posted in Programming, Projects, Ruby, gems at December 21st, 2008. 6 Comments
Tagged with , , , , . Written by: Mathias Stjernström

I’ve just released v0.5 of keyFinder. keyFinder is the simpliest frontend for OSX’s keychain that you can think of. Its basicly a little window that filters your passwords (live) as you type your keywords. Select the one you want and hit enter. The password then gets copied to your clipboard. 

More information can be found on the keyFinder page under my projects.

Cheers!

Posted in Projects, Utilities at August 3rd, 2008. No Comments
Tagged with , , , , , , . Written by: Mathias Stjernström

pastbedti.me is using WP-Gravatar