Watch our Blog Tutorial Screencast - Padrino Ruby Web Framework

Padrino 0.12.0 - ActiveSupport 4, Rewritten Reloader, Smarter Rendering, and Loads More

Nearly 3 months have come and gone since the release of 0.11.4 and we are all very excited to announce the release of the Padrino 0.12.0! This version is especially significant because it marks what will likely be one of the last major versions before the 1.0 release. The only major component left we are hoping to integrate is a brand new router and as a result dropping 1.9.3 compatibility.

This 0.12.0 release brings several major changes and updates such as dropping ruby 1.8 support, replacing our cache store, rewriting our development code reloader, improving how rendering works, bug fixes and a ton of code cleanup. Full details for this release are below. You should also check out the 0.12.0 upgrade guide as well for a detailed look at moving up from 0.11.X.

ActiveSupport 4 and Dropping Ruby 1.8

In this release, we have officially dropped support for Ruby 1.8.X! Now that Ruby 2.1.0 has been released, Ruby has really come a long way since 1.8.7 and we felt that it was time to move on and look towards the future of Ruby. In doing so, we were able to clean up a lot of old cruft and conditional logic from the codebase! Thanks to @ujifgc and @namusyaka for making this possible.

As a result of this cleanup, Padrino is now compatible with ActiveSupport 3.1 or higher including full compatibility with ActiveSupport 4. We have also added full support for Ruby 2.1 as well in this release.

A Smarter Render

In this release, we have added several key commonly requested features to our rendering component. First, the rendering engine is now aware of the calling controller and as such will automatically lookup templates within the correct folder for the given context.

# app/controllers/pages_controller.rb
SampleApp.controllers :pages do
  get :index do
    # BEFORE
    render "pages/show" # with explicit controller and view
    # AFTER
    render "show" # will now render "pages/show"

We can also now render a template and then render a layout with them using different template engines. Suppose for example that I had an “erb” template and a “haml” layout:

# app/controllers/pages_controller.rb
SampleApp.controllers :pages do
  get :index do
    render("index.erb", :layout => "application.erb")

We can also render templates and partials with blocks now as well. Given this template:

# app/views/foo.haml
%h1 start
  = yield
%h3 end

and this render call:

# app/views/foo.haml
render "foo" do
  content_tag :div, 'inside block!'

and the content block will be rendered when `yield` is invoked within the template.

Better Template Support

In this release, @ujifgc and @namusyaka have substantially rewritten the way that templates are managed within Padrino. There has been a lot of issues with Slim templates since support was introduced especially around handling blocks. In this release, we are now fully compatible with Slim and HAML as far as we know. We’ve also made a breaking change related to this to fall inline with the latest conventions.

In particular, when outputting code within blocks, we should now use an = rather than a -. For example, before we might have written a form with dashes:

- form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do
  - field_set_tag do
      = label_tag :username, :class => 'first'
      = text_field_tag :username, :value => params[:username]

Now in 0.12.0, we want to write them with = instead:

= form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do
  = field_set_tag do
      = label_tag :username, :class => 'first'
      = text_field_tag :username, :value => params[:username]

Note that this is a breaking change and that you should upgrade all your templates to this new format as part of the upgrade process!

Rewriting the Reloader

In this release, @ujifgc and others have made significant rewrites to the development code reloader. As some of you might know, our reloader has been know to be a bit unreliable and slow especially for large projects. We have fought with the reloader for quite a long time to try to wrestle it into submission. We’ve taken another pass at it with the following focuses:

  • Fixes file reloading to be significantly faster in large apps
  • Smarter reloading of modified files
  • No longer swallows important exceptions during reload
  • Less error prone implementation

A great deal of work has went into the new reloader, and we hope that it serves a much more solid base for Padrino code reloading. We will continue to improve this as needed.

Replacing the Cache Stores with Moneta

We are also excited to announce that minad has completely replaced the Padrino cache store system by integrating the Moneta project. This means better maintenance and compatibility with Cache stores and a more complete caching module! This also means a few breaking changes around configuring the cache store:

Padrino.cache ='tmp', app_name, 'cache')

Padrino.cache =, :dir => Padrino.root('tmp', app_name.to_s, 'cache'))

In addition, instead of expires_in for cache expiration, we now want to use just expires:

# Basic, page-level caching
class SimpleApp < Padrino::Application
  register Padrino::Cache
  enable :caching

  get '/foo', :cache => true do
    expires 30 # <-- replacing expires_in
    'Hello world'

