Padrino

Padrino 0.9.25 - Slim and Erubis, Caching, and Fixes

Since our 0.9.23 release, we have been busy fixing bugs and resolving incompatibilities as quickly as possible. Today, we are be releasing 0.9.25 which brings another wave of improvements, bug fixes, and component compatibility. 0.9.25 is very likely the largest release our team has had in quite a while and as you might notice represents two version bumps in one.

The biggest changes with this release are the introductions of Padrino Cache (and documentation), complete support for Erubis and Slim rendering, support for unobtrusive javascript handlers, and a revamped routing implementation.

For more details, check out the rest of this post below for the feature highlights.

Padrino Cache

The padrino-cache gem has had a long journey and has traditionally been the neglected and abandoned sibling in the padrino framework family.

This is no longer the case with this release. The padrino-cache gem has now been added as a first-class member of the Padrino framework.

The functionality includes a variety of caching types and stores including memcached and redis support. Adding new adapters in the future will be very easy as the gem was designed for extensibility in mind. This is the caching solution you always hoped to have when using Sinatra.

For more information, check out the README as well as the Padrino Cache Guide for a solid overview of this new addition to our framework.

Thanks to core member Joshua Hull for the majority of the caching implementation and Joshua Morris (Onethirtyfive), Arthur Chiu, and DAddYE for the Caching documentation.

Here's an example of the caching gem usage:

# app/app.rb
class Sample < Padrino::Application
  register Padrino::Helpers
  register Padrino::Mailer
  register Padrino::Cache
  ...
end

# lib/awesome.rb
Padrino.cache.set(:categories, Category.all) # => this is shared between apps
Sample.cache.set(:background, Image.order("RAND()").first) # => this is used only by Sample app

# app/controllers.rb
Sample.controllers do
  get :background do
    cache.get(:background)
  end
  ...
end

# demo/controllers.rb
Demo.controllers :cache => true do
  get :foo do
    render :some_thing_longer
  end

  get :bar, :cache => false do
    Padrino.get(:categories)
  end
  ...
end

You can start using this now in your Padrino and Sinatra applications. Let us know what you think.

UJS Adapters

Padrino has been waiting on unobtrusive javascript handling for a while now as well. This enables support for ‘remote’ links and forms as well as setting link ‘methods’ and having the unobtrusive javascript adapters make that ‘just work’.

For more information on these unobtrusive javascript handlers, check out the Helpers Guide which will give you a good overview of what's now available once the UJS adapter is included in your project.

Not all of the adapters are finished for each javascript framework yet, but we intend on getting them integrated soon. Of course, we could always use your help! jquery and prototype UJS adapters are complete but the others are only in partial states of completion.

Check out the padrino-static project to see all of the files associated with this effort. Please fork and help us improve this adapters.

You can read about how to add a new javascript component or add UJS support in the Adding Components guide.

An example code:

# /app/views/users/new.html.haml
- form_for :user, url(:create, :format => :js), :remote => true do |f|
  .content=partial "/users/form"

which will generate the following unobtrusive markup:

<form data-remote="true" action="../../../items/create.js" method="post">
  <div class="content">
    <input type="text" id="post_title" name="post[title]">
    <input type="submit" value="Create">
  </div>
</form>

# /app/controllers/users.rb
  post :create, :provides => :js do
    @user = User.new(params[:user])
    if @user.save
      "$('form.content').html('#{partial("/users/form")}');"
    else
      "alert('User is not valid');"
    end
  end

This feature should make javascript and ajax handling in Sinatra / Padrino easier then ever before.

Routing Enhancements

In this release, Joshua Hull has also completely rewrote http_router, the router library that powers Padrino under the hood.

This rewrite does not break compatibility with previous padrino releases and does not break the existing routing syntax.

The changes are mostly abstracted away from usage in Padrino, but the router is now leaner, faster and easier to extend.

Since it was designed to be more flexible, it also supports multiple named parameter captures and other things that weren't support in the previous release of Padrino.

Some examples:

# app/controllers.rb
get :show, :map => '/pictures/*path.html' do
  ...
end

get :index do
  # Generates: "/?account[name]=foo&account[surname]=bar"
  url(:index, "account[name]" => "foo", "account[surname]" => "bar")
end

get "/email/:email", :format => :json do |email|
  # => foo@bar.com
  email
end

Our new router is still under continued development but should not cause any breaking changes when you upgrade your applications. If you run into any issues please let us know!.

Erubis and Slim Helper Support

In the past few versions, we have had partial Slim and Erubis support but not full compatibility with our various helpers.

This was because of broken implementations of capture and concat for those template engines (described here).

Thankfully with the help of Makoto Kuwata of Erubis and Andrew Stone of Slim, and a couple patches to Tilt, we have been able to correct this and bring about full support for our helpers in Slim and Erubis bringing them in line with the existing support for Haml and ERB. The template engines are also supported by the Padrino generator now as well.

