Module: Merb::AssetsMixin

Includes:
Merb::Assets::AssetHelpers
Defined in:
lib/merb-assets/assets_mixin.rb

Overview

The AssetsMixin module provides a number of helper methods to views for linking to assets and other pages, dealing with JavaScript and CSS.

Constant Summary

Constants included from Merb::Assets::AssetHelpers

Merb::Assets::AssetHelpers::ASSET_FILE_EXTENSIONS

Instance Method Summary collapse

Methods included from Merb::Assets::AssetHelpers

#asset_path

Instance Method Details

Parameters

none

Returns

html<String>

Examples

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)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/merb-assets/assets_mixin.rb', line 26

def auto_link
  html    = ""
  prefix  = ""
  (controller_name / action_name).split("/").each do |path|
    path = prefix + path

    css_path  = path + ".css"
    if File.exists? Merb.root / "public" / "stylesheets" / css_path
      html << %{<link rel="stylesheet" type="text/css" href="/stylesheets/#{css_path}" /> }
    end

    js_path   = path + ".js"
    if File.exists? Merb.root / "public" / "javascripts" / js_path
      html << %{<script type="text/javascript" language="javascript" src="/javascripts/#{js_path}"></script>}
    end

    #Update the prefix for the next iteration
    prefix += path / ""
  end

  #Return the generated HTML
  html
end

#css_include_tag(*stylesheets) ⇒ Object

Parameters

*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.

Options

: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.

Returns

String

The CSS include tag(s).

Examples

 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" />


491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/merb-assets/assets_mixin.rb', line 491