Also, the preferred method for getting and setting values directly into the cache has changed as well in favor of the Moneta syntax:

MyApp.cache.set('val', 'test')
MyApp.cache.get('val') # => 'test'

MyApp.cache['val'] = 'test'
MyApp.cache['val'] # => 'test'

We are excited to have a Moneta-backed caching system now. Thanks again to minad for the contribution! You can see full details about the new caching system by checking out the padrino-cache readme!

Mounter Supports Cascade

The Padrino mounter now supports having a request cascade through all the mounted apps thanks to @ujifgc. With cascading enabled, given two apps:

class ::App1 < Padrino::Application
  get(:index) { halt 404, 'index1' }
class ::App2 < Padrino::Application
  get(:index) { 'index2' }

and then the following in `config/apps.rb` with cascade enabled:

# config/apps.rb
Padrino.mount('app1', :cascade => true).to('/foo')

If you were to hit “/foo”, both apps would be checked and “index2” would be returned. This cascade feature is disabled by default and you should be careful to put the root mounted app last within config/apps.rb.

New Task Generator

We also have a brand new generator for rake tasks as well thanks to @namusyaka. Invoking the following command:

$ padrino g task seed -n db -d "Populates the database"

Will now generate the following rake task file:

# lib/tasks/db.rake
namespace :db do
  desc "Populates the database"
  task :seed => :environment do
    # This is a custom task.

Great to have another convenient generator to make developing with Padrino simple and easy! Also be sure to check out the component generator released in 0.11.4 for more generator goodness.

Share Templates Between Apps

One common request we have had is for a better way to handle templates that are shared between apps. Thanks to @ujifgc we now have a very simple solution to reusing templates. We can simply invoke SomeApp.view_path or SomeApp.layout_path as shown below:

# app/controllers/pages_controller.rb
SampleApp.controllers :pages do
  get :index do
    render AnotherApp.view_path("users/index")
    # resolves to full path "/home/user/test/admin/views/users/index"
  get :show do
    render "pages/show", :layout => AnotherApp.layout_path("application")
    # resolves to full layout path "/home/user/test/admin/views/layouts/application"

This is a welcome improvement that helps encourage modular application design for a Padrino project but also allows for layouts and other templates to be easily shared when necessary.

Easier CSRF Filtering

Now, the protect_from_csrf can be passed an :except flag which will disable CSRF from a particular path. This is especially useful if you want to mount a Sinatra or Rack app that should not be protected. You can do this with:

DISALLOWED_CSRF_PATHS = ["/foo", "/bar"]
set :protect_from_csrf, :except => 
  proc {|env| DISALLOWED_CSRF_PATHS.any?{|path| path == env['PATH_INFO'] }}

This would disable CSRF protection for the “/foo” and “/bar” paths but still enable the protection for all other routes. You can use any conditions by leveraging the env yielded within the lambda.

Customize Asset Paths

Another commonly requested feature is to be able to configure the asset paths (javascript, css) within Padrino. By default the CSS path is public/stylesheets and the JS path is public/javascripts. Now, we can configure these asset paths by simply adjusting them in the settings:

class SimpleApp < Padrino::Application
  set :css_asset_folder, 'css'
  set :js_asset_folder, 'js'

Now, when we call stylesheet_link_tag or javascript_include_tag, the files will be expected in public/css or public/js respectively.

Other changes and fixes

