Skip to content
Padrino is a full-stack ruby framework built upon Sinatra.
Find file
Pull request Compare This branch is 4877 commits behind padrino:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Padrino is the godfather of Sinatra.


This gem has been designed to enhance and build upon the Sinatra Microframework. Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort. The canonical example of how to create an entire simple web application with Sinatra is something like:

# myapp.rb
require 'rubygems'
require 'sinatra'
get '/' do
  'Hello world!'

and then to run the application:

$ ruby myapp.rb

The extreme simplicity of this framework is quite refreshing. We have been using Sinatra a great deal for recent projects. First for small and simple json and xml web services and then even for more complex full-featured applications. This gem represents an attempt to make it as fun and easy as possible to code increasingly advanced web applications in Sinatra.


Many people love Sinatra's simplicity and lightweight but often quickly come to miss a great deal of functionality provided by other web frameworks such as Rails when building non-trivial applications.

The obvious question in these cases might be “Why not just use rails then?”. This can often be a viable option but still Rails is quite a large framework with a 'take it or leave it' attitude. Personally, we have come to love the philosophy of Sinatra which acts as a thin layer on top of rack often allowing middleware to do most of the work and pulling in additional complexity only when required.

My goal with this extension is to match the essence of Sinatra and at the same time create a standard library of tools, helpers and components that will make Sinatra suitable for more complex applications.

Here is a small list of what Padrino provides:


for creating new padrino applications i.e.: padrino-gen app or padrino start on command line


unlike other ruby frameworks Padrino is principally designed for mounting multiple apps at the same time.


Full url named route support to avoid hardcoding route url paths (map, url_for)

Tag Helpers

helpers such as: tag, content_tag, input_tag, …

Asset Helpers

helpers such as: link_to, image_tag, javascript_include_tag, …

Form Helpers

with builder support such as: form_tag, form_for, field_set_tag, text_field, …

Text Helpers

useful formatting extensions like: relative_time_ago, js_escape_html, sanitize_html


fast, tiny, delivery support for send templating emails (like ActionMailer do)


an ajax admin that displays your records in sortable grids, tree, windows … as a desktop app can do.

Keep in mind, the user will be able to pull in these components seperately and leave out those that are not required or use them altogether for a comprehensive upgrade to Sinatra (a full-stack Padrino application).

Note that all work has been created to be compatible with haml, erb, and erubis and that this gem is intended to be template-agnostic in providing helpers wherever possible.

Please help me brainstorm and fork the project if you have any ideas to contribute.


To install the padrino framework, simply grab the latest version from gemcutter:

$ sudo gem install padrino --source

This will install the necessary padrino gems to get you started. Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications.


Padrino is a framework which builds on the existing functionality and Sinatra and provides a variety of additional tools and helpers to extend the foundation. This README and Padrino documentation in general will focus on the enhancements to the core Sinatra functionality. To use Padrino, one should be familiar with the basic usage of Sinatra itself. Resources for Sinatra are listed below:

Below is a guide to how this gem enhances the Sinatra framework as part of a 'full-stack' padrino application. For information on how to use a specific gem in isolation within an existing Sinatra project, checkout the README for that individual gem or gems.

Enhanced Base Application (padrino-core)

Sinatra has support for classes which can be extended to create an application: Sinatra::Base and Sinatra::Application These classes can be extended in order to create a Sinatra web application. These classes provide support for all the basic functionality afforded by Sinatra.

Padrino has support for an enhanced base application class Padrino::Application. Padrino::Application expands the capabilities of Sinatra::Application and automatically provides the resulting application access to all of the padrino framework's functionalities.

Similar in spirit to Sinatra itself, Padrino application layout is extremely flexible and can be as small as a single file. However, Padrino provides many extensions which improve upon the ability to construct more complex applications.

Simple Application Definition

Let us first take a look at the simplest possible Padrino application:

# app.rb
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
require 'padrino'

class SimpleApp < Padrino::Application
  get '/ do
    'Hello world'

Gemfile Dependency Resolution

While this is a fully operational Padrino application in itself, let us take a look at Padrino's expanded capabilites. First, we can create Gemfile within the application root. This will contain a list of all the dependencies for our application.

# /Gemfile
source ''
gem 'sinatra',     :require_as => 'sinatra/base'
gem 'rack-flash'

