Padrino

Padrino 0.9.10 Released - Built for speed!

Our team is pleased to announce the 0.9.10 release of the Padrino Framework!

We have been working hard on Padrino since our first ‘public’ announcement and we have gotten a lot of amazing feedback and suggestions! This new release contains three major types of changes:

1) Performance Optimizations 2) Added Features 3) Bug Fixes

In the full post below, we will take you through a detailed tour of the biggest changes in this release (for a more compact view, see our changelog). Also, the full post contains benchmarks comparing Padrino to other popular ruby frameworks!

Performance Optimizations

Right after announcing Padrino, many developers began to request benchmarks to give them a better understanding of how our framework compared in terms of performance with the existing ruby web frameworks.

Personally, no one on our team is a big fan of benchmarks since they can often be misleading and real world usage is generally quite different. However, we thought that providing a set of simple benchmarking results would help people get at least a basic sense of Padrino’s speed.

According to our benchmarks, Padrino is now about as fast as Sinatra (and in some cases actually a bit faster!).

For our benchmarks, we chose to test three different sample applications. The first test was a bare minimum app as a baseline where a response is just rendered with a short inline string. The second test is a simple app where we render a small erb template. The third test was the most comprehensive with a more ‘full-stack’ application including sessions, haml, layouts, templates, flash, and helpers.

  # Rendering a string inline
  Merb 1.1.0        => 1749.97 rps
  Padrino 0.9.10    => 1629.15 rps
  Sinatra 1.0.0     => 1537.78 rps
  Rails 3.beta3     => 381.76 rps
  Ramaze 2010.04.04 => 270.08 rps

  # Rendering a basic erb template
  Merb 1.1.0        => 1490.8 rps
  Padrino 0.9.10    => 1416.84 rps
  Sinatra 1.0.0     => 1157.89 rps
  Rails 3.0.beta3   => 330.58 rps
  Ramaze 2010.04.04 => 254.23 rps

  # Rendering a simulated simple app
  Padrino 0.9.10    => 675.79 rps
  Sinatra 1.0.0     => 652.0 rps
  Merb 1.1.0        => 642.29 rps
  Rails 3.0.beta3   => 201.86 rps
  Ramaze 2010.04.04 => 130.62 rps

rps = requests per second (higher is better)

As you can see Padrino is very competitive in terms of speed in 0.9.10! In every case, Padrino is on par speed-wise with the equivalent Sinatra application. Be sure to check out the code for our benchmarks and let us know how we can improve them!

New Localized Translations

We added four new languages to the admin, helpers and error message translations:

  • Danish [Thanks to Molte]
  • French [Thanks to Mickey]
  • Russian [Thanks to Imm]
  • Brazilian [Thanks to Deminew]

If you want to contribute a translation for another language, please follow the translation guide and fork/send us your translations.

New Persistence Adapters

We are very very glad to announce that Padrino can now build the admin interface with these orm adapters:

This means Padrino now fully supports the following persistence engines: MongoMapper, MongoId, CouchDb, ActiveRecord and Sequel.

In the future, we are also planning to integrate: OHM (for redis) and Friendly as well among others.

If you want to contribute a component, be sure to checkout the guide for adding components which explains how to add a component to the generator and admin.

Enhanced Router Capabilities

In this version of Padrino, we have introduced the Padrino#router

This class is an extended version of Rack::URLMap which is responsible for:

  • Mapping a path to the specified App (like URLMap)
  • Ignoring server names (this solve several issues with virtual hosts and domain aliases)
  • Using hosts instead of server name for match mappings (this help us with our vhost and domain aliases)

Padrino is principally designed to support mountable applications and now with Padrino#router things are much simpler because you can match for a host pattern:

Padrino.mount_core("Blog").host("blog.example.org")
Padrino.mount("Admin").host("admin.example.org")
Padrino.mount("WebSite").host(/.*\.?example.org/)
Padrino.mount("Foo").to("/foo").host("bar.example.org")

In addition to these changes, Padrino has also been improved to work out of the box (with no special configuration) when deploying projects on Passenger and even when deploying to Sub-URIs.

Route Provides and Conditions

Now controllers accept Sinatra conditions and that means respond_to can work together with Sinatra provides.

Our provides/respond_to auto sets the content_type looking for the request format (aka extension ex: .js, .json) and can set it according to the request.accept

get :foo, :provides => [:js, :json] do ... end
# older respond_to is still supported
get :foo, :respond_to => [:js, :json] do ... end

Or you can write:

provides :js, :json
get :foo do ... end

Remember that now you also can build your custom conditions (like in Sinatra):

  def protect(*args)
    condition {
      unless username == "foo" && password == "bar"
        halt 403, "go away"
      end
    }
  end

  get "/", :protect => true do
    "Only foo can see this"
  end

Scoped Filters and Layouts