As for tilt and sinatra, Erubis is the new standard engine for processing erb files. Another enhancement allows Padrino to use mixed templates combining templates and partials from multiple engines.

For example:

# views/yours.haml
%p=partial 'show/an/erb/partial.erb'

# partial.erb
<%= some code in erb here %>

This has been a tremendous effort getting these engines to work together and to provide full helper support for Slim, Erubis, ERB, and HAML. Thanks specifically to DAddYE of our core team for the implementation. Also RKH from the Sinatra team for his help.

Sessions and Flash

Rack::Flash is no longer dependent on rack’s default sessions, so you are able to use Rack::Flash with other session engines such as memcached, datamapper, mongomapper etc…

Unfortunately you’ll now need to update your projects to specifically enable sessions inside your app.rb to use Rack::Flash, otherwise an error will be returned.

class PadrinoWeb < Padrino::Application
  enable :sessions
end

Select Tag Enhancements

Thanks to ActiveStylus, the select tag also sports a number of improvements. You can now specify the options as a range directly:

select_tag(:favorite_color, :options => (1..3))

or pass in a grouped options set:

grouped_options = {'Friends'=>['Yoda',['Obiwan',1]], 'Enemies'=>['Palpatine','Vader']}
select_tag(:name, :grouped_options => grouped_options)

All previous select tag options should work without any breaking compatibility issues.

Secret key for sessions

Now according to the new Sinatra we have a session_secret and rake task to generate new keys. In projects generated with Padrino 0.9.25 this will be generated in your app.rb as default, if you upgrade from an older project you can use our rake task.

Some code:

# app/app.rb
class Sample < Padrino::Application
  set :session_secret, "6ca7e9fd7b1eb5a447ae3ba55495621c9169e8ec236ef19829a7684cf86f2404"
  ...
end

# Generate a secret key
$ padrino-dev rake secret
=> Executing Rake secret ...
7043bc560e73c46f0d5eabedbabd217f9f5277e6935047bb9430296ab7b47a44

Logger Improvements

Our logger got several major readability enhancements and now logs cache set and cache get with the amount of time spent.

An example:

# First request
DEBUG - [08/Apr/2011 22:02:17] "MONGODB padrino_www_development['accounts'].find({:_id=>nil})"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0121ms) 127.0.0.1 - - /admin/ HTTP/1.1 - 302 -"
DEBUG - [08/Apr/2011 22:02:17] "MONGODB padrino_www_development['accounts'].find({:_id=>nil})"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0269ms) 127.0.0.1 - - /admin/sessions/new HTTP/1.1 - 200 1749"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0010ms) 127.0.0.1 - - /admin/stylesheets/themes/default/style.css?1268092944 HTTP/1.1 - 200 6741"
DEBUG - [08/Apr/2011 22:02:17] "MONGODB padrino_www_development['accounts'].find({:_id=>nil})"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0023ms) 127.0.0.1 - - /admin/stylesheets/override.css?1302292937 HTTP/1.1 - 302 -"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0008ms) 127.0.0.1 - - /admin/stylesheets/base.css?1269259073 HTTP/1.1 - 200 4774"
DEBUG - [08/Apr/2011 22:02:17] "MONGODB padrino_www_development['accounts'].find({:_id=>nil})"
DEBUG - [08/Apr/2011 22:02:17] "GET (0.0097ms) 127.0.0.1 - - /admin/sessions/new HTTP/1.1 - 200 1749"
DEBUG - [08/Apr/2011 22:02:20] "Resolving layout /src/padrino-web/app/views/layouts/application"

# Second request
DEBUG - [08/Apr/2011 22:03:10] "GET Cache (0.0002ms) /"
DEBUG - [08/Apr/2011 22:03:10] "GET (0.0083ms) 127.0.0.1 - - / HTTP/1.1 - 200 18475"

Other significant changes

  • Padrino logger can now be disabled – commit
  • Uses official mongomapper release – commit
  • Fixes issue with ERB capture support in certain edge cases – commit
  • Fixes ajax jquery detection [Thanks funny-falcon!] – commit
  • Added Lib to folders to be reloaded in development – commit
  • Added mounted app name to the log for debugging – commit
  • Fixes to Form Builder and object name generation [Thanks funny-falcon!] – commit
  • stylesheet_link_tag and javascript_include_tag (allow array input) – pull

Looking at Projects using Padrino

Padrino development has been continuing along fairly smoothly with the release 0.9.23 that supports Sinatra 1.2. The last few releases have worked through a lot of the most annoying issues that could prevent new users from getting started. We have also been updating the guides to fix many inconsistencies.