This manifest file uses the standard bundler gem syntax of which details can be found in the Bundler README This gem allows us to place all our dependencies into a single file. Padrino will then automatically require all necessary files (if they exist on the system).

If the dependencies are not on the system, you can automatically vendor all necessary gems using the gem bundle command within the application root. Note that this is all possible without any further effort than adding the Gemfile (or having this generated automatically with generators explained later).

Auto Load Paths

Padrino also intelligently supports requiring useful files within your application automatically and provides functionality for easily splitting up your application into separate files. Padrino automatically requires config/database.rb as a convention for establishing database connection. Also, any files within the lib folder will be required automatically by Padrino.

This is powered by the fact that Padrino will automatically load (and reload) any directory patterns within the 'load path'. Additional directory patterns can be added to the load path as needed by simply appending to the load_paths within your application:

# app.rb
class SimpleApp < Padrino::Application
  load_paths << ["app/special/*.rb", "some_file.rb"]

This will instruct Padrino to autoload these files (and reload them when changes are detected). By default, the load path contains certain paths known to contain important files such as controllers, mailers, models, urls, and helpers.


Padrino also has support for 'initializers' which are important setup steps or configuration within an application that should occur during the bootup process. To construct initializers, simply add a file to the <tt>config/initializers<tt> directory following this convention:

# config/initializers/example.rb
module ExampleInitializer
  def self.registered(app)
    # Manipulate 'app' here to register components or adjust configuration
    app.set :environment, :production # just an example configuration change
    app.use Hassle # or even enable middleware

Initializers are automatically required and 'registered' during the application startup process. Note that the name of the module must be the name of the file appended with 'Initializer' (i.e sample.rb => SampleInitializer)


Suppose we wanted to add additional routes to our Padrino application, and we want to organize the routes within a more structured layout. Simply add a controllers or app/controllers folder and create a file as such:

# controllers/example.rb
SimpleApp.controllers do
  get "/test" do
    "Text to return"

Application Logging

Padrino also supports robust logging capabilities. By default, logging information will go to the STDOUT in development (for use in a console) and in an environment-specific log file log/development.log in test and production environments.

You can modify the logging behavior or disable logging altogether:

# app.rb
class SimpleApp < Padrino::Application
  disable :logging     # Turns off logging
  enable  :log_to_file # Forces logging to be written to a file

To use the logger within a Padrino application, simply refer to the logger method accessible within your app and any controller or views:

# controllers/example.rb
SimpleApp.controllers do
  get("/test") { "This is a test" }

The logger automatically supports severity through the use of, logger.warn, logger.error, et al. For more information about the logger, check out the Logger RDOC

Mounting Applications

Padrino applications are all automatically mountable into other Padrino projects. This means that a given Padrino project directory can easily mount multiple applications. This allows for better organization of complex applications, re-usable applications that can be applied (i.e admin, auth, blog) and even more flexibility.

You can think of mountable applications as a 'full-featured' merb slice or rails engine. Instead of a separate construct, any application can simply be packaged and mounted into another project.

Padrino stores application mounting information by default within config/apps.rb. This file is intended to keep all information regarding what applications are mounted to which uri's. An apps.rb file has the following structure:


This would mount two applications onto the Padrino project, one served from the '/blog' uri namespace and the other served from the '/website' uri namespace. Often a Padrino project directory requires a single 'core' application which is served from the uri root. This can be easily configured using:

Padrino.mount_core("app_name") # mounts app with class AppName, in file <tt>app/app.rb</tt>
Padrino.mount_core("app_name", :app_file => Padrino.root('app.rb')) # now with file in <tt>app.rb</tt>

This will mount a 'core' application with class AppName from the file 'app.rb' to the uri root which will act as a primary application.

Development Reloader

Padrino applications also have the enabled ability to automatically reload all changing application files without the need to restart the server. Through the use of a customized Rack middleware, all files on the 'load path' are monitored and reloaded whenever changes are applied.

This makes rapid development much easier and provides a better alternative to 'shotgun' or 'rerun' which require the application server to be restarted which makes requests take much longer to complete.

An application can explicitly enable / disable reloading through the use of options:

# app.rb
class SimpleApp < Padrino::Application
  disable :reload # reload is disabled in all environments
  enable  :reload # enabled in all environments

