pubba
pubba is a library designed to help you manage your site. It uses Sprockets for packaging assets and R18n for internationalization/localization. I use R18n as a central location for default text, the internationalization functionality is a nice bonus in the event the application needs to move in that direction.
Note
This extension is under heavy, heavy development and is subject to massive changes over the next week or so.
I do not consider this project production ready at this time. It will be soon though.
TODO:
- More tests!
- Improve documentation!
Why?
There's really two main driving forces behind this extension: audit requirements and code organization.
If you've ever had to deal with an audit department, you understand some of the strict requirements that can be placed on releases. One of the main themes in audit is providing proof on what was released.
Any process that involves changing code between environments, even in an automated fashion, is great fodder for the audit machine. This extension makes sure the javascript and css you work with in development is the same as it will be in production.
As mentioned, code organization is another focus of pubba. The config file pubba.yml uses the global section to clearly state which assets should be on all pages. This functionality is not restricted to your local assets. The pubba config file also allows you to declare external assets. In short, you should not have a single script tag in your views other than those generated by the page_head_tags
and page_body_tags
helpers provided by pubba.
In addition, when using R18n, pubba gives you access through a single page object. This allows you to have all your static text in a central location.
Settings
More details on these later, but here are the configuration options:
A couple of things to note:
- settings.root refers to <ProjectRoot>/app/**
- Images are not processed and should be stored in your public directory
Sample configuration
Pubba.configure do |p|
# REQUIRED.
p.config_file = File.join( File.dirname(__FILE__), 'pubba.yml')
# REQUIRED.
p.asset_folder = File.join(settings.root, 'assets')
# REQUIRED.
p.public_folder = settings.public_folder
# OPTIONAL. Defaults to 'css'
p.style_folder = 'css'
# OPTIONAL. Defaults to 'js'
p.script_folder = 'js'
# OPTIONAL. Defaults to Sprockets: https://github.com/sstephenson/sprockets/
p.asset_handler = Pubba::Assets::SprocketsHandler
# OPTIONAL. Defaults to YUI Compressor: https://github.com/sstephenson/ruby-yui-compressor/
p.asset_minifier = Pubba::Assets::YUIMinifier
# OPTIONAL. Asset hosts (value must be a Proc)
p.asset_host = -> asset { [ "http://assets.mysite.com#{asset}",
"http://assets1.mysite.com#{asset}"].sample }
# OPTIONAL.
p.r18n_folder = File.join(settings.root, 'i18n')
# OPTIONAL.
p.r18n_locale, 'en'
end
How?
First things first, you'll want to install the gem:
gem install pubba
Then you'll want to use it in your app like so:
require 'pubba'
class App < Sinatra::Application
# Settings as described above
set :public_folder, File.join(settings.root, '..', 'public')
Pubba.configure do |p|
p.config_file = File.join(settings.root, '..', 'config', 'pubba.yml')
p.public_folder = settings.public_folder
p.asset_folder = File.join(settings.root, 'assets')
p.r18n_folder = File.join(settings.root, 'i18n')
end
end
Next up is creating the all important pubba.yml config file:
global:
styles:
all:
urls:
- "http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css"
- "custom/global"
phone:
media: "only screen and (min-width: 480px)"
urls:
- "custom/large"
desktop:
media: "only screen and (max-width: 480px)"
urls:
- "custom/small"
scripts:
head:
- "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
- "third-party/modernizr"
body:
- "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"
- "third-party/backbone"
- "custom/app"
- "custom/tracker"
# Home page configuration
home:
styles:
all:
urls:
- "custom/home"
# Search results page configuration
search:
styles:
all:
urls:
- "custom/search"
scripts:
body:
- "custom/lightbox"
The config file is referencing the javascripts and stylesheets located in the asset_folder
. The default folder structure for assets:
# Javascript assets
{asset_folder}/js/
# Stylesheet assets
{asset_folder}/css/
# After processing javascripts will be placed in:
{public_folder}/js/
# After processing stylesheets will be placed in:
{public_folder}/css/
Now you obviouslly need some helpers to make use of the definitions in pubba.yml, and here they are:
page_head_tags
- This helper emits the
link
and script
tags with the contents defined in pubba.yml
page_body_tags
- This helper emits the
script
tag with the contents defined in pubba.yml. You would typically place this just before the </body>
tag.
Sample use:
html
head
title = @page.title
== page_head_tags
body
menu
a href="/" = @page.home_link
== page_body_tags
What you'll see when working with pubba is that the files in your asset_folder
are never referenced in your view. Even in development mode! The intent is that development mode is as close to production mode as possible. So, you are working with the same combined asset file you will be deploying.
Using the above pubba.yml configuration, if you are using the 'home' page definition, the output of page_head_tags
will be (formatted for the README):
<link href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css" rel="stylesheet" type="text/css"></link>
<link href="/css/home-all.css" rel="stylesheet" type="text/css"></link>
<link href="/css/home-phone.css" media="only screen and (max-width: 480px)" rel="stylesheet" type="text/css"></link>
<link href="/css/home-desktop.css" media="only screen and (min-width: 480px)" rel="stylesheet" type="text/css"></link>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="/js/home-head.js" type="text/javascript"></script>|
Again, using the above pubba.yml configuration, if you are using the 'home' page definition, the output of page_body_tags
will be (formatted for the README):
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script src="/js/home-body.js" type="text/javascript"></script>
Monitoring changes
To monitor your assets directory to keep the public directory in sync, you'll need to create a rake task:
namespace :pubba do
desc 'Process the js and css assets then monitor for changes'
task :monitor do
# Require your app to configure Pubba
require_relative 'app/app'
require 'pubba/monitor'
# The monitor process will only run Site.process when it detects a
# change so we need to run it once to make sure the public directory
# is in sync.
puts ">> Processing assets..."
Pubba::Site.process
Pubba::Monitor.run
end
end
R18n
If you're using R18n, you will need a translation file, here's a sample en.yml:
home:
title: "Home title"
meta_description: "Home meta description"
meta_keywords: "Home keywords"
welcome_text: "Welcome Home"
logout_link: "Logout"
login_link: "Login"
home_link: "Home"
account_link: "My Account"
Take note of the home section in both pubba.yml and en.yml. If you have a route in your app that you want to use the home defintions, do this:
get '/' do
@page = Pubba::Site.page('home')
slim :"aux/index"
end
The @page
variable gives you access to the definitions in en.yml. In your view you'll be able to use it like so:
html
head
title = @page.title
body
menu
a href="/" = @page.home_link
Notice that title
is defined under the home
section, but home_link
is a top level definition. Pubba makes the effort to correctly resolve the en.yml reference for you. Nice isn't it.
Acknowledgement
Huge thanks to my company, Primedia for encouraging open source contributions.
Contributors
I highly value contributions and will happily list all those who submit accepted pull requests.
Blanton Black : Id atttribute support on style tag
Chas Lemley : YUI Compressor support