Padrino now scopes both filters and layouts for each controller. This means that layouts and/or route filters defined in a controller do not interfere with those defined in the main application or in other controllers.

SimpleApp.controllers :posts do
  # Apply a layout for routes in this controller
  # Layout file would be in 'app/views/layouts/posts.haml'
  layout :posts
  before { @foo = "bar" }
  get("/posts") { render :haml, "Uses posts layout and @foo = #{@foo}" }
end

SimpleApp.controllers :accounts do
  # Padrino allows you to apply a different layout for this controller
  # Layout file would be in 'app/views/layouts/accounts.haml'
  layout :accounts
  before { @bar = "foo" }
  get("/accounts") { render :haml, "Uses accounts layout and @bar = #{@bar}" }
end

As you can see each controller is now scoped allowing for easy grouping of layouts and filters for all routes within a particular controller.

Default Values

In certain scenarios like I18n apps, we need to repeat given values for multiple routes like:

get :show, :with => [:id, :lang] do ... end

and repeat this option multiple times with :lang => I18n.locale like:

url(:show, :lang => I18n.locale, :id => 123)

Now you can easily save yourself time with:

controller :lang => I18n.locale do
  get :show, :with => [:id, :lang] do ... end
end

and in this way you can build urls like:

url(:show, :id => 123)

and the default controller settings will be automatically appended to the route.

Minor Features

Padrino 0.9.10 also features support for a host of minor improvements:

  • Added support for ext-core as javascript engine [Thanks to Imm]
  • Mailer now supports explicitly setting the template path to render for a mail method
  • Beautiful colorized logging support
  • Ruby 1.9.2-head compatibility
  • Now sessions (like Sinatra) are disabled as default
  • Updated jQuery to v1.4.2
  • Added padrino rake routes

Bug Fixes

  • Removed always “index” from our routes name
  • Fixes SASS reload plugin issue on 1.9.X
  • Fixes an issue with generator not casing controller / model names
  • Fixed padrino g and padrino gen aliases
  • Fixes issue with mounter and locating the app file
  • Removed VERSION files. This prevent problems described here: http://github.com/nex3/haml/issues/issue/24
  • Fixed a bug with layouts that prevent double rendering
  • ActiveSupport 3.0 Compatibility fixes

Summary

As you can see there are some important fixes and new features but we want to point out a few things:

  • Padrino is already quite stable (remember that since version 0.7 our team has been using it in the real world)
  • This project is very actively contributed to and our team is committed to this framework and fix bugs quickly.

And what is next for Padrino?

We can anticipate right now that our team will soon be completing padrino templates and plugins, the tiny app generator and the padrino-cache gem.

After we complete these items and fix any bugs that crop up, Padrino can be ready for ONE-DOT-ZERO release!


Addressing Concerns about Padrino

Over the last week, we have taken the first steps towards showing Padrino to a larger audience of Ruby and Sinatra fans. Our team and other developers have gotten around to announcing Padrino on RubyInside, Rubyflow, the Ruby5 Podcast, Hacker News, the Sinatra Google Group, among other sources.

The chatter on twitter and the fact that Padrino has become a most watched ruby repo this month on Github shows this little framework is gaining an audience. Thus far, our team has been very pleased with the feedback that we have gotten even already after the various announcements. The response has been overwhelmingly positive and constructive and we wanted to thank everyone for taking the time to explore what Padrino is all about!

At the same time, there have been a couple questions that have popped up along with some valid criticisms and/or confusion as to what the Padrino framework is all about. I would like to take this blog post as an opportunity to address many of these concerns as well as talk a little bit about the future of Padrino.

Why another web framework? Aren’t there enough out there already?

This is probably the most common criticism that I have seen so far when a developer immediately reacts to hearing about Padrino. I definitely understand this reaction and I consider this a reasonable question to ask whenever a new web development framework pops onto the stage.

First, I would like to disagree that Padrino is a ‘new’ web development framework at all. When you take a deeper look at Padrino, it quickly becomes clear that we have not strayed far from our Sinatra roots. This is not a ‘brand new’ framework by any stretch. This is simply an enhanced super-set of Sinatra! If a developer knows Sinatra, then they already know basic Padrino. If a gem on Github works currently on rack or Sinatra, the very same gem will already work on Padrino without any modifications whatsoever! There is virtually nothing about Padrino that steps on Sinatra’s toes.

Second, I would argue that Padrino is very different from a typical ‘new’ web framework. Padrino’s codebase is fairly small all things considered. Not ‘Sinatra small’ but certainly fairly miniscule in comparison to Rails or most full-stack frameworks. During the development of Padrino, our team was committed to absolutely never re-inventing the wheel. Whenever possible, we have taken popular, existing, and battle-tested libraries and integrated them together to make development easier. We used usher to enhance routing, a modified pony for developing the mailer, bundler for managing dependencies, and the excellent thor for the generators, tasks and templates. We understand that new code usually means unstable code and have tried to use existing tools whenever possible!