By default, reloading is enabled in development and disabled in the test and production environments.

Terminal Commands

Padrino also comes equipped with multiple useful terminal commands which can be activated to perform common tasks such as starting / stopping the application, executing the unit tests or activating an irb session.

The following commands are available:

# starts the app server (non-daemonized)
$ padrino start 
# starts the app server (daemonized) with given port, environment and adapter
$ padrino start -d -p 3000 -e development -a thin 

# Stops a daemonized app server
$ padrino stop

# Run all the unit tests
$ padrino test

# Bootup the Padrino console (irb)
$ padrino console

Using these commands can simplify common tasks making development that much smoother.

Application Extensions and Helpers (padrino-helpers)

Padrino provides a large number of 'standard' helpers to make development faster and easier. For a detailed look at all of the padrino helpers, check out the documentation within the padrino-helpers README. The following is a whirlwind guide through useful helpers provided by this gem.

Output Helpers

Output helpers are a collection of important methods for managing, capturing and displaying output in various ways and is used frequently to support higher-level helper functions. There are three output helpers worth mentioning: content_for, capture_html, and concat_content

The content_for functionality supports capturing content and then rendering this into a different place such as within a layout. One such popular example is including assets onto the layout from a template:

# app/views/site/index.erb
<% content_for :assets do %>
  <%= stylesheet_link_tag 'index', 'custom' %>
<% end %>

Added to a template, this will capture the includes from the block and allow them to be yielded into the layout:

# app/views/layout.erb
  <%= stylesheet_link_tag 'style' %>
  <%= yield_content :assets %>

This will automatically insert the contents of the block (in this case a stylesheet include) into the location the content is yielded within the layout.

The capture_html and the concat_content methods allow content to be manipulated and stored for use in building additional helpers accepting blocks or displaying information in a template. One example is the use of these in constructing a simplified 'form_tag' helper which accepts a block.

# form_tag '/register' do ... end
def form_tag(url, options={}, &block)
  # ... truncated ...
  inner_form_html = capture_html(&block)
  concat_content '<form>' + inner_form_html + '</form>'

This will capture the template body passed into the form_tag block and then append the content to the template through the use of concat_content. Note have been built to work for both haml and erb templates using the same syntax.

Tag Helpers

Tag helpers are the basic building blocks used to construct html 'tags' within a view template. There are three major functions for this category: tag, content_tag and input_tag.

The tag and content_tag are for building arbitrary html tags with a name and specified options. If the tag contains 'content' within then content_tag is used. For example:

tag(:br, :style => ‘clear:both’) => <br style="clear:both" />
content_tag(:p, "demo", :class => ‘light’) => <p class="light">demo</p>

The input_tag is used to build tags that are related to accepting input from the user:

input_tag :text, :class => "demo" => <input type='text' class='demo' />
input_tag :password, :value => "secret", :class => "demo"

Note that all of these accept html options and result in returning a string containing html tags.

Asset Helpers

Asset helpers are intended to help insert useful html onto a view template such as 'flash' notices, hyperlinks, mail_to links, images, stylesheets and javascript. An example of their uses would be on a simple view template:

# app/views/example.haml
  = stylesheet_link_tag 'layout'
  = javascript_include_tag 'application'
  = flash_tag :notice
  %p= link_to 'Blog', '/blog', :class => 'example'
  %p Mail me at #{mail_to '', "Fake Email Link", :cc => ""}
  %p= image_tag 'padrino.png', :width => '35', :class => 'logo'

For more detailed documentation, check out the padrino-helpers README.

Form Helpers

Form helpers are the 'standard' form tag helpers you would come to expect when building forms. A simple example of constructing a non-object form would be:

- form_tag '/destroy', :class => 'destroy-form', :method => 'delete' do
= flash_tag(:notice)
- field_set_tag do
    = label_tag :username, :class => 'first'
    = text_field_tag :username, :value => params[:username]
    = label_tag :password, :class => 'first'
    = password_field_tag :password, :value => params[:password]
    = label_tag :strategy
    = select_tag :strategy, :options => ['delete', 'destroy'], :selected => 'delete'
    = check_box_tag :confirm_delete
- field_set_tag(:class => 'buttons') do
  = submit_tag "Remove"

