Class: Rack::Backbone

Inherits:
Object
  • Object
show all
Includes:
JQuery::Helpers
Defined in:
lib/rack/backbone.rb,
lib/rack/backbone/version.rb

Overview

Backbone CDN script tags and fallback in one neat package.

Defined Under Namespace

Modules: CDN

Constant Summary collapse

BACKBONE_FILE_NAME =

Current file name of fallback.

"backbone-#{BACKBONE_VERSION}-min.js"
BACKBONE_SOURCE_MAP_UNVERSIONED =

Fallback source map file name without version. Because the main script doesn’t call a versioned file.

"backbone-min.map"
BACKBONE_SOURCE_MAP =

Fallback source map file name.

"backbone-#{BACKBONE_VERSION}-min.map"
DEFAULT_OPTIONS =

Default options hash for the middleware.

{
  :http_path => "/js"
}
FALLBACK_TOP =

This javascript checks if the Backbone object has loaded. If not, that most likely means the CDN is unreachable, so it uses the local minified Backbone. It’s the top half, it gets pieced together elsewhere.

<<STR
<script type="text/javascript">
  if (typeof Backbone == 'undefined') {
    document.write(unescape("%3Cscript src='
STR
FALLBACK_BOTTOM =

Bottom half of the fallback script.

<<STR
' type='text/javascript'%3E%3C/script%3E"))
  };
</script>
STR
VERSION =

the version of this library

"0.1.0"
BACKBONE_VERSION =

the version of Backbone it supports.

"1.0.0"
BACKBONE_VERSION_DATE =
TODO:

remember to change Last-Modified with each release!

This is the release date of the Backbone file, it makes an easy “Last-Modified” date for setting the headers around caching.

"Wed, 20 Mar 2013 12:13:55 +0000"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Backbone

Returns a new instance of Backbone.

Examples:

# The default:
use Rack::Backbone

# With a default organisation:
use Rack::Backbone, :organisation => :cloudflare

Parameters:

  • app (#call)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :http_path (String)

    If you wish the Backbone fallback route to be “/js/backbone-1.9.1.min.js” (or whichever version this is at) then do nothing, that’s the default. If you want the path to be “/assets/javascripts/backbone-1.9.1.min.js” then pass in ‘:http_path => “/assets/javascripts”.

  • :organisation (Symbol)

    see cdn



105
106
107
108
109
110
# File 'lib/rack/backbone.rb', line 105

def initialize( app, options={} )
  @app, @options  = app, DEFAULT_OPTIONS.merge(options)
  @http_path_to_backbone = ::File.join @options[:http_path], BACKBONE_FILE_NAME
  @http_path_to_source_map = ::File.join @options[:http_path], BACKBONE_SOURCE_MAP_UNVERSIONED
  @organisation = options.fetch :organisation, :media_temple
end

Class Method Details

.cdn(env, options = {}) ⇒ String

Returns The HTML script tags to get the CDN.

Parameters:

  • env (Hash)

    The rack env hash.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • organisation (Symbol)

    Choose which CDN to use, either :jsdelivr, or :cloudflare (the default). This will override anything set via the ‘use` statement. Pass in `false` to force use of the local Backbonejs script. `nil` will force choosing the default CDN.

  • :debug (TrueClass)

    Pass ‘true` to get the unminified version of the script from the CDN.

Returns:

  • (String)

    The HTML script tags to get the CDN.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rack/backbone.rb', line 60

def self.cdn( env, options={}  )
  if env.nil? || env.has_key?(:organisation)
    fail ArgumentError, "The Rack::Backbone.cdn method needs the Rack environment passed to it, or at the very least, an empty hash."
  end
      
  debug = options.fetch :debug, false

  organisation =  options[:organisation]
  if organisation.nil?
    organisation = 
      env["rack.backbone.organisation"] ||
      :media_temple
  end

  unless organisation == false
    script_src = case organisation
      when :cloudflare
        CDN::CLOUDFLARE
      when :jsdelivr
        CDN::JSDELIVR
      else
        CDN::CLOUDFLARE
    end

    script_src = "#{script_src[0..-8]}.js" if debug

    %Q!<script src='#{script_src}'></script>\n#{FALLBACK_TOP}#{env["rack.backbone.http_path"]}#{FALLBACK_BOTTOM}!
  else
    "<script src='#{env["rack.backbone.http_path"]}'></script>"
  end

end

Instance Method Details

#_call(env) ⇒ Object

For thread safety

Parameters:

  • env (Hash)

    Rack request environment hash.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rack/backbone.rb', line 121

def _call( env )
  request = Rack::Request.new(env.dup)
  env.merge! "rack.backbone.organisation" => @organisation
  env.merge! "rack.backbone.http_path" => @http_path_to_backbone
  if request.path_info == @http_path_to_backbone
    response = Rack::Response.new
    # for caching
    response.headers.merge! caching_headers( BACKBONE_FILE_NAME, BACKBONE_VERSION_DATE)

    # There's no need to test if the IF_MODIFIED_SINCE against the release date because the header will only be passed if the file was previously accessed by the requester, and the file is never updated. If it is updated then it is accessed by a different path.
    if request.env['HTTP_IF_MODIFIED_SINCE']
      response.status = 304
    else
      response.status = 200
      response.write ::File.read( ::File.expand_path "../../../vendor/assets/javascripts/#{BACKBONE_FILE_NAME}", __FILE__)
    end
    response.finish
  elsif request.path_info == @http_path_to_source_map
    response = Rack::Response.new
    # No need for caching with the source map
    response.status = 200
    response.write ::File.read( ::File.expand_path "../../../vendor/assets/javascripts/#{BACKBONE_SOURCE_MAP}", __FILE__)
    response.finish
  else
    @app.call(env)
  end
end

#call(env) ⇒ Object

Parameters:

  • env (Hash)

    Rack request environment hash.



114
115
116
# File 'lib/rack/backbone.rb', line 114

def call( env )
  dup._call env
end