Module | Merb::AssetsMixin |
In: |
lib/merb-assets/assets_mixin.rb
|
The AssetsMixin module provides a number of helper methods to views for linking to assets and other pages, dealing with JavaScript and CSS.
none
html<String>
We want all possible matches in the FileSys up to the action name Given: controller_name = "namespace/controller" action_name = "action" If all files are present should generate link/script tags for: namespace.(css|js) namespace/controller.(css|js) namespace/controller/action.(css|js)
img<~to_s>: | The image path. |
opts<Hash>: | Additional options for the image tag (see below). |
:path<String>: | Sets the path prefix for the image. Defaults to "/images/" or whatever is specified in Merb::Config. This is ignored if img is an absolute path or full URL. |
All other options set HTML attributes on the tag.
image_tag('foo.gif') # => <img src='/images/foo.gif' /> image_tag('foo.gif', :class => 'bar') # => <img src='/images/foo.gif' class='bar' /> image_tag('foo.gif', :path => '/files/') # => <img src='/files/foo.gif' /> image_tag('http://test.com/foo.gif') # => <img src="http://test.com/foo.gif"> image_tag('charts', :path => '/dynamic/') or image_tag('/dynamic/charts') # => <img src="/dynamic/charts">
name<~to_s>: | The text of the link. |
url<~to_s>: | The URL to link to. Defaults to an empty string. |
opts<Hash>: | Additional HTML options for the link. |
link_to("The Merb home page", "http://www.merbivore.com/") # => <a href="http://www.merbivore.com/">The Merb home page</a> link_to("The Ruby home page", "http://www.ruby-lang.org", {'class' => 'special', 'target' => 'blank'}) # => <a href="http://www.ruby-lang.org" class="special" target="blank">The Ruby home page</a> link_to p.title, "/blog/show/#{p.id}" # => <a href="/blog/show/13">The Entry Title</a>
javascript<String>: | Text to escape for use in JavaScript. |
escape_js("'Lorem ipsum!' -- Some guy") # => "\\'Lorem ipsum!\\' -- Some guy" escape_js("Please keep text\nlines as skinny\nas possible.") # => "Please keep text\\nlines as skinny\\nas possible."
data<Object>: | Object to translate into JSON. If the object does not respond to :to_json, then data.inspect.to_json is returned instead. |
js({'user' => 'Lewis', 'page' => 'home'}) # => "{\"user\":\"Lewis\",\"page\":\"home\"}" js([ 1, 2, {"a"=>3.141}, false, true, nil, 4..10 ]) # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
name<~to_s>: | The text in the link. |
function<~to_s>: | The onClick event in JavaScript. |
link_to_function('Click me', "alert('hi!')") # => <a href="#" onclick="alert('hi!'); return false;">Click me</a> link_to_function('Add to cart', "item_total += 1; alert('Item added!');") # => <a href="#" onclick="item_total += 1; alert('Item added!'); return false;">Add to cart</a>
You can use require_js(:prototype) or require_css(:shinystyles) from any view or layout, and the scripts will only be included once in the head of the final page. To get this effect, the head of your layout you will need to include a call to include_required_js and include_required_css.
# File: app/views/layouts/application.html.erb <html> <head> <%= include_required_js %> <%= include_required_css %> </head> <body> <%= catch_content :layout %> </body> </html> # File: app/views/whatever/_part1.herb <% require_js 'this' -%> <% require_css 'that', 'another_one' -%> # File: app/views/whatever/_part2.herb <% require_js 'this', 'something_else' -%> <% require_css 'that' -%> # File: app/views/whatever/index.herb <%= partial(:part1) %> <%= partial(:part2) %> # Will generate the following in the final page... <html> <head> <script src="/javascripts/this.js" type="text/javascript"></script> <script src="/javascripts/something_else.js" type="text/javascript"></script> <link href="/stylesheets/that.css" media="all" rel="Stylesheet" type="text/css"/> <link href="/stylesheets/another_one.css" media="all" rel="Stylesheet" type="text/css"/> </head> . . . </html>
See each method‘s documentation for more information.
The key to making a fast web application is to reduce both the amount of data transfered and the number of client-server interactions. While having many small, module Javascript or stylesheet files aids in the development process, your web application will benefit from bundling those assets in the production environment.
An asset bundle is a set of asset files which are combined into a single file. This reduces the number of requests required to render a page, and can reduce the amount of data transfer required if you‘re using gzip encoding.
Asset bundling is always enabled in production mode, and can be optionally enabled in all environments by setting the :bundle_assets value in config/merb.yml to true.
In the development environment, this:
js_include_tag :prototype, :lowpro, :bundle => true
will produce two <script> elements. In the production mode, however, the two files will be concatenated in the order given into a single file, all.js, in the public/javascripts directory.
To specify a different bundle name:
css_include_tag :typography, :whitespace, :bundle => :base css_include_tag :header, :footer, :bundle => "content" css_include_tag :lightbox, :images, :bundle => "lb.css"
(base.css, content.css, and lb.css will all be created in the public/stylesheets directory.)
To use a Javascript or CSS compressor, like JSMin or YUI Compressor:
Merb::Assets::JavascriptAssetBundler.add_callback do |filename| system("/usr/local/bin/yui-compress #{filename}") end Merb::Assets::StylesheetAssetBundler.add_callback do |filename| system("/usr/local/bin/css-min #{filename}") end
These blocks will be run after a bundle is created.
Combining the require_css and require_js helpers with bundling can be problematic. You may want to separate out the common assets for your application — Javascript frameworks, common CSS, etc. — and bundle those in a "base" bundle. Then, for each section of your site, bundle the required assets into a section-specific bundle.
N.B.: If you bundle an inconsistent set of assets with the same name, you will have inconsistent results. Be thorough and test often.
In your application layout:
js_include_tag :prototype, :lowpro, :bundle => :base
In your controller layout:
require_js :bundle => :posts
*stylesheets: | The stylesheets to include. If the last element is a Hash, it will be used as options (see below). If ".css" is left out from the stylesheet names, it will be added to them. |
:bundle<~to_s>: | The name of the bundle the stylesheets should be combined into. |
:media<~to_s>: | The media attribute for the generated link element. Defaults to :all. |
String: | The CSS include tag(s). |
css_include_tag 'style' # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> css_include_tag 'style.css', 'layout' # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> # <link href="/stylesheets/layout.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> css_include_tag :menu # => <link href="/stylesheets/menu.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> css_include_tag :style, :screen # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> # <link href="/stylesheets/screen.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" /> css_include_tag :style, :media => :print # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="utf-8" /> css_include_tag :style, :charset => 'iso-8859-1' # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="iso-8859-1" />
A method used in the layout of an application to create +<link>+ tags for CSS stylesheets required in in templates and subtemplates using require_css.
options<Hash>: | Options to pass to css_include_tag. |
String: | The CSS tag. |
:bundle<~to_s>: | The name of the bundle the stylesheets should be combined into. |
:media<~to_s>: | The media attribute for the generated link element. Defaults to :all. |
# my_action.herb has a call to require_css 'style' # File: layout/application.html.erb include_required_css # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> # my_action.herb has a call to require_css 'style', 'ie-specific' # File: layout/application.html.erb include_required_css # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
A method used in the layout of an application to create +<script>+ tags to include JavaScripts required in in templates and subtemplates using require_js.
options<Hash>: | Options to pass to js_include_tag. |
:bundle<~to_s>: | The name of the bundle the scripts should be combined into. |
String: | The JavaScript tag. |
# my_action.herb has a call to require_js 'jquery' # File: layout/application.html.erb include_required_js # => <script src="/javascripts/jquery.js" type="text/javascript"></script> # my_action.herb has a call to require_js 'jquery', 'effects', 'validation' # File: layout/application.html.erb include_required_js # => <script src="/javascripts/jquery.js" type="text/javascript"></script> # <script src="/javascripts/effects.js" type="text/javascript"></script> # <script src="/javascripts/validation.js" type="text/javascript"></script>
*scripts: | The scripts to include. If the last element is a Hash, it will be used as options (see below). If ".js" is left out from the script names, it will be added to them. |
:bundle<~to_s>: | The name of the bundle the scripts should be combined into. |
String: | The JavaScript include tag(s). |
js_include_tag 'jquery' # => <script src="/javascripts/jquery.js" type="text/javascript"></script> js_include_tag 'moofx.js', 'upload' # => <script src="/javascripts/moofx.js" type="text/javascript"></script> # <script src="/javascripts/upload.js" type="text/javascript"></script> js_include_tag :effects # => <script src="/javascripts/effects.js" type="text/javascript"></script> js_include_tag :jquery, :validation # => <script src="/javascripts/jquery.js" type="text/javascript"></script> # <script src="/javascripts/validation.js" type="text/javascript"></script>
The require_css method can be used to require any CSS file anywhere in your templates. Regardless of how many times a single stylesheet is included with require_css, Merb will only include it once in the header.
*css<~to_s>: | CSS files to include. |
<% require_css('style') %> # A subsequent call to include_required_css will render... # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> <% require_css('style', 'ie-specific') %> # A subsequent call to include_required_css will render... # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
The require_js method can be used to require any JavaScript file anywhere in your templates. Regardless of how many times a single script is included with require_js, Merb will only include it once in the header.
*js<~to_s>: | JavaScript files to include. |
<% require_js 'jquery' %> # A subsequent call to include_required_js will render... # => <script src="/javascripts/jquery.js" type="text/javascript"></script> <% require_js 'jquery', 'effects' %> # A subsequent call to include_required_js will render... # => <script src="/javascripts/jquery.js" type="text/javascript"></script> # <script src="/javascripts/effects.js" type="text/javascript"></script>
*assets: | Creates unique paths for stylesheet files (prepends "/stylesheets" and appends ".css") |
Array: | Full unique paths to assets OR |
String: | if only a single path is requested |
uniq_css_path("my") #=> "http://assets2.my-awesome-domain.com/stylesheets/my.css" uniq_css_path(["admin/secrets","home/signup"]) #=> ["http://assets2.my-awesome-domain.com/stylesheets/admin/secrets.css", "http://assets1.my-awesome-domain.com/stylesheets/home/signup.css"]
*assets: | As uniq_css_tag but has unique path |
Array: | Full unique paths to assets OR |
String: | if only a single path is requested |
uniq_css_tag("my") #=> <link href="http://assets2.my-awesome-domain.com/stylesheets/my.css" type="text/css" />
*assets: | Creates unique paths for javascript files (prepends "/javascripts" and appends ".js") |
Array: | Full unique paths to assets OR |
String: | if only a single path is requested |
uniq_js_path("my") #=> "http://assets2.my-awesome-domain.com/javascripts/my.js" uniq_js_path(["admin/secrets","home/signup"]) #=> ["http://assets2.my-awesome-domain.com/javascripts/admin/secrets.js", "http://assets1.my-awesome-domain.com/javascripts/home/signup.js"]
*assets: | As js_include_tag but has unique path |
Array: | Full unique paths to assets OR |
String: | if only a single path is requested |
uniq_js_tag("my") #=> <script type="text/javascript" src="http://assets2.my-awesome-domain.com/javascripts/my.js"></script>
*assets: | The assets to include. These should be the full paths to any static served file |
Array: | Full unique paths to assets OR |
String: | if only a single path is requested |
uniq_path("/javascripts/my.js","/javascripts/my.css") #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/javascripts/my.css"] uniq_path(["/javascripts/my.js","/stylesheets/my.css"]) #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"] uniq_path(%w(/javascripts/my.js /stylesheets/my.css)) #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"] uniq_path('/stylesheets/somearbitrary.css') #=> "http://assets3.my-awesome-domain.com/stylesheets/somearbitrary.css" uniq_path('/images/hostsexypicture.jpg') #=>"http://assets1.my-awesome-domain.com/images/hostsexypicture.jpg"
Merb provides views with convenience methods for links images and other assets.