A full list of other changes can be found on Github but an abridged version has been appended below:

  • FIX #1421 Prevent double-escaped HTML in simple_format (@inkstak)
  • FIX #1423 Adds MIT license to gemspec (@ujifgc)
  • FIX #1121 Modify the encoding of crypted_password (@namusyaka)
  • FIX #1428 logger constants to match stdlib (@spariev)
  • FIX #775 track I18n locale files properly (@ujifgc)
  • FIX #1435 broken slim templates (@namusyaka)
  • NEW #1436 support rails-style attribute hash of select options (@ujifgc)
  • FIX #1443 Don’t step over :session_id setting on admin apps (@dariocravero)
  • NEW #1452 Modified `padrino start` to take an extra `—options` (`-O`) parameter (@dariocravero)
  • NEW #1455 Steak generator written for acceptance tests (@eturk)
  • NEW #1452 Allow padrino start to take handler specific options
  • FIX #1462 cache content_type (@ujifgc)
  • FIX #1466 Change accepts to empty array to fix latest sinatra
  • FIX #1431 incorrect behavior when using content_tag with block (@namusyaka)
  • FIX #1457 Major helpers cleanup (@ujifgc)
  • NEW #1405 Params is now converted to `HashWithIndifferentAccess` (@Ortuna)
  • FIX #1391 Skip path_traversal protection (@namusyaka)
  • NEW #1471 allow configuring codes of cascade apps (@ujifgc)
  • NEW #1477 Add :as option to form_for helper (@graudeejs)
  • FIX #1481 incorrect namespace of #named_routes (@namusyaka)
  • FIX #1461 Allow to render template with layout that using other template engine (@namusyaka)
  • NEW #767 introduces App.view_path and App.layout_path (@ujifgc)
  • FIX #1488 plugin generator url path to github (@bolshakov)
  • FIX #915 use app.root when mounting if available (@ujifgc)
  • NEW #1414 drop ruby 18mode, liberate ActiveSupport
  • NEW #711 Verify render with block now works as expected (@ujifgc)
  • NEW #1504 allow partial with block (@ujifgc)
  • FIX #1507 patch jruby utf-8 method naming (@ujifgc)
  • FIX #1505 Remove charset from json mimetype, fix sinatra edge (@namusyaka)
  • FIX #1513 Extracting logic to methods to improve readability (@scudelletti)
  • FIX #1517 correctly set a name of mounted application (@ujifgc)
  • NEW #1518 Add :flush option to content_for (@namusyaka)
  • FIX #1523 Add Rakefile tasks to the component generator (@tyabe)
  • FIX #1526 options on ActiveRecord version 3 (@tyabe)
  • NEW #1528 Allow asset_folders to be configured in settings
  • FIX #1529 double escaping of link urls (@ujifgc)
  • FIX #1532 allow asset_path with no kind (@ujifgc)
  • FIX #1535 rebase string urls to uri_root (@ujifgc)
  • NEW #1539 Enable :except option to :protect_from_csrf (@namusyaka)
  • FIX #1540 generator should abort if constant name already exists (@namusyaka)
  • NEW #922 resolve templates relative to controller name (@ujifgc)
  • NEW #1541 Reimplement authenticity token logic (@namusyaka)
  • FIX development dependency for padrino-gen (@namusyaka)
  • FIX #1520 Skip loading models for sequel migration tasks (@ujifgc)
  • FIX #1493 make admin aware of uri_root (@ujifgc)
  • NEW #854 allow -a master to rename admin path (@ujifgc)
  • FIX Get tests passing again on rubinius (@ujifgc)
  • FIX #1545 Don’t raise on protect_from_csrf without sessions (@skade)
  • FIX #1546 Silence deprecation warnings for File.exists? (@fj)
  • REMOVE #1516 support for TestSpec component from generator (@ujifgc)
  • FIX resolve_template should respect :views option (@ujifgc)
  • FIX #1547 Rename `showexceptions.rb` to `show_exceptions.rb` (@namusyaka)
  • NEW #1551 Introduce #default method to set application options (@ujifgc)
  • FIX #1553 Chinese time translations (@gokure)
  • FIX #1556 German translations (@Signum)
  • FIX #1555 Fix a problem the before/after filters (@namusyaka)
  • FIX #1550 Shove LOADING/RELOADING to devel log level
  • FIX #1445 Drop `PADRINO_ENV` in favour of `RACK_ENV` for further compatibility (@dariocravero)
  • FIX #1578 Fix latvian translations (@graudeejs)
  • FIX #1576 incorrect nl.yml translations (@fevers)
  • FIX #1564 do not reload apps with disabled or absent :reload flag (@ujifgc)
  • FIX #1571 Allow for url generation to accept stringified keys (@jsmpereira)
  • NEW #1570 add custom index option for form_for abstract form helper (@graudeejs)
  • FIX #1567 Add :app option to the component generator (@namusyaka)
  • FIX #1563 Fix behavior of content_tag when use with content that is not a string (@tyabe)
  • NEW #1422 allow options Hash in protect_from_csrf (@ujifgc)

Want to give a special thanks to the key contributors for this release, working tirelessly to make this Padrino release happen: @ujifgc, @namusyaka, @dariocravero, and @Ortuna. Thanks so much!

Please report any issues you encounter with this release! We are working very actively on Padrino and want to make the framework as stable and reliable as possible. That concludes the changelog for this release. As always if you want to keep up with Padrino updates, be sure to follow us on twitter: @padrinorb, join us on IRC at “#padrino” on freenode or open an issue on GitHub.

blog comments powered by Disqus

Write at least 4 chars
Matches are highlighted



  • Author namusyaka
  • Posted almost 2 years ago