This is the most convenient way to set up your CSS/JS (and images) in a Sinatra app. Seriously. No need for crappy routes to render Sass or whatever. No-siree!
/app
like so (you can configure directories don't worry):
/app/js
/app/css
/app/images
register Sinatra::AssetPack
and set up options to your app (see below)<%= css :application %>
to your layouts. Use this instead of
messy script and link tags$ gem install sinatra-assetpack
Sinatra AssetPack is a simple Ruby gem. You can install it via gem install
.
gem 'sinatra-assetpack', :require => 'sinatra/assetpack'
If you use Bundler, you will need to add it to your Gemfile.
require 'sinatra/assetpack'
class App < Sinatra::Base
set :root, File.dirname(__FILE__)
register Sinatra::AssetPack
assets {
serve '/js', from: 'app/js' # Optional
serve '/css', from: 'app/css' # Optional
serve '/images', from: 'app/images' # Optional
# The second parameter defines where the compressed version will be served.
# (Note: that parameter is optional, AssetPack will figure it out.)
js :app, '/js/app.js', [
'/js/vendor/**/*.js',
'/js/app/**/*.js'
]
css :application, '/css/application.css', [
'/css/screen.css'
]
js_compression :jsmin # Optional
css_compression :sass # Optional
}
end
Install the plugin and add some options. (Feel free to omit the Optional items, they're listed here for posterity):
<%= css :application, :media => 'screen' %>
<%= js :app %>
In your layouts, use the css
and js
helpers:
(Use haml? Great! Use != css :youreawesome
instead.)
<link rel='stylesheet' class='/css/screen.849289.css' media='screen' type='text/css' />
<script type='text/javascript' src="/img/spacer.gif">
If you're on development mode, it serves each of the files as so:
<link rel='stylesheet' class='/css/application.849289.css' media='screen' type='text/css' />
<script type='text/javascript' src="/img/spacer.gif">
If you're on production mode, it serves a compressed version in the URLs you specify:
CoffeeScript support Just add your coffee files in one of the paths
served (in the example, app/js/hello.coffee
) and they will be available as JS
files (localhost:4567/js/hello.js
).
Sass/Less/SCSS support Works the same way. Place your dynamic CSS files
in there (say, app/css/screen.sass
) and they will be available as CSS files
(localhost:4567/css/screen.css
).
Cache busting the css
and js
helpers automatically ensures the URL
is based on when the file was last modified. The URL /js/jquery.js
may be
translated to /js/jquery.8237898.js
to ensure visitors always get the latest
version.
Images support Image filenames in your CSS will automatically get a
cache-busting suffix (eg, /images/icon.742958.png
).
Embedded images support You can embed images in your CSS files as
data:
URIs by simply adding ?embed
to the end of your URL.
No intermediate files needed You don't need to generate compiled files. You can, but it's optional. Keeps your source repo clean!
Auto minification (with caching) JS and CSS files will be compressed as needed.
Heroku support Oh yes. That's right.
assets {
js_compression :jsmin # :jsmin | :yui | :closure | :uglify
css_compression :simple # :simple | :sass | :yui | :sqwish
}
By default, AssetPack uses JSMin for JS
compression, and simple regexes for CSS compression. You can specify other
compressors in the assets
block:
assets {
js_compression :yui
js_compression :yui, :munge => true # Munge variable names
css_compression :yui
}
This uses Yahoo's Java-powered YUI compressor. For YUI compression, you need the
YUI compressor gem (gem install yui-compressor
).
# Gemfile
gem 'yui-compressor', :require => 'yui/compressor'
Note: This depends on the yui-compressor
gem. You will need to install it.
(gem install yui-compressor
) If you use Bundler, you will need to add it to
your Gemfile as well.
assets {
css_compression :sass
}
For SASS compression, you need the Sass gem (gem install sass
). This treats
the CSS files as Scss files and uses Sass's :output => :compressed
.
# Gemfile
gem 'sass'
Note: This depends on the sass
gem. You will need to install it (gem
install sass
). If you use Bundler, you will need to add it to your Gemfile as
well.
assets {
css_compression :sqwish
css_compression :sqwish, :strict => true
}
Sqwish is a NodeJS-based CSS compressor. To use
Sqwish with AssetPack, install it using npm install -g sqwish
. You need NodeJS
and NPM installed.
assets {
js_compression :closure
js_compression :closure, :level => "SIMPLE_OPTIMIZATIONS"
}
This uses the Google closure compiler service to compress your JavaScript. Available levels are:
WHITESPACE_ONLY
SIMPLE_OPTIMIZATIONS
ADVANCED_OPTIMIZATIONS
assets {
js_compression :uglify
js_compression :uglify, [options]
}
This uses the UglifyJS compressor to compress your JavaScript. You will need to install the uglifier gem.
For options, refer to the Uglifier documentation.
# Gemfile
gem 'uglifier'
# If you're on Heroku:
gem "therubyracer-heroku", "0.8.1.pre3", :require => false
Note: This depends on the uglifier
gem. In your Gemfile, you will need to
add it. For Heroku support, you will need to add the therubyracer-heroku
gem
as well.
<!-- Original: --> <%= img '/images/email.png' %>
<!-- Output: --> <img src="/img/spacer.gif">
To show images, use the img
helper.
This automatically adds width, height, and a cache buster thingie.
ImageMagick is required to generate full image tags with width and height.
/* Original: */ .email { "need_to_build_the_files">Need to build the files?
# Rakefile
APP_FILE = 'app.rb'
APP_CLASS = 'App'
require 'sinatra/assetpack/rake'
Actually, you don't need to—this is optional! But add this to your Rakefile
:
Invoking
$ rake assetpack:build
Now invoke the assetpack:build
Rake task. This will create files in /public
.
class App < Sinatra::Base
register Sinatra::AssetPack
# Style 1
assets do
css :hello, [ '/css/*.css' ]
js_compression :yui
end
# Style 2
assets do |a|
a.css :hello, ['/css/*.css' ]
a.js_compression :yui
end
end
All configuration happens in the assets
block. You may invoke it in 2 ways:
App.assets
App.assets.js_compression #=> :yui
Invoking it without a block allows you to access the options. This works for
almost all the options, with the exception for css
, js
and serve
.
# Usage
serve 'PATH', :from => 'LOCALPATH'
Serves files from LOCALPATH
in the URI path PATH
. Both parameters are
required.
serve '/js', from: '/app/javascripts'
This makes /app/javascripts/vendor/jquery.js
available as localhost:4567/js/vendor/jquery.js
.
# Usage:
assets {
js_compression :ENGINE
js_compression :ENGINE, OPTIONS_HASH
css_compression :ENGINE
css_compression :ENGINE, OPTIONS_HASH
}
Sets the compression engine to use for JavaScript or CSS. This defaults to
:jsmin
and :simple
, respectively.
If OPTIONS_HASH
is given as a hash, it sets options for the engine to use.
assets {
css_compression :sqwish
css_compression :sqwish, :strict => true
}
Yo seriously check this out: the first line uses Sqwish with it's defaults, and the second line uses Sqwish with it's magic.
# Usage:
assets {
js_compression_options HASH
css_compression_options HASH
}
Sets the options for the compression engine to use. This is usually not needed
as you can already set options using js_compression
and css_compression
.
css_compression_options :munge => true
This sets the option for :munge
for the CSS compression engine.
# Usage:
assets {
css :NAME, [ PATH1, PATH2, ... ]
css :NAME, 'URI', [ PATH1, PATH2, ... ]
js:NAME, [ PATH1, PATH2, ... ]
js:NAME, 'URI', [ PATH1, PATH2, ... ]
}
Adds packages to be used.
The NAME
is a symbol defines the ID for that given package that you can use
for the helpers. That is, If a CSS package was defined as css :main, [ ... ]
,
then you will need to use <%= css :main %>
to render it in views.
the URI
is a string that defines where the compressed version will be served.
It is optional. If not provided, it will default to "/assets/name.type"
(eg:
/assets/main.css
).
the PATHs
is an array that defines files that will be served. Take note that
this is an array of URI paths, not local paths.
If a PATH
contains wildcards, it will be expanded in alphabetical order.
Redundancies will be taken care of.
class App < Sinatra::Base
assets {
serve '/js', from: '/app/javascripts'
js :application, [
'/js/vendor/jquery.*.js',
'/js/vendor/jquery.js'
]
}
end
# In views: <%= js :application %>
In this example, JavaScript files will be served compressed as
/js/application.js
(default since no URI
is given). The files will be taken
from ./app/javascripts/vendor/jquery*.js
.
# Usage:
assets {
ignore FILESPEC
}
Excludes any URL paths that match the given spec.
These files will not show up in packages, and they will not be accessible.
By default, .*
and _*
are ignored. The former protects folders such as
.svn
from being accessed, and the latter protects Sass partial files from
being accessed directly.
Note that this matches against URL paths, not local file paths. This means
something like *.scss
will not work, as all stylesheet files will be compiled
to .css
.
class App < Sinatra::Base
assets {
# Ignores all files matching *.private.js in any folder.
ignore '*.private.js'
# Ignores all files in `/app/js/foo/**/*`
ignore '/js/foo'
}
end
Here's an example.
assets {
clear_ignores!
ignore '*.private.js'
}
By default, .*
and _*
are ignored. To disable this behavior, you can use
clear_ignores!
before your ignore
lines.
assets.ignored?("/css/_chrome.css") #=> true
To check if a certain file is ignored, use assets.ignore?
# Usage:
prebuild {true|false}
Caches the built packages on application startup.
If this is not used, the packages will be minified when they are first
requested. This only has an effect in the production environment (or when
Sinatra's reload_templates
is otherwise set to false).
class App < Sinatra::Base
assets {
js_compression :closure
js :application, [
'/js/vendor/jquery.*.js',
'/js/vendor/jquery.js'
]
prebuild true
}
end
# $ RACK_ENV=production ruby app.rb
# ** Building /assets/application.js...
# == Sinatra/1.2.6 has taken the stage on 4567 for production
# >> Thin web server (v1.2.11 codename Bat-Shit Crazy)
# >> Maximum connections set to 1024
# >> Listening on 0.0.0.0:4567, CTRL+C to stop
In this example, the package for :application
will be built when the
application is started in the production environment.
These are helpers you can use in your views.
# Usage:
<%= css :PACKAGE %>
<%= css :PACKAGE_1, :PACKAGE_2, ... :PACKAGE_N, OPTIONS_HASH %>
<%= css :PACKAGE, OPTIONS_HASH %>
Shows a CSS package named PACKAGE
. If OPTIONS_HASH
is given, they will we
passed onto the <link>
tag to be generated as attributes.
You may specify as many packages as you need, as shown in the second usage line.
<%= css :main, media: 'screen' %>
<!-- Output: -->
<link rel='stylesheet' type='text/css' class='/css/main.873984.css' media='screen' />
This links to the main
stylesheet for screen media.
<%= css :base, :app, :main, media: 'screen' %>
<!-- Output: -->
<link rel='stylesheet' type='text/css' class='/css/base.873984.css' media='screen' />
<link rel='stylesheet' type='text/css' class='/css/app.873984.css' media='screen' />
<link rel='stylesheet' type='text/css' class='/css/main.873984.css' media='screen' />
You may also invoke it with multiple packages.
# Usage:
<%= js :PACKAGE %>
<%= js :PACKAGE_1, :PACKAGE_2, ... :PACKAGE_N, OPTIONS_HASH %>
<%= js :PACKAGE, OPTIONS_HASH %>
Same as css
, but obviously for JavaScript. You may also specify as many packages as you need, just with css
.
<%= js :main, id: 'main_script' %>
<!-- Output: -->
<script type='text/javascript' src="/img/spacer.gif">
This example embeds the main package with an ID.
# Usage:
img 'SRC'
img 'SRC', OPTIONS_HASH
Shows an <img>
tag from the given SRC
. If the images is found in the asset
directories (and ImageMagick is available), width
and height
attributes will
be added.
If OPTIONS_HASH
is given, they will we passed onto the <img>
tag to be
generated as attributes.
<%= img '/images/icon.png', alt: 'Icon' %>
<!-- Output: -->
<img src="/img/spacer.gif">
This example renders an image with an alt tag.
# gem install sinatra/support
Encoding.default_external = 'utf-8'
require 'sinatra/support'
class Main
register Sinatra::CompassSupport
end
No, AssetPack doesn't have built-in Compass support, but you can use Sinatra Support.
For an example of how to use AssetPack with Compass, including on how to use it to generate image sprites, see the Compass example application.
© 2011, Rico Sta. Cruz. Released under the MIT License.
Sinatra-AssetPack is authored and maintained by Rico Sta. Cruz with help from it's contributors. It is sponsored by my startup, Sinefunc, Inc.