fannypack 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +127 -0
- data/Guardfile +6 -0
- data/LICENSE +22 -0
- data/Procfile +1 -0
- data/README.md +166 -0
- data/Rakefile +50 -0
- data/config.rb +74 -0
- data/fannypack.gemspec +22 -0
- data/lib/assets/javascripts/fanny_pack.coffee +21 -0
- data/lib/assets/javascripts/fanny_pack/ajax.js.coffee +58 -0
- data/lib/assets/javascripts/fanny_pack/env.js.coffee +4 -0
- data/lib/assets/javascripts/fanny_pack/models/environment.js.coffee +15 -0
- data/lib/assets/javascripts/fanny_pack/namespace.coffee +10 -0
- data/lib/assets/javascripts/fanny_pack/routers/base.coffee +82 -0
- data/lib/assets/javascripts/fanny_pack/version.js.coffee +2 -0
- data/lib/assets/javascripts/fanny_pack/views/app.coffee +19 -0
- data/lib/assets/javascripts/fanny_pack/views/base.coffee +90 -0
- data/lib/assets/javascripts/fanny_pack/views/list.coffee +29 -0
- data/lib/fanny_pack.rb +4 -0
- data/lib/fanny_pack/assets.rb +24 -0
- data/lib/fanny_pack/version.rb +4 -0
- data/source/images/background.png +0 -0
- data/source/images/middleman.png +0 -0
- data/source/index.html.haml +9 -0
- data/source/javascripts/application.js.coffee +2 -0
- data/source/javascripts/lib/.gitkeep +0 -0
- data/source/javascripts/vendor/.gitkeep +0 -0
- data/source/layouts/layout.html.haml +49 -0
- data/source/stylesheets/application.css.sass +2 -0
- data/source/stylesheets/lib/_fonts.css.sass +0 -0
- data/source/stylesheets/lib/_mixins.css.sass +0 -0
- data/source/stylesheets/lib/_variables.css.sass +0 -0
- data/source/stylesheets/lib/common.css.sass +1 -0
- data/source/stylesheets/vendor/all.css +55 -0
- data/source/stylesheets/vendor/normalize.css +375 -0
- data/spec/javascripts/helpers/spec_helper.coffee +11 -0
- data/spec/javascripts/support/jasmine-jquery.js +812 -0
- data/spec/javascripts/support/jasmine-sinon.coffee +246 -0
- data/spec/javascripts/support/jasmine.yml +10 -0
- data/spec/javascripts/support/jasmine_helper.rb +3 -0
- data/spec/javascripts/support/sinon-1.7.3.js +4290 -0
- data/spec/javascripts/views/base_spec.coffee +130 -0
- data/spec/javascripts/views/list_spec.coffee +31 -0
- data/vendor/assets/javascripts/backbone-1.1.2.js +1608 -0
- data/vendor/assets/javascripts/jquery-1.11.0.js +10337 -0
- data/vendor/assets/javascripts/json2.js +487 -0
- data/vendor/assets/javascripts/ppx.js +391 -0
- data/vendor/assets/javascripts/underscore-1.5.1.js +1246 -0
- data/vendor/assets/javascripts/uri.js +1803 -0
- data/vendor/assets/javascripts/zepto-detect.js +66 -0
- metadata +150 -0
data/fannypack.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/fanny_pack/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "fannypack"
|
6
|
+
s.version = FannyPack::VERSION
|
7
|
+
s.authors = ["Matt Diebolt", "Steel Fu", "Brad Gessler"]
|
8
|
+
s.email = ["matt@polleverywhere.com", "steel@polleverywhere.com", "brad@polleverywhere.com"]
|
9
|
+
s.homepage = "http://getfannypack.com"
|
10
|
+
s.summary = %q{A simple set of base views to help develop Backbone applications.}
|
11
|
+
s.description = %q{A simple set of base views to help develop Backbone applications.}
|
12
|
+
|
13
|
+
# Manifest
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_development_dependency 'middleman', '~> 3.3'
|
20
|
+
s.add_development_dependency 'growl'
|
21
|
+
s.add_development_dependency 'rb-fsevent'
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Handle lots of commond URL parsing concerns so that we can easily
|
2
|
+
# do stuff like URI('google.com/hi').params({search: 'football'})
|
3
|
+
#= require uri
|
4
|
+
|
5
|
+
# IE8 JSON parsing compatability.
|
6
|
+
# TODO - Remove when we no longer care about IE8.
|
7
|
+
#= require json2
|
8
|
+
|
9
|
+
# Provides $.os support, which jQuery ditched.
|
10
|
+
#= require zepto-detect
|
11
|
+
|
12
|
+
# Fanny Pack prerequisites
|
13
|
+
#= require fanny_pack/namespace
|
14
|
+
#= require fanny_pack/version
|
15
|
+
#= require fanny_pack/models/environment
|
16
|
+
#= require fanny_pack/env
|
17
|
+
|
18
|
+
# Fanny Pack assets
|
19
|
+
#= require_tree ./fanny_pack/routers
|
20
|
+
#= require_tree ./fanny_pack/models
|
21
|
+
#= require_tree ./fanny_pack/views
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#= require ppx
|
2
|
+
|
3
|
+
FannyPack.namespace "FannyPack", (FannyPack) ->
|
4
|
+
FannyPack.BasicAuth =
|
5
|
+
setCredentials: (username, password) ->
|
6
|
+
FannyPack.BasicAuth.username = username
|
7
|
+
FannyPack.BasicAuth.password = password
|
8
|
+
FannyPack.AJAX_DEFAULTS.headers['Authorization'] = "Basic #{btoa(FannyPack.BasicAuth.username + ':' + FannyPack.BasicAuth.password)}"
|
9
|
+
|
10
|
+
FannyPack.AJAX_DEFAULTS =
|
11
|
+
xhrFields: {}
|
12
|
+
headers: {}
|
13
|
+
dataType: 'json'
|
14
|
+
type: 'GET'
|
15
|
+
|
16
|
+
# Deep clone the ajax defaults
|
17
|
+
ajaxDefaults = ->
|
18
|
+
clone = _.clone FannyPack.AJAX_DEFAULTS
|
19
|
+
clone.xhrFields = _.clone FannyPack.AJAX_DEFAULTS.xhrFields
|
20
|
+
clone.headers = _.clone FannyPack.AJAX_DEFAULTS.headers
|
21
|
+
clone
|
22
|
+
|
23
|
+
# Cross Domain polyfill for IE8
|
24
|
+
# ---
|
25
|
+
# IMPORTANT: We MUST call toString() on this method or IE will barf on allow
|
26
|
+
# other URLS to access the domain. For example, IE would request the URL
|
27
|
+
# 'multiple_choice_polls/[object]' without throwing an error message.
|
28
|
+
|
29
|
+
# PPX Proxy JS will determine whether iframe needs SSL or not
|
30
|
+
polyfillCORS = (options, xhr) ->
|
31
|
+
# A PPX end-point lives in our rails_app server at the /ppx location.
|
32
|
+
path = FannyPack.env.get('api_url').path()
|
33
|
+
ppxUrl = FannyPack.env.get('api_url').path("/ppx#{path}")
|
34
|
+
|
35
|
+
FannyPack.PPXRequest ||= PPX.buildClientConstructor ppxUrl.toString()
|
36
|
+
|
37
|
+
if (options.crossDomain && !$.support.cors) || options.usePostMessage
|
38
|
+
options.xhr = FannyPack.PPXRequest
|
39
|
+
options.crossDomain = false
|
40
|
+
xhr.isProxiedThroughPostMessage = true
|
41
|
+
|
42
|
+
$.ajaxPrefilter (options, originalOptions, xhr) ->
|
43
|
+
_.defaults options, ajaxDefaults()
|
44
|
+
|
45
|
+
# Only set this up if we're given a relative path. Paths with domains
|
46
|
+
# should just flow through to the next uri mutations.
|
47
|
+
url = URI(options.url).absoluteTo(FannyPack.env.get('api_url'))
|
48
|
+
url.setQuery 'cache_buster', (new Date).getTime().toString() if $.os?.android
|
49
|
+
options.url = url.toString()
|
50
|
+
|
51
|
+
# Check if this is a cross domain request.
|
52
|
+
# CORS PPX polyfill uses this to determine if PPX should be used.
|
53
|
+
options.crossDomain = !url.absoluteTo('/').equals(URI(window.location.href).absoluteTo('/'))
|
54
|
+
|
55
|
+
# We need this for CORS + Cookies to work when using jQuery
|
56
|
+
options.xhrFields.withCredentials ?= true
|
57
|
+
|
58
|
+
polyfillCORS(options, xhr)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
FannyPack.namespace "FannyPack.Model", (Model) ->
|
2
|
+
class Model.Environment extends Backbone.Model
|
3
|
+
currentHost = window?.location?.host
|
4
|
+
protocol = window?.location?.protocol
|
5
|
+
defaults:
|
6
|
+
api_url: "//#{currentHost}"
|
7
|
+
ssl: protocol is 'https:'
|
8
|
+
|
9
|
+
get: (key) ->
|
10
|
+
switch
|
11
|
+
# When a key ends with _url, wrap it in an URI.js object so we can mutate it.
|
12
|
+
when key.match(/_url$/)
|
13
|
+
URI(super(key))
|
14
|
+
else
|
15
|
+
super(key)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
if module?.exports?
|
2
|
+
global.FannyPack ||= {}
|
3
|
+
else
|
4
|
+
window.FannyPack ||= {}
|
5
|
+
|
6
|
+
FannyPack.namespace = (target, name, block) ->
|
7
|
+
[target, name, block] = [(if global? then global else window), arguments...]
|
8
|
+
top = target
|
9
|
+
target = target[item] or= {} for item in name.split '.'
|
10
|
+
block target, name
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# The FannyPack.Router.Base is considered our most global application
|
2
|
+
# state for applications. Its assumed that only one router should
|
3
|
+
# be running at a given time within the context of a single runtime.
|
4
|
+
#
|
5
|
+
# Views and Templates all have access to the router via the `@app`
|
6
|
+
# method.
|
7
|
+
FannyPack.namespace "FannyPack.Router", (Router) ->
|
8
|
+
{Model} = FannyPack
|
9
|
+
|
10
|
+
class Router.Base extends Backbone.Router
|
11
|
+
# Default app name. Sets the default <title> on the page and
|
12
|
+
# is used in error messaging.
|
13
|
+
appName: "FannyPack App"
|
14
|
+
|
15
|
+
constructor: ->
|
16
|
+
# Lets prevent confusion for the clowns out there who try
|
17
|
+
# initializing 2 routers in the same runtime.
|
18
|
+
throw Error "FannyPack.app already initialized with '#{@appName}'" if FannyPack.app
|
19
|
+
FannyPack.app = @
|
20
|
+
|
21
|
+
# Convient access to the FannyPack.env from
|
22
|
+
# applications
|
23
|
+
@env = FannyPack.env
|
24
|
+
|
25
|
+
# What's that? You turned logging on? SWEET! You
|
26
|
+
# get to hear about everything that's happening in the
|
27
|
+
# event bus.
|
28
|
+
if @env.get('logging_enabled')
|
29
|
+
@on 'all', =>
|
30
|
+
@log 'App Event', arguments
|
31
|
+
|
32
|
+
# View manager responsible for de-activating old views and activating new ones
|
33
|
+
@view = new View.App
|
34
|
+
|
35
|
+
# We call super last since this calls the `initialize` method,
|
36
|
+
# which assumes everything above is all set and ready to go.
|
37
|
+
super
|
38
|
+
|
39
|
+
# Take care of all the messy bootstrapping of browser globals and singletons to
|
40
|
+
# the router, render a view, bootstrap user data from the server, and start
|
41
|
+
# Backbone.history routing. Basically all of the gross browser bootstrapping should
|
42
|
+
# go here.
|
43
|
+
#
|
44
|
+
# If you're trying to setup the router for testing, you should either decompose this
|
45
|
+
# method or manually start the browser's history.
|
46
|
+
start: (opts={pushState: true}) =>
|
47
|
+
throw Error "Specify a view property in the initialize method of the router" unless @view
|
48
|
+
|
49
|
+
{pushState, el} = opts
|
50
|
+
|
51
|
+
# Render the view first on the element since the login state could
|
52
|
+
# change what's rendered.
|
53
|
+
el.append @view.render().$el
|
54
|
+
|
55
|
+
# Start the router
|
56
|
+
Backbone.history.start(pushState: pushState)
|
57
|
+
|
58
|
+
@
|
59
|
+
|
60
|
+
# Returns the current location of the application.
|
61
|
+
location: ->
|
62
|
+
# This assumes that we're in a web browser context.
|
63
|
+
window.location.pathname.substring(1)
|
64
|
+
|
65
|
+
# Go "back" through the browsers history.
|
66
|
+
navigateBack: ->
|
67
|
+
Backbone.history.history.back()
|
68
|
+
|
69
|
+
# Default in backbone is to *not* trigger to execute the route handler,
|
70
|
+
# which is undesirable and feels like unexpected behavior for our devs.
|
71
|
+
navigate: (fragment, options = {trigger: true}) ->
|
72
|
+
super fragment, options
|
73
|
+
|
74
|
+
# Log tracing messages to a logging device if enabled.
|
75
|
+
log: =>
|
76
|
+
console.log(arguments...) if @env.get('logging_enabled')
|
77
|
+
|
78
|
+
# Change the title of the page and notify views/models that
|
79
|
+
# care about a title change what's up.
|
80
|
+
title: (title = @appName) =>
|
81
|
+
document?.title = title
|
82
|
+
@trigger "change:title", title
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#= require_tree ../views
|
2
|
+
|
3
|
+
FannyPack.namespace "FannyPack.View", (View) ->
|
4
|
+
class View.App extends View.Base
|
5
|
+
className: 'fannypack'
|
6
|
+
|
7
|
+
initialize: (opts = {}) ->
|
8
|
+
@currentView = null
|
9
|
+
|
10
|
+
activate: (view) =>
|
11
|
+
@currentView?.remove()
|
12
|
+
@currentView = view
|
13
|
+
@$el.append view.render().$el
|
14
|
+
|
15
|
+
currentPage: =>
|
16
|
+
@currentView
|
17
|
+
|
18
|
+
render: =>
|
19
|
+
@
|
@@ -0,0 +1,90 @@
|
|
1
|
+
FannyPack.namespace 'FannyPack.View', (View) ->
|
2
|
+
class View.Base extends Backbone.View
|
3
|
+
include: (modules...) ->
|
4
|
+
for module in modules
|
5
|
+
_.extend this, module(this)
|
6
|
+
|
7
|
+
constructor: (options = {}) ->
|
8
|
+
# Set the app for this view to the base application
|
9
|
+
# that FannyPack.Router.Base sets up in its initialize method.
|
10
|
+
@app ||= FannyPack.app
|
11
|
+
|
12
|
+
{title, template} = options
|
13
|
+
|
14
|
+
# Set the page title if we're given one.
|
15
|
+
@title = title if title?
|
16
|
+
|
17
|
+
# Override the template if specified
|
18
|
+
@template = template if template?
|
19
|
+
|
20
|
+
# TODO - Figure out how to show the full namespace
|
21
|
+
# of the view that's being rendered (and not just the prototype name)
|
22
|
+
# Make it easier for non-lib devs to find views.
|
23
|
+
@app.log "Constructing View", @
|
24
|
+
|
25
|
+
# Tell the router what the title of our window should be.
|
26
|
+
@app.title @title if @title
|
27
|
+
|
28
|
+
# make sure we have an external events hash
|
29
|
+
# if the child class hasn't defined one
|
30
|
+
@appEvents ?= {}
|
31
|
+
|
32
|
+
# Setup Backbone.View last since it fires the
|
33
|
+
# subclasses' `initialize` method, which assumes
|
34
|
+
# everything above is setup.
|
35
|
+
super
|
36
|
+
|
37
|
+
# Listen to a list of events and fire callback only once
|
38
|
+
# e.g. @listenToChanges @poll, "max_votes web_enabled sms_enabled", @refreshPage
|
39
|
+
# The above will call @refreshPage only once instead of 3 times for each attribute
|
40
|
+
# change event
|
41
|
+
listenToChanges: (model, attributes, callback) =>
|
42
|
+
attributes = attributes.split /\s+/
|
43
|
+
@listenTo model, 'change', (model) ->
|
44
|
+
changedAttributes = _.keys model.changed
|
45
|
+
|
46
|
+
if _.intersection(changedAttributes, attributes).length
|
47
|
+
callback.apply(@, model)
|
48
|
+
|
49
|
+
pageTitle: =>
|
50
|
+
if _.isFunction(@title)
|
51
|
+
@title.apply(@)
|
52
|
+
else
|
53
|
+
@title
|
54
|
+
|
55
|
+
_configureAppEvents: =>
|
56
|
+
for action, handler of @appEvents
|
57
|
+
try
|
58
|
+
method = @[handler]
|
59
|
+
method = handler if _.isFunction(handler)
|
60
|
+
boundMethod = _.bind(method, @)
|
61
|
+
|
62
|
+
@app.on action, boundMethod
|
63
|
+
catch
|
64
|
+
name = "'#{@constructor?.name || ''}'"
|
65
|
+
message = "View #{name} has no method named '#{handler}'. It cannot be registered as a handler for application events."
|
66
|
+
throw new Error(message)
|
67
|
+
|
68
|
+
@
|
69
|
+
|
70
|
+
delegateEvents: (events) =>
|
71
|
+
super
|
72
|
+
@_configureAppEvents()
|
73
|
+
@
|
74
|
+
|
75
|
+
undelegateEvents: =>
|
76
|
+
super
|
77
|
+
for action, handler of @appEvents
|
78
|
+
@app.off action, _.bind @[handler], @
|
79
|
+
@
|
80
|
+
|
81
|
+
renderTemplate: (template = @template) =>
|
82
|
+
@app.log "Rendering Template", template
|
83
|
+
@$el.html JST[template]()
|
84
|
+
|
85
|
+
renderTitle: =>
|
86
|
+
@$(".title").text @pageTitle()
|
87
|
+
@app.title @pageTitle()
|
88
|
+
|
89
|
+
pageClass: =>
|
90
|
+
""
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#= require ../namespace
|
2
|
+
|
3
|
+
FannyPack.namespace 'FannyPack.View', (View) ->
|
4
|
+
class View.List extends View.Base
|
5
|
+
initialize: (options={}) ->
|
6
|
+
@collection = options.collection
|
7
|
+
@subView = options.subView
|
8
|
+
|
9
|
+
@subViews = []
|
10
|
+
|
11
|
+
# always blow away existing subViews.
|
12
|
+
# call this only if you want a full re-render
|
13
|
+
render: =>
|
14
|
+
@remove()
|
15
|
+
|
16
|
+
@collection.each (item) =>
|
17
|
+
v = new @subView
|
18
|
+
model: item
|
19
|
+
|
20
|
+
@subViews.push v
|
21
|
+
|
22
|
+
@$el.append v.render().$el
|
23
|
+
|
24
|
+
@
|
25
|
+
|
26
|
+
remove: =>
|
27
|
+
_.invoke @subViews, 'remove'
|
28
|
+
|
29
|
+
super
|
data/lib/fanny_pack.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module FannyPack
|
2
|
+
# Deal with bundling Sprocket assets into environments (like Rails or Sprockets)
|
3
|
+
module Assets
|
4
|
+
def self.path(*segs)
|
5
|
+
File.join File.expand_path('../../assets', __FILE__), segs
|
6
|
+
end
|
7
|
+
|
8
|
+
# Integrate FannyPack ./lib/assets files into a sprocket-enabled environment.
|
9
|
+
module Sprockets
|
10
|
+
# Drop flash and javascript paths to FannyPack assets into a sprockets environment.
|
11
|
+
def self.configure(env)
|
12
|
+
env.append_path FannyPack::Assets.path('javascripts')
|
13
|
+
env
|
14
|
+
end
|
15
|
+
|
16
|
+
# Try to automatically configure Sprockets if its detected in the project.
|
17
|
+
def self.auto_detect
|
18
|
+
if defined? ::Sprockets and ::Sprockets.respond_to? :append_path
|
19
|
+
FannyPack::Assets::Sprockets.configure ::Sprockets
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,4 @@
|
|
1
|
+
module FannyPack
|
2
|
+
# Read the FannyPack.version attribute from lib/assets/javascripts/fanny_pack/version.js.coffee
|
3
|
+
VERSION = File.read(File.expand_path('../../assets/javascripts/fanny_pack/version.js.coffee', __FILE__)).match(/Package.version \= '(.+)'/m).captures.first
|
4
|
+
end
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
!!! 5
|
2
|
+
/[if lt IE 7] <html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7" lang="en-us">
|
3
|
+
/[if IE 7] <html class="no-js lt-ie10 lt-ie9 lt-ie8" lang="en-us">
|
4
|
+
/[if IE 8] <html class="no-js lt-ie10 lt-ie9" lang="en-us">
|
5
|
+
/[if IE 9] <html class="no-js lt-ie10 lt-ie9" lang="en-us">
|
6
|
+
/[if lt IE 10] <html class="no-js lt-ie10" lang="en-us">
|
7
|
+
/[if !IE]>
|
8
|
+
%html{lang: 'en', class: 'no-js'}
|
9
|
+
/<![endif]
|
10
|
+
%head
|
11
|
+
%title #{data.page.title || "The Middleman"}
|
12
|
+
%meta(http-equiv="content-type" content="text/html" charset="utf-8")
|
13
|
+
%meta(http-equiv="x-ua-compatible" content="ie=edge,chrome=1")
|
14
|
+
%meta(name="description" content="")
|
15
|
+
%meta(name="author" content="")
|
16
|
+
|
17
|
+
-# Standard viewport tag to set the viewport to the device's width,
|
18
|
+
-# Android 2.3 devices need this so 100% width works properly and
|
19
|
+
-# doesn't allow children to blow up the viewport width
|
20
|
+
%meta{content: "initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width", name: "viewport"}
|
21
|
+
|
22
|
+
-# Fix for iPhone 5 fullscreen web apps
|
23
|
+
%meta(name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1" media="(device-height: 568px)")
|
24
|
+
%meta(name='apple-mobile-web-app-capable' content='yes')
|
25
|
+
%meta(name='apple-mobile-web-app-status-bar-style' content='translucent-black')
|
26
|
+
|
27
|
+
-# App Icons
|
28
|
+
%link(rel="shortcut icon" href="/images/favicon.ico")
|
29
|
+
%link(rel="apple-touch-icon-precomposed" href="/images/apple-touch-icon-precomposed.png")
|
30
|
+
%link(rel="apple-touch-icon-precomposed" sizes="57x57" href="/images/apple-touch-icon-57x57-precomposed.png")
|
31
|
+
%link(rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/apple-touch-icon-72x72-precomposed.png")
|
32
|
+
%link(rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/apple-touch-icon-114x114-precomposed.png")
|
33
|
+
|
34
|
+
-# Stylesheets
|
35
|
+
= stylesheet_link_tag 'application'
|
36
|
+
%body{class: current_page.data.body_class || 'page'}
|
37
|
+
= yield
|
38
|
+
-# Javascripts
|
39
|
+
= javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js'
|
40
|
+
= javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js'
|
41
|
+
= javascript_include_tag 'application'
|
42
|
+
|
43
|
+
- if build?
|
44
|
+
-# Google Analytics
|
45
|
+
:javascript
|
46
|
+
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
|
47
|
+
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
48
|
+
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
|
49
|
+
s.parentNode.insertBefore(g,s)}(document,'script'));
|