Still, one aspect we haven’t talked about too much on our blog yet is the community around Padrino. Specifically, the applications and libraries that have been built on Padrino since the framework was released in November 2009. Recently, we created a projects page that provides a guide to all the Padrino applications and libraries our team knows about. This post will highlight the most interesting of these projects in more detail.

Padrino Applications

There have been a great deal of Sinatra + Padrino applications released into the wild over the last 2 years. Many of these have actually been Lipsiasoft websites built in Padrino by Davide, one of our core team members. Padrino originally started in part because of Davide’s interest in using Sinatra at his own Italy-based consulting company.

In addition to the applications released and deployed by the core team, there have also been a number of interesting applications built by others in the community. A few are highlighted below.

Fikus

Fikus is the “Simple Ruby CMS” created by Tim Gourley of the Engine Yard team. This simple content management features an admin interface, markdown for page contents, easy extensibility, mongodb-backed data store, and page caching.

Right now, the easiest way to use fikus is to simply fork the project and begin making your own changes. All you need to do is clone the project locally and then use bundler to install dependencies. In addition, you need to be running mongodb for persistence.

Piccioto

Piccioto is a “minimalistic website framework based on Padrino” created by Andrea Pavoni of digitalbricks in Italy. This simple website framework allows you to create simple hybrid web sites containing static and dynamic components. This framework is composed of many tools which can be used for easy web development and features Html5 Boilerplates, Haml Templates, Sass stylesheets, Rspec testing and semi-static page support.

Right now, the easiest way to use Piccioto is to simply fork the project and begin making your own changes. All you need to do is clone the project locally and then use bundler to install dependencies. Next you can put static pages in app/views/main/static and add other routes as necessary to your application.

Presto

Presto is an effort to combine Padrino with Nesta to build a simple Sinatra-based CMS that can be mounted into a larger application. This project was created by Wynn Netherland who works a popular podcast about open-source called TheChangeLog. Padrino was actually featured on the program about 9 months ago where they interviewed us about Padrino.

The easiest way to use this project is to simply clone the repository and mount it as a sub-application in your Padrino project.

Notable Mentions

In addition to those projects, there are many others out there which we know about and many more which we don’t! Here is a list of a few more we thought were worth checking out:

  • Padrino Web – The web application powering our official Padrino website and blog.
  • pergola – Created by Ryan Fitz and provides a web front-end to MongoDB.
  • haircut – Created by Uchio Kondo and is a simple url shortener in Padrino and MongoDB.
  • moolah – Created by Elliot Winkler and is a tiny money management application.
  • mashup – Created by Michael Lang and is a simple RSS feed reader.
  • me-tee – Created by Josef Pospíšil and is a small shop for a t-shirt business.

If you have a project built on Padrino that is not mentioned here, please let us know about it!

Padrino Libraries

There are also many libraries built to extend Padrino’s functionality. Many of these provide excellent features to make development even easier. We select three to feature below:

padrino-fields

padrino-fields by activestylus is a framework to make form building even easier in Padrino applications. Once you install this application and register this in a Padrino app:

# Gemfile
gem "padrino-fields"
# app.rb
register PadrinoFields
set :default_builder, 'PadrinoFieldsBuilder'

You can begin using forms such as:

app/views/form.haml
- form_for @user do |f|
  = f.input :username
  = f.input :password
  = f.submit

This will generate a form with labels for username and password – supplying the appropriate inputs, labels and error messages on missing/invalid fields. PadrinoFields looks at your database columns to generate default inputs. Currently only supports datamapper but can be extended to support any component.

simple-navigation

simple-navigation by Andi Schacke is a module that makes creating simple navigations with multiple levels easy in Rails, Sinatra or Padrino applications. You can render your navigation as an html list, link list or with breadcrumbs.

Simply install the application with:

# Gemfile
gem 'sinatra-simple-navigation', :require => 'sinatra/simple-navigation'
# app.rb
register Sinatra::SimpleNavigation

and then run bundle install and begin defining your navigation structure. For examples, check out the simple nav demos.

padrino-warden

padrino-warden by Dotan J. Nahum is a module that provides authentication for your Padrino application through Warden.

Notable Mentions

There are other libraries definately worth checking out listed below:

If you have a library built on Padrino that is not mentioned here, please let us know about it!

People Using Padrino

There are also a number of developers and consulting companies that have been using Padrino for various projects. A few of them we know of are listed below:

This is only a very small list of the people using Padrino. Since we never made much of an effort to compile this information before, we would love to know if you are using Padrino or picking modules into your Sinatra applications. We want to post more regularly on the community around Padrino in the future. You can let us know by sending us a message on Github (nesquena, achiu, daddye) or on our google groups or through email to nesquena(AT)gmail(DOT)com. Look forward to hearing from you.


  • Prev Page
  • Next Page