def css_include_tag(*stylesheets)
  options = stylesheets.last.is_a?(Hash) ? stylesheets.pop : {}
  return nil if stylesheets.empty?

  reload = options[:reload] || Merb::Config[:reload_templates]

  if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && stylesheets.size > 1
    bundler = Merb::Assets::StylesheetAssetBundler.new(bundle_name, *stylesheets)
    bundled_asset = bundler.bundle!
    return css_include_tag(bundled_asset)
  end

  tags = ""

  for stylesheet in stylesheets
    href = asset_path(:stylesheet, stylesheet)
    href += href.include?('?') ? "&#{random_query_string}" : "?#{random_query_string}" if reload
    attrs = {
      :href => href,
      :type => "text/css",
      :rel => "Stylesheet",
      :charset => options[:charset] || 'utf-8',
      :media => options[:media] || :all
    }
    tags << %Q{<link #{attrs.to_xml_attributes} />}
  end

  return tags
end

#escape_js(javascript) ⇒ Object

Parameters

javascript<String>

Text to escape for use in JavaScript.

Examples

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."


133
134
135
# File 'lib/merb-assets/assets_mixin.rb', line 133

def escape_js(javascript)
  (javascript || '').gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
end

#image_tag(img, opts = {}) ⇒ Object

Parameters

img<~to_s>

The image path.

opts<Hash>

Additional options for the image tag (see below).

Options (opts)

: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.

Examples

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">


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/merb-assets/assets_mixin.rb', line 100

def image_tag(img, opts={})
  if img[0].chr == '/'
    opts[:src] = img
  else
    opts[:path] ||=
      if img =~ %r{^https?://}
        ''
      else
        if Merb::Config[:path_prefix]
          Merb::Config[:path_prefix] + '/images/'
        else
          '/images/'
        end
      end
    opts[:src] ||= opts.delete(:path) + img
  end
  random = opts.delete(:reload) || Merb::Config[:reload_templates]
  opts[:src] += opts[:src].include?('?') ? "&#{random_query_string}" : "?#{random_query_string}" if random
  %{<img #{ opts.to_xml_attributes } />}
end

#include_required_css(options = {}) ⇒ Object

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.

Parameters

options<Hash>

Options to pass to css_include_tag.

Returns

String

The CSS tag.

Options

: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.

Examples

# 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"/>


397
398
399
# File 'lib/merb-assets/assets_mixin.rb', line 397

def include_required_css(options = {})
  required_css(options).map { |req_js| css_include_tag(*req_js) }.join
end

#include_required_js(options = {}) ⇒ Object

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.

Parameters

options<Hash>

Options to pass to js_include_tag.

Options

:bundle<~to_s>

The name of the bundle the scripts should be combined into.

Returns

String

The JavaScript tag.

Examples

# 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>


365
366
367
# File 'lib/merb-assets/assets_mixin.rb', line 365

def include_required_js(options = {})
  required_js(options).map { |req_js| js_include_tag(*req_js) }.join
end

#js(data) ⇒ Object

Parameters

data<Object>

Object to translate into JSON. If the object does not respond to :to_json, then data.inspect.to_json is returned instead.

Examples

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\"]"


148
149
150
151
152
153
154
# File 'lib/merb-assets/assets_mixin.rb', line 148

def js(data)
  if data.respond_to? :to_json
    data.to_json
  else
    data.inspect.to_json
  end
end

#js_include_tag(*scripts) ⇒ Object

Parameters

*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.

Options

:bundle<~to_s>

The name of the bundle the scripts should be combined into.

Returns

String

The JavaScript include tag(s).

Examples

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>


429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/merb-assets/assets_mixin.rb', line 429

def js_include_tag(*scripts)
  options = scripts.last.is_a?(Hash) ? scripts.pop : {}
  return nil if scripts.empty?
  
  reload = options[:reload] || Merb::Config[:reload_templates]

  if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && scripts.size > 1
    bundler = Merb::Assets::JavascriptAssetBundler.new(bundle_name, *scripts)
    bundled_asset = bundler.bundle!
    return js_include_tag(bundled_asset)
  end

  tags = ""

  for script in scripts
    src = asset_path(:javascript, script)
    src += src.include?('?') ? "&#{random_query_string}" : "?#{random_query_string}" if reload
    attrs = {
      :src => src,
      :type => "text/javascript"
    }
    tags << %Q{<script #{attrs.to_xml_attributes}></script>}
  end

  return tags
end

Parameters

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.

Examples

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>


66
67
68
69
# File 'lib/merb-assets/assets_mixin.rb', line 66

def link_to(name, url='', opts={})
  opts[:href] ||= url
  %{<a #{ opts.to_xml_attributes }>#{name}</a>}
end

#require_css(*css) ⇒ Object

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.

Parameters

*css<~to_s>

CSS files to include.

Examples

<% 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"/>


325
326
327
328
# File 'lib/merb-assets/assets_mixin.rb', line 325

def require_css(*css)
  @required_css ||= []
  @required_css << css
end

#require_js(*js) ⇒ Object

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.

Parameters

*js<~to_s>

JavaScript files to include.

Examples

<% 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>


295
296
297
298
# File 'lib/merb-assets/assets_mixin.rb', line 295

def require_js(*js)
  @required_js ||= []
  @required_js << js
end

#required_css(options = {}) ⇒ Object

All css files to include, without duplicates.

Parameters

options<Hash>

Default options to pass to css_include_tag.



334
335
336
# File 'lib/merb-assets/assets_mixin.rb', line 334

def required_css(options = {})
  extract_required_files(@required_css, options)
end

#required_js(options = {}) ⇒ Object

All javascript files to include, without duplicates.

Parameters

options<Hash>

Default options to pass to js_include_tag.



304
305
306
# File 'lib/merb-assets/assets_mixin.rb', line 304

def required_js(options = {})
  extract_required_files(@required_js, options)
end

#uniq_css_path(*assets) ⇒ Object

Parameters

*assets

Creates unique paths for stylesheet files (prepends “/stylesheets” and appends “.css”)

Returns

Array

Full unique paths to assets OR

String

if only a single path is requested

Examples

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"]


587
588
589
590
591
592
593
# File 'lib/merb-assets/assets_mixin.rb', line 587

def uniq_css_path(*assets)
  paths = []
  assets.collect.flatten.each do |filename|
    paths.push(Merb::Assets::UniqueAssetPath.build(asset_path(:stylesheet,filename)))
  end
  paths.length > 1 ? paths : paths.first
end

#uniq_css_tag(*assets) ⇒ Object

Parameters

*assets

As uniq_css_tag but has unique path

Returns

Array

Full unique paths to assets OR

String

if only a single path is requested

Examples

uniq_css_tag("my")
#=> <link href="http://assets2.my-awesome-domain.com/stylesheets/my.css" type="text/css" />


619
620
621
# File 'lib/merb-assets/assets_mixin.rb', line 619

def uniq_css_tag(*assets)
  css_include_tag(*uniq_css_path(assets))
end

#uniq_js_path(*assets) ⇒ Object

Parameters

*assets

Creates unique paths for javascript files (prepends “/javascripts” and appends “.js”)

Returns

Array

Full unique paths to assets OR

String

if only a single path is requested

Examples

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"]


565
566
567
568
569
570
571
# File 'lib/merb-assets/assets_mixin.rb', line 565

def uniq_js_path(*assets)
  paths = []
  assets.collect.flatten.each do |filename|
    paths.push(Merb::Assets::UniqueAssetPath.build(asset_path(:javascript,filename)))
  end
  paths.length > 1 ? paths : paths.first
end

#uniq_js_tag(*assets) ⇒ Object

Parameters

*assets

As js_include_tag but has unique path

Returns

Array

Full unique paths to assets OR

String

if only a single path is requested

Examples

uniq_js_tag("my")
#=> <script type="text/javascript" src="http://assets2.my-awesome-domain.com/javascripts/my.js"></script>


605
606
607
# File 'lib/merb-assets/assets_mixin.rb', line 605

def uniq_js_tag(*assets)
  js_include_tag(*uniq_js_path(assets))
end

#uniq_path(*assets) ⇒ Object

Parameters

*assets

The assets to include. These should be the full paths to any static served file

Returns

Array

Full unique paths to assets OR

String

if only a single path is requested

Examples

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"


543
544
545
546
547
548
549
# File 'lib/merb-assets/assets_mixin.rb', line 543

def uniq_path(*assets)
  paths = []
  assets.collect.flatten.each do |filename|
    paths.push(Merb::Assets::UniqueAssetPath.build(filename))
  end
  paths.length > 1 ? paths : paths.first
end