For more detailed documentation, check out the padrino-helpers README.

Form Builders

Form builders are full-featured objects allowing the construction of complex object-based forms using a simple, intuitive syntax. Building a form is as follows:

- form_for @user, '/register', :id => 'register' do |f|
= f.error_messages
  = f.label :username, :caption => "Nickname"
  = f.text_field :username
  = f.label :email
  = f.text_field :email
  = f.label :password
  = f.password_field :password
  = f.label :is_admin, :caption => "Admin User?"
  = f.check_box :is_admin
  = f.label :color, :caption => "Favorite Color?"
  = :color, :options => ['red', 'black']
  - fields_for @user.location do |location|
    = location.text_field :street
    = location.text_field :city
  = f.submit "Create", :class => 'button'

There is also support for using more advanced form builders or even creating your own to make form building even easier. For more detailed documentation, check out the padrino-helpers README.

Format Helpers

Format helpers are several useful utilities for manipulating the format of text to achieve a goal. The four format helpers are escape_html, relative_time_ago, time_in_words, and js_escape_html.

The escape_html and js_escape_html function are for taking an html string and escaping certain characters. escape_html will escape ampersands, brackets and quotes to their HTML/XML entities. This is useful to sanitize user content before displaying this on a template. js_escape_html is used for passing javascript information from a js template to a javascript function.

escape_html('<hello>&<goodbye>') # => &lt;hello&gt;&amp;&lt;goodbye&gt;

There is also an alias for escape_html called h for even easier usage within templates.

Format helpers also includes a number of useful text manipulation functions such as simple_format, pluralize, word_wrap, and truncate.

simple_format("hello\nworld") # => "<p>hello<br/>world</p>"
pluralize(2, 'person') => '2 people'
word_wrap('Once upon a time', :line_width => 8) => "Once upon\na time"
truncate("Once upon a time in a world far far away", :length => 8) => "Once upon..."

These helpers can be invoked from any route or view within your application.

For a breakdown of all format helper methods, check out the padrino-helpers README.

Render Helpers

Render helpers are a series of helpers intended to make certain rendering template tasks easier to perform. This section also includes partial support to allow rendering mini-templates.

The haml_template and erb_template functions simply make rendering view templates easier when working with templates inside the views directory. Sinatra provides helpers for this but they work in a way which can be slightly counter-intuitive:

haml :index        # OK, renders the ./views/index.haml
haml 'site/index'  # This renders the literal string 'site/index'
haml :'site/index' # AH, this renders the ./views/site/index.haml

For this reason, additional helpers for erb and haml have been provided which always renders a given file path:

haml_template :index        # OK, renders the ./views/index.haml
haml_template 'site/index'  # This renders ./views/site/index.haml
haml_template :'site/index' # This also renders ./views/site/index.haml

This helper also supports template partials which make rendering small bits of view template within a view much easier. Quick example would be:

# app/views/index.haml
= partial 'photo/item', :object => @photo, :locals => { :foo => 'bar' }

and then the partial would be:

# app/views/photo/_item.haml
# Access to collection counter with <partial_name>_counter i.e item_counter
# Access the object with the partial_name i.e item

Advanced Routing Support (padrino-routing)

Padrino provides support for advanced routing functionality not available within Sinatra. This routing supports named route aliases and easy access to url paths. The benefits of this is that instead of having to hard-code route urls into every area of your application, now we can just define the urls in a single spot and then attach an alias which can be used to refer to the url throughout the application.

For a detailed look at all of padrino routing functionality, check out the documentation within the padrino-routing README. The following is a whirlwind guide through useful route extensions provided by this gem.

Simple Route Aliases

The simplest example of route aliases is to construct named aliases representing a url, and then use the alias to reference the url within the application:

class SimpleApp < Padrino::Application
   # Define the named route mappings

   # Configure the routes using the named alias
  get :account  do
    "name: params[:name] - id: params[:id]"
  get :accounts do
    "I am the body for the url /the/accounts/index"

Padrino Routing Conventions

The convention within a Padrino application is to store 'external' route alias mappings within a special urls file located at urls.rb or config/urls.rb. A url routing file might look like:

# config/urls.rb
SimpleApp.urls do

Urls mapped here can then be defined within a controller:

# app/controllers/example.rb
SimpleApp.controllers do
  get :index do

  get :account do
    # access params[:name] and params[:index]

and finally referenced anywhere in the application:

# app/views/example.haml
= link_to "Index", url_for(:index)
= link_to "Account", url_for(:account, :id => 1, :name => 'first')

Inline Route Alias Definitions

The routing plugin also supports inline route definitions in which the url and the named alias are defined together within the controller:

# app/controllers/example.rb
SimpleApp.controllers do
  get :index, :map => '/index' do

  get :account, :map => '/the/accounts/:name/and/:id' do
    # access params[:name] and params[:index]

Routes defined inline this way can be accessed and treated the same way as traditional named aliases.

Namespaced Route Aliases

There is also support for namespaced routes which are organized into a larger grouping:

# /app/routes/example.rb
SimpleApp.controllers do
  map :admin do |namespace|"/admin/:id/show")

  namespace :admin do
    get :show do
      "admin show for #{params[:id]}"

    get :index, :map => "/admin/:id/index" do
      "admin destroy for #{params[:id]}"

You can then reference the urls using the same url_for method:

<%= link_to 'admin show page', url_for(:admin, :show, :id => 25) %>
<%= link_to 'admin index page', url_for(:admin, :index, :id => 25) %>

Controller Namespaces

In addition to regular namespacing, as a shortcut you can have a controller serve as a namespace as well:

 # /app/routes/admin.rb
SimpleApp.controllers :admin do
  get :index, :map => "/admin/:id/index" do
    "admin destroy for #{params[:id]}"

This will put all named routes within this controller block into the 'admin' namespace and then can be referenced:

<%= link_to 'admin index page', url_for(:admin, :index, :id => 25) %>

Note that controller namespaces are simply a shortcut for standard namespaces and do not differ in any other way.

Simple Mailer Support (padrino-mailer)

Padrino provides support for mailer capabilities to make delivering email within your application as painless as possible and familiar to anyone who has ever used ActionMailer. This functionality is performed using an adapted version of the excellent and lightweight pony but no longer relies upon this as a dependency.

For detailed information on the padrino mailer, check out the padrino-mailer README.