Third, while we have indeed taken the time to combine excellent libraries and integrate them for the purpose of enhancing Sinatra, it is also important to point out that we have not become an ‘opinionated’ framework’. In fact, we have worked hard to make Padrino agnostic and yet still maintain a smooth and easy development flow. The generators and the admin system are both engineered to be able to support an arbitrary number of different tools or library choices. A Padrino application could just as easily be using Mongoid, Rspec, Less and Erb or Datamapper, Shoulda, Sass, and Haml. We don’t mind and make it easy to use any stack that you already like working with!

Hasn’t Padrino ruined the whole intention of Sinatra by making it too heavyweight?

All three current core developers of Padrino have fairly extensive experience using Rails and Sinatra. We have developed many applications for hobby, for clients and for companies we have worked for in the past. I personally cannot say I have much disdain for Rails at all. In fact, I sincerely enjoyed programming web applications with Rails for years. However, once I stumbled onto Sinatra and started experimenting with simple applications, I was very impressed with how lightweight and expressive Sinatra could be. I appreciated Sinatra and the spirit of that micro-framework so much that I started using it for more and more of my development work.

However, anyone who has fallen in love with Sinatra knows that eventually you run into various brick walls and major nuisances that make Sinatra impractical for large applications. Yet, I felt that with a few standardized additions, Sinatra could easily be enhanced to support applications of an arbitrary size. Those tools that I built were the early stages of an older library of mine called sinatra_more. This became modestly popular and from there (with help from DAddYE, Arthur and others), ultimately evolved into the Padrino framework that we have today.

Padrino is about building where Sinatra leaves off and creating a cohesive set of standardized building blocks to allow developers to push Sinatra development to new heights and far more complex applications than typically feasible prior. Keep in mind that Padrino is simply a superset of Sinatra and that a developer can pick and choose which Padrino features he would like to include in his application. In fact, Padrino is modular enough that most of the functionality can be included right inside an existing Sinatra application rather easily.

How does Padrino compare to Monk, Chicago, sinatra_more, Pancake, etc?

Another common question that I have seen emerge is an explanation on how Padrino compares to existing Sinatra ‘glue’ extension such as Monk , Chicago , sinatra_more , Pancake. Here I will briefly outline what each existing one is and how this differs from Padrino.

Monk is primarily a skeleton (bare application) which gives you a solid starting point for developing a Sinatra application. The default skeleton will give you a Sinatra application with a structure, which can be tested using Contest, Rack::Test and Webrat. To store things you’ll have Ohm, a persistence layer that talks to Redis. Other niceties included, like a logger, a settings hash and proper reloading for easier development. While monk is a very cool library, it is actually quite a bit different in scope from Padrino. Monk does allow for creating skeletons of different types, but no proper ‘generator’ is available and the skeletons provided do not really compare to totally agnostic generators that are offered by Padrino. Padrino also provides all of the niceties afforded by monk (improved logger, configuration hash, proper development reloaded) along with other great features like i18n localization, admin dashboard, mail delivery, view helpers, form helpers, form builders, enhanced routing and much more.

Chicago is a library filled with “testing helpers, extensions, and macros used commonly by Thumble Monks”. Looking at Chicago, you can tell that the developers were running into some of the same annoyances that led to the development of Padrino. Chicago provides enhanced support for SASS in your application, basic helpers such as ‘anchor’, ‘stylesheet_include’, and ‘javascript_include’ along with helpers to make testing easier with a few frameworks. Chicago is undoubtedly an excellent library and in many ways a precursor to Padrino::Helpers which contains nearly all the functionality within Chicago and much, much more. If you like Chicago, you will love using Padrino for the same reasons.

sinatra_more is the direct ancestor of Padrino. The developers of both are the same and the intention of them both are almost exactly the same. Padrino simply builds off of what sinatra_more started and created a more comprehensive and integrated set of functionality. If you have enjoyed using sinatra_more, Padrino provides everything you have appreciated along with many additional features.

pancake is a very cool project that provides very useful helpers on top of Rack that assist in constructing Rack stacks as mixins. Almost all key aspects of web frameworks are covered in Pancake as mixins to help you create your own re-usable Rack Stacks without worrying about the really low level plumbing. Pancake actually overlaps very little with Padrino. I recommend experimenting with Padrino applications as part of the Pancake Rack stack!

In addition, there are admittedly lots of libraries that provide small subsets of the functionality afforded by Padrino. Many of these libraries are great and there is nothing about Padrino that prevents them from being used! In fact, any library that you can use in Sinatra can be used the exact same way with Padrino. Padrino simply gives you a very strong starting point for building powerful Sinatra applications.

For more information on Padrino, be sure to read our page devoted to why to use our framework which contains additional explanations and comparisons.


  • Prev Page
  • Next Page