space_frame_spine 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +34 -0
  5. data/Rakefile +2 -0
  6. data/lib/generators/base_generator.rb +7 -0
  7. data/lib/generators/model/USAGE +0 -0
  8. data/lib/generators/model/model_generator.rb +30 -0
  9. data/lib/generators/model/templates/.gitkeep +0 -0
  10. data/lib/generators/model/templates/app/models/%model_name%.coffee.tt +14 -0
  11. data/lib/generators/named_base_generator.rb +7 -0
  12. data/lib/generators/new/USAGE +13 -0
  13. data/lib/generators/new/new_generator.rb +25 -0
  14. data/lib/generators/new/templates/.gitkeep +0 -0
  15. data/lib/generators/new/templates/app/app.coffee.tt +2 -0
  16. data/lib/generators/new/templates/app/controllers/.gitkeep +0 -0
  17. data/lib/generators/new/templates/app/index.coffee.tt +33 -0
  18. data/lib/generators/new/templates/app/lib/.gitkeep +0 -0
  19. data/lib/generators/new/templates/app/main.coffee.tt +15 -0
  20. data/lib/generators/new/templates/app/models/.gitkeep +0 -0
  21. data/lib/generators/new/templates/app/nav.coffee.tt +16 -0
  22. data/lib/generators/new/templates/app/views/.gitkeep +0 -0
  23. data/lib/generators/new/templates/app/views/layouts/nav.jst.eco.tt +9 -0
  24. data/lib/generators/section/USAGE +0 -0
  25. data/lib/generators/section/section_generator.rb +54 -0
  26. data/lib/generators/section/templates/.gitkeep +0 -0
  27. data/lib/generators/section/templates/app/controllers/%controller_name%.coffee.tt +18 -0
  28. data/lib/generators/section/templates/app/controllers/%controller_name%/index.coffee.tt +30 -0
  29. data/lib/generators/section/templates/app/controllers/%controller_name%/index/detail.coffee.tt +8 -0
  30. data/lib/generators/section/templates/app/controllers/%controller_name%/index/item.coffee.tt +23 -0
  31. data/lib/generators/section/templates/app/controllers/%controller_name%/index/list.coffee.tt +27 -0
  32. data/lib/generators/section/templates/app/views/%view_name%/index/detail.jst.eco.tt +0 -0
  33. data/lib/generators/section/templates/app/views/%view_name%/index/item.jst.eco.tt +0 -0
  34. data/lib/generators/section/templates/app/views/layouts/section.jst.eco.tt +2 -0
  35. data/lib/generators/section/templates/app/views/nav/nav_item.jst.eco +3 -0
  36. data/lib/space_frame_spine.rb +8 -0
  37. data/lib/space_frame_spine/railtie.rb +15 -0
  38. data/lib/space_frame_spine/version.rb +5 -0
  39. data/space_frame_spine.gemspec +18 -0
  40. metadata +89 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spaceframe_spine.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # SpaceFrame - Spine