Let’s take a look at using the MailerPlugin in an application. By default, MailerPlugin uses the built-in sendmail functionality on the server. However, SMTP is also supported using the following configuration:

 Padrino::Mailer::Base.smtp_settings = {
   :host   => '',
   :port   => '587',
   :tls    => true,
   :user   => 'user',
   :pass   => 'pass',
   :auth   => :plain

Once that has been defined, the default will become smtp delivery unless overwritten in an individual mail definition. Next, we should define a custom mailer extended from Padrino::Mailer::Base or use the mailer generator (see next section)

$ padrino-gen mailer sample

Once the mailer is generated, we can define the specific email delivery methods

# app/mailers/sample_mailer.rb
class SampleMailer < Padrino::Mailer::Base
  def registration_email(name, user_email_address)
    from ''
    to user_email_address
    subject 'Welcome to the site!'
    body    :name => name
    type    'html'                # optional, defaults to plain/text
    charset 'windows-1252'        # optional, defaults to utf-8
    via     :sendmail             # optional, to smtp if defined otherwise sendmail

This defines mail called ‘registration_mail’ with the specified attributes for delivery. The body method is passing the name attribute to the body message template which should be defined in [views_path]/sample_mailer/registration_email.erb as shown below:

# ./views/sample_mailer/registration_email.erb
This is the body of the email and can access the <%= name %> that was passed in from the mailer definition
That's all there is to defining the body of the email which can be plain text or html

Once the mailer definition has been completed and the template has been defined, the email can be sent using:

SampleMailer.deliver(:registration_email, "Bob", "")

or if you like the method_missing approach:

SampleMailer.deliver_registration_email "Bob", ''

For detailed information or examples using attachments or more advanced techniques, check out the padrino-mailer README.

Agnostic Application Generators (padrino-gen)

Padrino provides support for advanced routing functionality not available within Sinatra. This routing supports named route aliases and easy access to url paths. The benefits of this is that instead of having to hard-code route urls into every area of your application, now we can just define the urls in a single spot and then attach an alias which can be used to refer to the url throughout the application.

For a detailed look at all of padrino generator functionality, check out the documentation within the padrino-generator README. The following is a whirlwind guide through useful generators provided by this gem.

Application Generator

Padrino provides generator support for quickly creating new Padrino applications. This provides many benefits such as constructing the recommended Padrino application structure, auto-generating a Gemfile listing all starting dependencies and guidelines provided within the generated files to help orient a new user to using Padrino.

One important feature of the generators is that they were built from the ground up to support a wide variety of tools, libraries and gems for use within your padrino application.

This means that Padrino generators do not lock you into using any particular database, ORM, testing framework, templating engine or javascript library. In fact, when generating an application you can actually tell Padrino which components you would like to use!

Generating a brand new Padrino project is as simple as a single command on the terminal:

$ padrino-gen app demo_blog . --test shoulda --renderer haml --mock rr --script jquery --orm datamapper

This will automatically create a new folder called 'demo_blog' containing a starting point for the 'DemoBlog' Padrino application using all the components specified during construction.

You can also instruct the generator to skip a certain component to avoid using one at all (or to use your own):

$ padrino-gen demo_app . --test none --renderer none

For information on generating appications, check out the padrino-generator README.

Model Generator

Padrino provides generator support for quickly creating new models within your Padrino application. Note that the models (and migrations) generated are specifically tailored towards the ORM component and testing framework chosen during application generation.

Very important to note that model generators are intended primarily to work within applications created through the Padrino application generator and that follow Padrino conventions. Using model generators within an existing application not generated by Padrino will likely not work as expected.

Using the model generator is as simple as:

$ padrino-gen model User

You can also specify desired fields to be contained within your User model:

$ padrino-gen model User name:string age:integer email:string

The model generator will create multiple files within your application and based on your ORM component. Usually the model file will generate files similar to the following:

* model definition file [app/models/user.rb]
* migration declaration [db/migrate/xxx_create_users.rb]
* model unit test file  [test/models/user_test.rb]

You can define as many models as you would like in a Padrino application using this generator.

Migration Generator

Padrino provides generator for quickly generating new migrations to change or manipulate the database schema. These migrations generated will be tailored towards the ORM chosen when generating the application.

Very important to note that migration generators are intended primarily to work within applications created through the Padrino application generator and that follow Padrino conventions. Using migration generators within an existing application not generated by Padrino will likely not work as expected.

Using the migration generator is as simple as:

$ padrino-gen migration AddFieldsToUsers
$ padrino-gen migration RemoveFieldsFromUsers

You can also specify desired columns to be added to the migration file:

$ padrino-gen migration AddFieldsToUsers last_login:datetime crypted_password:string
$ padrino-gen migration RemoveFieldsFromUsers password:string ip_address:string

The migration generator will then construct the migration file according to your ORM component chosen within db/migrate/xxx_add_fields_to_users.rb including the columns specified in the command.

Controller Generator

Padrino provides generator support for quickly creating new controllers within your Padrino application. Note that the controller tests are generated specifically tailored towards the testing framework chosen during application generation.

Very important to note that controller generators are intended primarily to work within applications created through the Padrino application generator and that follow Padrino conventions.

Using the controller generator is as simple as:

$ padrino-gen controller Admin

You can also specify desired actions to be added to your controller:

$ padrino-gen controller Admin get:index get:new post:create

The controller generator will then construct the controller file within app/controllers/admin.rb and also a controller test file at test/controllers/admin_controller_test.rb according to the test framework chosen during app generation. A default route will also be generated mapping to name of the controller and the route name. For example:

$ padrino-gen controller User get:index

will create a url route for :index mapping to “/user/index” inside config/urls.rb

Mailer Generator

Padrino provides generator support for quickly creating new mailers within your Padrino application. Very important to note that mailer generators are intended primarily to work within applications created through the Padrino application generator and that follow Padrino conventions.

Using the mailer generator is as simple as:

$ padrino-gen mailer UserNotifier

You can also specify desired delivery actions to be added to the mailer:

$ padrino-gen mailer UserNotifier confirm_account welcome inactive_account

The mailer generator will then construct the mailer file within app/mailers/user_notifier.rb

Admin Dashboard and Authentication (padrino-admin)


Painless Page and Fragment Caching (padrino-cache)


Something went wrong with that request. Please try again.