2
+
3
+ SpaceFrame for Spine is a set of Rails generators to implement ChaiOne's best practices for a client-side application. This version supports [Spine.js](http://www.spinejs.com), a popular client-side framework.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'space_frame_spine'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install spaceframe_spine
18
+
19
+ ## Requirements
20
+
21
+ Although they aren't required, it's a pretty good idea to add the `spine-rails` and `eco` gems to your Gemfile.
22
+
23
+ You could also provide your own [Spine.js](http://www.spinejs.com) libraries, and any Javascript templating engine that supports JST.
24
+
25
+ ## Usage
26
+ rails g spaceframe:new
27
+ rails g spaceframe:model NAME [attributes]
28
+ rails g spaceframe:section NAME
29
+
30
+ ## What's a SpaceFrame?
31
+
32
+ Independently in 1900 and 1950, Alexander Graham Bell and Buckminster Fuller developed the [Space Frame](http://en.wikipedia.org/wiki/Space_frame), one of the strongest construction frameworks ever devised. It employs either a triagonal or octahedronal cross-truss shape to distribute loads.
33
+
34
+ Space frames are used in architecture and performance vehicles, and are lightweight, inexpensive and easy to implement.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ module SpaceFrame
2
+ module Generators
3
+ class Base < Rails::Generators::Base
4
+ source_root File.expand_path('templates', File.expand_path(__FILE__))
5
+ end
6
+ end
7
+ end
File without changes
@@ -0,0 +1,30 @@
1
+ module SpaceFrame
2
+ module Generators
3
+ class ModelGenerator < SpaceFrame::Generators::NamedBase
4
+ source_root File.expand_path('templates', File.dirname(__FILE__))
5
+
6
+ desc "Generate a Spine model with configured fields"
7
+
8
+ argument :fields, :desc => 'List of model attributes', :type => :array, :banner => 'field1 field2'
9
+
10
+ attr_reader :model_name
11
+
12
+ def initialize(*args)
13
+ super(*args)
14
+
15
+ if @name == @name.pluralize && !options[:force_plural]
16
+ logger.warning "You selected a plural resource name. It's best to use the singular version. Override with --force-plural"
17
+ @name = @name.singularize
18
+ end
19
+
20
+ @model_name = singular_table_name
21
+ end
22
+
23
+ def generate_model
24
+ directory "app", "app/assets/javascripts/app"
25
+ #process other templates
26
+ end
27
+
28
+ end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,14 @@
1
+ window.<%= @model_name.camelize %> = class <%= @model_name.camelize %> extends Spine.Model
2
+ @configure "<%= @model_name.camelize %>", <%= fields.map {|f| %Q{"#{f}"} }.join(', ') %>
3
+ @extend Spine.Model.Ajax
4
+ select: =>
5
+ item.deselect() for item in @constructor.all() when item.selected
6
+ @selected = true
7
+ @trigger("select", @)
8
+
9
+ deselect: =>
10
+ @selected = false
11
+ @trigger("deselect", @)
12
+
13
+ @selected: ->
14
+ @select (item) -> item.selected is true
@@ -0,0 +1,7 @@
1
+ module SpaceFrame
2
+ module Generators
3
+ class NamedBase < Rails::Generators::NamedBase
4
+ source_root File.expand_path('templates', File.expand_path(__FILE__))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ Description:
2
+ Generates the basic application structure for a spine app and places it in app/assets/javascripts/app.
3
+
4
+ Example:
5
+ rails generate spaceframe_new
6
+
7
+ This will create:
8
+ app/assets/javascripts/app/
9
+ app/assets/javascripts/app/app.coffee
10
+ app/assets/javascripts/app/main.coffee
11
+ app/assets/javascripts/app/models/
12
+ app/assets/javascripts/app/controllers/
13
+ app/assets/javascripts/app/views/
@@ -0,0 +1,25 @@
1
+ module SpaceFrame
2
+ module Generators
3
+ class NewGenerator < SpaceFrame::Generators::Base
4
+ source_root File.expand_path('templates', File.dirname(__FILE__))
5
+ def create_empty_shell
6
+ directory "app", "app/assets/javascripts/app"
7
+ end
8
+
9
+ def remove_require_tree
10
+ gsub_file "app/assets/javascripts/application.js", /require_tree\s\./, "require app/index"
11
+ end
12
+
13
+ def add_dom_structure
14
+ gsub_file "app/views/layouts/application.html.erb", /<body>\s+<%= yield %>\s+<\/body>/, <<-DOM
15
+ <body>
16
+ <div id='nav'></div>
17
+ <div id='main'>
18
+ <%= yield %>
19
+ </div>
20
+ </body>
21
+ DOM
22
+ end
23
+ end
24
+ end
25
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ # Application class namespace
2
+ window.App = {}
@@ -0,0 +1,33 @@
1
+ #= require_tree ./lib
2
+ #
3
+ #= require spine
4
+ #= require spine/manager
5
+ #= require spine/route
6
+ #= require spine/ajax
7
+ #
8
+ #= require ./app
9
+ #
10
+ #= require_tree ./models
11
+ #= require_tree ./controllers
12
+ #= require_tree ./views
13
+ #
14
+ #= require ./nav
15
+ #= require ./main
16
+
17
+ app = {}
18
+
19
+ $ ->
20
+ app.main = new App.Main(el: $("#main"))
21
+ app.nav = new App.Nav(el: $("#nav"), sections: app.main.sections)
22
+
23
+ app.main.render()
24
+ app.nav.render()
25
+
26
+ Spine.Route.setup
27
+ history: true
28
+
29
+ $('body').on "click", "a.navigable", (e) ->
30
+ app.main.navigate(e.currentTarget.pathname)
31
+ e.preventDefault()
32
+
33
+ window.app = app
File without changes
@@ -0,0 +1,15 @@
1
+ App.Main = class Main extends Spine.Controller
2
+
3
+ constructor: ->
4
+ super
5
+
6
+ @sections = []
7
+
8
+ @manager = new Spine.Manager(@sections...)
9
+
10
+ @routes
11
+
12
+
13
+ render: ->
14
+ @append section.render().el for section in @sections
15
+ @
File without changes
@@ -0,0 +1,16 @@
1
+ App.Nav = class Nav extends Spine.Controller
2
+ tag: "nav"
3
+
4
+ constructor: ->
5
+ super
6
+
7
+ render: ->
8
+ @html JST['app/views/layouts/nav']()
9
+ @addAll()
10
+ @
11
+
12
+ addAll: ->
13
+ @addOne(item) for item in @sections when item.navTitle
14
+
15
+ addOne: (item) ->
16
+ @$("ul.nav").append JST['app/views/nav/nav_item'](item)
File without changes
@@ -0,0 +1,9 @@
1
+ <div class="navbar">
2
+ <div class="navbar-inner">
3
+ <div class="container">
4
+ <a class='brand' href='/'><%= @application_name %></a>
5
+ <ul class="nav">
6
+ </ul>
7
+ </div>
8
+ </div>
9
+ </div>
File without changes
@@ -0,0 +1,54 @@
1
+ module SpaceFrame
2
+ module Generators
3
+ class SectionGenerator < SpaceFrame::Generators::NamedBase
4
+ source_root File.expand_path('templates', File.dirname(__FILE__))
5
+
6
+ attr_reader :controller_name,
7
+ :view_name,
8
+ :model_name
9
+
10
+ def initialize(*args)
11
+ super(*args)
12
+ @logger = Logger.new STDOUT
13
+
14
+ if @name == @name.pluralize && !options[:force_plural]
15
+ @logger.info "You selected a plural resource name. It's best to use the singular version. Override with --force-plural"
16
+ @name = @name.singularize
17
+ end
18
+
19
+ @controller_name = plural_table_name
20
+ @view_name = plural_table_name
21
+ @model_name = singular_table_name
22
+ end
23
+
24
+ def generate_section
25
+ directory "app", "app/assets/javascripts/app"
26
+
27
+ insert_into_file "app/assets/javascripts/app/main.coffee",
28
+ " @#{@controller_name} = new App.#{@controller_name.camelize}.Section()",
29
+ :after =>"super\n"
30
+
31
+ gsub_file "app/assets/javascripts/app/main.coffee", /\@sections = \[(.*)\]/ do |match|
32
+ puts match.to_s
33
+ match = /\@sections = \[(.*)\]/.match(match.to_s)
34
+ puts "match: #{match[1]}"
35
+
36
+ if match == "sections = []"
37
+ "@sections = [@#{@controller_name}]"
38
+ else
39
+ sections = match[1].split(",")
40
+ sections << "@#{@controller_name}" unless sections.include?("@#{@controller_name}")
41
+ "@sections = [#{sections.join(',')}]"
42
+ end
43
+ end
44
+
45
+ #process other templates
46
+ end
47
+
48
+ def add_root_route
49
+ route(%Q{root :to => "#{@controller_name}#index"})
50
+ end
51
+
52
+ end
53
+ end
54
+ end
File without changes
@@ -0,0 +1,18 @@
1
+ App.<%= @controller_name.camelize %> = {}
2
+
3
+ App.<%= @controller_name.camelize %>.Section = class <%= @controller_name.camelize %> extends Spine.Stack
4
+ tag: "section"
5
+ navTitle: "<%= @controller_name.camelize %>"
6
+
7
+ constructor: ->
8
+ @controllers =
9
+ index: App.<%= @controller_name.camelize %>.Index.Main
10
+ super
11
+
12
+ routes:
13
+ "/<%= @controller_name %>/:id": "index"
14
+ "/<%= @controller_name %>" : "index"
15
+
16
+ render: ->
17
+ @index.render()
18
+ @
@@ -0,0 +1,30 @@
1
+ App.<%= @controller_name.camelize %>.Index = {}
2
+
3
+ App.<%= @controller_name.camelize %>.Index.Main = class Main extends Spine.Controller
4
+
5
+ className: "index"
6
+
7
+ elements:
8
+ ".list" : "listEl"
9
+ ".detail" : "detailEl"
10
+
11
+ constructor: ->
12
+ @listClass = App.<%= @controller_name.camelize %>.Index.List
13
+ @detailClass = App.<%= @controller_name.camelize %>.Index.Detail
14
+ super
15
+
16
+ render: ->
17
+ @html JST['app/views/layouts/section']()
18
+ @list = new @listClass(el: @listEl).render()
19
+ @
20
+
21
+ activate: (params) =>
22
+ super
23
+ @show params if params.id
24
+
25
+ show: (params) ->
26
+ if item = <%= @model_name.camelize %>.exists(params.id)
27
+ @detail = new @detailClass(el: @detailEl, item: item).render(item)
28
+ else
29
+ <%= @model_name.camelize %>.one "refresh", =>
30
+ @show(params)
@@ -0,0 +1,8 @@
1
+ App.<%= @controller_name.camelize %>.Index.Detail = class Detail extends Spine.Controller
2
+
3
+ constructor: ->
4
+ super
5
+
6
+ render: ->
7
+ @html JST["app/views/<%= @view_name %>/index/detail"](@item)
8
+ @
@@ -0,0 +1,23 @@
1
+ App.<%= @controller_name.camelize %>.Index.Item = class Item extends Spine.Controller
2
+
3
+ className: "<%= @model_name %> item list-item"
4
+
5
+ events:
6
+ "click" : "clicked"
7
+
8
+ constructor: ->
9
+ super
10
+
11
+ render: ->
12
+ @html JST["app/views/<%= @view_name %>/index/item"](@item)
13
+ @
14
+
15
+ select: ->
16
+ @el.addClass("selected")
17
+
18
+ deselect: ->
19
+ @el.removeClass("selected")
20
+
21
+ clicked: =>
22
+ @item.select()
23
+ @navigate "/<%= @controller_name %>/#{@item.id}"
@@ -0,0 +1,27 @@
1
+ App.<%= @controller_name.camelize %>.Index.List = class List extends Spine.Controller
2
+
3
+ constructor: ->
4
+ <%= @model_name.camelize %>.bind "refresh", @addAll
5
+ <%= @model_name.camelize %>.bind "select", @select
6
+ <%= @model_name.camelize %>.bind "deselect", @deselect
7
+ super
8
+ @itemClass = App.<%= @controller_name.camelize %>.Index.Item
9
+ @children = {}
10
+
11
+ render: ->
12
+ <%= @model_name.camelize %>.fetch()
13
+ @
14
+
15
+ addAll: (items) =>
16
+ @addOne(item) for item in items
17
+
18
+ addOne: (item) ->
19
+ controller = new @itemClass(item: item)
20
+ @children[item.id] = controller
21
+ @append controller.render().el
22
+
23
+ select: (item) =>
24
+ @children[item.id].select()
25
+
26
+ deselect: (item) =>
27
+ @children[item.id].deselect()
@@ -0,0 +1,2 @@
1
+ <div class='list'></div>
2
+ <div class='detail'></div>
@@ -0,0 +1,3 @@
1
+ <li class='nav-item'>
2
+ <a href='/'><%= @navTitle %></a>
3
+ </li>
@@ -0,0 +1,8 @@
1
+ require "space_frame_spine/version"
2
+
3
+ require 'space_frame_spine/railtie' if defined? Rails
4
+
5
+ module SpaceFrame
6
+ module Spine
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module SpaceFrame
2
+ module Spine
3
+ class Railtie < Rails::Railtie
4
+
5
+ generators do
6
+ require 'generators/base_generator'
7
+ require 'generators/named_base_generator'
8
+ require 'generators/new/new_generator'
9
+ require 'generators/section/section_generator'
10
+ require 'generators/model/model_generator'
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module SpaceFrame
2
+ module Spine
3
+ VERSION = "0.0.5"
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/space_frame_spine/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Scott Burton", "Ryan Marsh"]
6
+ gem.email = ["scott@chaione.com", "ryan.marsh@chaione.com"]
7
+ gem.description = %q{SpaceFrame for Spine is a set of Rails generators to implement ChaiOne's best practices for a client-side application.}
8
+ gem.summary = %q{SpaceFrame for Spine is a set of Rails generators to implement ChaiOne's best practices for a client-side application.}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "space_frame_spine"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SpaceFrame::Spine::VERSION
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: space_frame_spine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Scott Burton
9
+ - Ryan Marsh
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-04-28 00:00:00.000000000Z
14
+ dependencies: []
15
+ description: SpaceFrame for Spine is a set of Rails generators to implement ChaiOne's
16
+ best practices for a client-side application.
17
+ email:
18
+ - scott@chaione.com
19
+ - ryan.marsh@chaione.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - LICENSE
27
+ - README.md
28
+ - Rakefile
29
+ - lib/generators/base_generator.rb
30
+ - lib/generators/model/USAGE
31
+ - lib/generators/model/model_generator.rb
32
+ - lib/generators/model/templates/.gitkeep
33
+ - lib/generators/model/templates/app/models/%model_name%.coffee.tt
34
+ - lib/generators/named_base_generator.rb
35
+ - lib/generators/new/USAGE
36
+ - lib/generators/new/new_generator.rb
37
+ - lib/generators/new/templates/.gitkeep
38
+ - lib/generators/new/templates/app/app.coffee.tt
39
+ - lib/generators/new/templates/app/controllers/.gitkeep
40
+ - lib/generators/new/templates/app/index.coffee.tt
41
+ - lib/generators/new/templates/app/lib/.gitkeep
42
+ - lib/generators/new/templates/app/main.coffee.tt
43
+ - lib/generators/new/templates/app/models/.gitkeep
44
+ - lib/generators/new/templates/app/nav.coffee.tt
45
+ - lib/generators/new/templates/app/views/.gitkeep
46
+ - lib/generators/new/templates/app/views/layouts/nav.jst.eco.tt
47
+ - lib/generators/section/USAGE
48
+ - lib/generators/section/section_generator.rb
49
+ - lib/generators/section/templates/.gitkeep
50
+ - lib/generators/section/templates/app/controllers/%controller_name%.coffee.tt
51
+ - lib/generators/section/templates/app/controllers/%controller_name%/index.coffee.tt
52
+ - lib/generators/section/templates/app/controllers/%controller_name%/index/detail.coffee.tt
53
+ - lib/generators/section/templates/app/controllers/%controller_name%/index/item.coffee.tt
54
+ - lib/generators/section/templates/app/controllers/%controller_name%/index/list.coffee.tt
55
+ - lib/generators/section/templates/app/views/%view_name%/index/detail.jst.eco.tt
56
+ - lib/generators/section/templates/app/views/%view_name%/index/item.jst.eco.tt
57
+ - lib/generators/section/templates/app/views/layouts/section.jst.eco.tt
58
+ - lib/generators/section/templates/app/views/nav/nav_item.jst.eco
59
+ - lib/space_frame_spine.rb
60
+ - lib/space_frame_spine/railtie.rb
61
+ - lib/space_frame_spine/version.rb
62
+ - space_frame_spine.gemspec
63
+ homepage: ''
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.15
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: SpaceFrame for Spine is a set of Rails generators to implement ChaiOne's
87
+ best practices for a client-side application.
88
+ test_files: []
89
+ has_rdoc: