sinatra-backbone 0.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /doc
data/HISTORY.md ADDED
@@ -0,0 +1,4 @@
1
+ v0.1.0.rc1 - Sept 12, 2011
2
+ --------------------------
3
+
4
+ Initial version.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Sinatra-backbone
2
+ #### Neat integration of Backbone.js with Sinatra
3
+
4
+ Do you like [Backbone.js][bb]? Do you like [Sinatra][sn]? Did you ever wish you
5
+ can use them together? Well now you can, with the new Sinatra Backbone!
6
+
7
+ [bb]: http://documentcloud.github.com/backbone/
8
+ [sn]: http://sinatrarb.com
9
+
10
+ #### Usage
11
+
12
+ This is a Ruby gem.
13
+ `$ gem install sinatra-backbone --pre`
14
+
15
+ Or do you use Bundler?
16
+ `gem 'sinatra-backbone', :require => 'sinatra/backbone'`
17
+
18
+ Contents
19
+ --------
20
+
21
+ __Sinatra-backbone__ is comprised of two Sinatra plugins:
22
+
23
+ * `Sinatra::JstPages` – Provides support for JavaScript server templates (JST)
24
+ for use in Backbone views.
25
+
26
+ * `Sinatra::RestAPI` – Provides restful API for your models for use in Backbone
27
+ models.
28
+
29
+ For usage and API reference, please see http://ricostacruz.com/sinatra-backbone. [](#api_reference)
30
+
31
+ Acknowledgements
32
+ ----------------
33
+
34
+ © 2011, Rico Sta. Cruz. Released under the [MIT
35
+ License](http://www.opensource.org/licenses/mit-license.php).
36
+
37
+ Sinatra-Backbone is authored and maintained by [Rico Sta. Cruz][rsc] with help
38
+ from it's [contributors][c]. It is sponsored by my startup, [Sinefunc, Inc][sf].
39
+
40
+ * [My website](http://ricostacruz.com) (ricostacruz.com)
41
+ * [Sinefunc, Inc.](http://sinefunc.com) (sinefunc.com)
42
+ * [Github](http://github.com/rstacruz) (@rstacruz)
43
+ * [Twitter](http://twitter.com/rstacruz) (@rstacruz)
44
+
45
+ [rsc]: http://ricostacruz.com
46
+ [c]: http://github.com/rstacruz/xxxxx
47
+ [sf]: http://sinefunc.com
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ desc "Invokes the test suite in multiple RVM environments"
2
+ task :'test!' do
3
+ # Override this by adding RVM_TEST_ENVS=".." in .rvmrc
4
+ envs = ENV['RVM_TEST_ENVS'] || '1.9.2@sinatra,1.8.7@sinatra'
5
+ puts "* Testing in the following RVM environments: #{envs.gsub(',', ', ')}"
6
+ system "rvm #{envs} rake test" or abort
7
+ end
8
+
9
+ desc "Runs tests"
10
+ task :test do
11
+ Dir['test/*_test.rb'].each { |f| load f }
12
+ end
13
+
14
+ task :default => :test
15
+
16
+ repo = ENV['GITHUB_REPO'] || 'rstacruz/sinatra-backbone'
17
+ namespace :doc do
18
+ desc "Builds documentation"
19
+ task :build do
20
+ # github.com/rstacruz/reacco
21
+ system "reacco -a --api lib --github #{repo}"
22
+ end
23
+
24
+ desc "Uploads documentation"
25
+ task :deploy => :build do
26
+ # github.com/rstacruz/git-update-ghpages
27
+ system "git update-ghpages -i doc #{repo}"
28
+ end
29
+ end
30
+
31
+ task :doc => :'doc:build'
@@ -0,0 +1,11 @@
1
+ module Sinatra
2
+ module Backbone
3
+ def self.version
4
+ "0.1.0.rc1"
5
+ end
6
+
7
+ end
8
+
9
+ autoload :RestAPI, "sinatra/restapi"
10
+ autoload :JstPages, "sinatra/jstpages"
11
+ end
@@ -0,0 +1,196 @@
1
+ # ## Sinatra::JstPages [module]
2
+ # A Sinatra plugin that adds support for JST (JavaScript Server Templates).
3
+ #
4
+ # #### Basic usage
5
+ # Register the `Sinatra::JstPages` plugin in your application, and use
6
+ # `serve_jst`. This example serves all JST files found in `/views/**/*.jst.*`
7
+ # (where `/views` is your views directory as defined in Sinatra's
8
+ # `settings.views`) as `http://localhost:4567/jst.js`.
9
+ #
10
+ # require 'sinatra/jstpages'
11
+ #
12
+ # class App < Sinatra::Base
13
+ # register Sinatra::JstPages
14
+ # serve_jst '/jst.js'
15
+ # end
16
+ #
17
+ # You will need to link to the JST route in your layout. Make a `<script>` tag
18
+ # where the `src='...'` attribute is the same path you provide to `serve_jst`.
19
+ #
20
+ # <script type='text/javascript' src='/jst.js'></script>
21
+ #
22
+ # So, if you have a JST view written in Jade, placed in `views/editor/edit.jst.jade`:
23
+ #
24
+ # # views/editor/edit.jst.jade
25
+ # h1= "Edit "+name
26
+ # form
27
+ # button Save
28
+ #
29
+ # Now in your browser you may invoke `JST['templatename']`:
30
+ #
31
+ # // Renders the editor/edit template
32
+ # JST['editor/edit']();
33
+ #
34
+ # // Renders the editor/edit template with template parameters
35
+ # JST['editor/edit']({name: 'Item Name'});
36
+ #
37
+ # #### Using Sinatra-AssetPack?
38
+ #
39
+ # __TIP:__ If you're using the [sinatra-assetpack][sap] gem, just add `/jst.js`
40
+ # to a package. (If you're not using Sinatra AssetPack yet, you probably
41
+ # should.)
42
+ #
43
+ # [sap]: http://ricostacruz.com/sinatra-assetpack
44
+ #
45
+ # #### Supported templates
46
+ # Currently supports the following templates:
47
+ #
48
+ # * [Jade][jade] (`.jst.jade`) -- Jade templates. This requires
49
+ # [jade.js][jade]. For older browsers, you will also need [json2.js][json2],
50
+ # and an implementation of [String.prototype.trim][trim].
51
+ #
52
+ # * [Underscore templates][under_tpl] (`.jst.tpl`) -- Simple templates by
53
+ # underscore. This requires [underscore.js][under], which Backbone also
54
+ # requires.
55
+ #
56
+ # * [Haml.js][haml] (`.jst.haml`) -- A JavaScript implementation of Haml.
57
+ # Requires [haml.js][haml].
58
+ #
59
+ # * [Eco][eco] (`.jst.eco`) -- Embedded CoffeeScript templates. Requires
60
+ # [eco.js][eco] and [coffee-script.js][cs].
61
+ #
62
+ # [jade]: http://github.com/visionmedia/jade
63
+ # [json2]: https://github.com/douglascrockford/JSON-js
64
+ # [trim]: http://snippets.dzone.com/posts/show/701
65
+ # [under_tpl]: http://documentcloud.github.com/underscore/#template
66
+ # [under]: http://documentcloud.github.com/underscore
67
+ # [haml]: https://github.com/creationix/haml-js
68
+ # [eco]: https://github.com/sstephenson/eco
69
+ # [cs]: http://coffeescript.org
70
+ #
71
+ module Sinatra
72
+ module JstPages
73
+ def self.registered(app)
74
+ app.extend ClassMethods
75
+ app.helpers Helpers
76
+ end
77
+
78
+ # Returns a hash to determine which engine is mapped onto a given extension.
79
+ def self.mappings
80
+ @mappings ||= Hash.new
81
+ end
82
+
83
+ def self.register(ext, engine)
84
+ mappings[ext] = engine
85
+ end
86
+
87
+ module Helpers
88
+ # Returns a list of JST files.
89
+ def jst_files
90
+ # Tuples of [ name, Engine instance ]
91
+ tuples = Dir.chdir(settings.views) {
92
+ Dir["**/*.jst.*"].map { |fn|
93
+ fn =~ %r{^(.*)\.jst\.([^\.]+)$}
94
+ name, ext = $1, $2
95
+ engine = JstPages.mappings[ext]
96
+
97
+ [ name, engine.new(File.join(settings.views, fn)) ] if engine
98
+ }.compact
99
+ }
100
+
101
+ Hash[*tuples.flatten]
102
+ end
103
+ end
104
+
105
+ module ClassMethods
106
+ # ### serve_jst(path, [options]) [class method]
107
+ # Serves JST files in given `path`.
108
+ #
109
+ def serve_jst(path, options={})
110
+ get path do
111
+ content_type :js
112
+ jsts = jst_files.map { |(name, engine)|
113
+ %{
114
+ JST[#{name.inspect}] = function() {
115
+ if (!c[#{name.inspect}]) c[#{name.inspect}] = (#{engine.function});
116
+ return c[#{name.inspect}].apply(this, arguments);
117
+ };
118
+ }.strip.gsub(/^ {12}/, '')
119
+ }
120
+
121
+ %{
122
+ (function(){
123
+ var c = {};
124
+ if (!window.JST) window.JST = {};
125
+ #{jsts.join("\n ")}
126
+ })();
127
+ }.strip.gsub(/^ {12}/, '')
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+
135
+ # ## Sinatra::JstPages::Engine [class]
136
+ # A template engine.
137
+ #
138
+ # #### Adding support for new template engines
139
+ # You will need to subclass `Engine`, override at least the `function` method,
140
+ # then use `JstPages.register`.
141
+ #
142
+ # This example will register `.jst.my` files to a new engine that uses
143
+ # `My.compile`.
144
+ #
145
+ # module Sinatra::JstPages
146
+ # class MyEngine < Engine
147
+ # def function() "My.compile(%s)"; end
148
+ # end
149
+ #
150
+ # register 'my', MyEngine
151
+ # end
152
+ #
153
+ module Sinatra::JstPages
154
+ class Engine
155
+ # ### file [attribute]
156
+ # The string path of the template file.
157
+ attr_reader :file
158
+ def initialize(file)
159
+ @file = file
160
+ end
161
+
162
+ # ### contents [method]
163
+ # Returns the contents of the template file as a string.
164
+ def contents
165
+ File.read(@file)
166
+ end
167
+
168
+ # ### function [method]
169
+ # The JavaScript function to invoke on the precompile'd object.
170
+ #
171
+ # What this returns should, in JavaScript, return a function that can be
172
+ # called with an object hash of the params to be passed onto the template.
173
+ def function
174
+ "_.template(#{contents.inspect})"
175
+ end
176
+ end
177
+
178
+ class HamlEngine < Engine
179
+ def function() "Haml.compile(#{contents.inspect})"; end
180
+ end
181
+
182
+ class JadeEngine < Engine
183
+ def function() "require('jade').compile(#{contents.inspect})"; end
184
+ end
185
+
186
+ class EcoEngine < Engine
187
+ def function
188
+ "function() { var a = arguments.slice(); a.unshift(#{contents.inspect}); return eco.compile.apply(eco, a); }"
189
+ end
190
+ end
191
+
192
+ register 'tpl', Engine
193
+ register 'jade', JadeEngine
194
+ register 'haml', HamlEngine
195
+ register 'eco', EcoEngine
196
+ end
@@ -0,0 +1,202 @@
1
+ require 'json'
2
+
3
+ # ## Sinatra::RestAPI [module]
4
+ # A plugin for providing rest API to models. Great for Backbone.js.
5
+ #
6
+ # To use this, simply `register` it to your Sinatra Application. You can then
7
+ # use `rest_create` and `rest_resource` to create your routes.
8
+ #
9
+ # require 'sinatra/restapi'
10
+ #
11
+ # class App < Sinatra::Base
12
+ # register Sinatra::RestAPI
13
+ # end
14
+ #
15
+ module Sinatra::RestAPI
16
+ def self.registered(app)
17
+ app.helpers Helpers
18
+ end
19
+
20
+ # ### rest_create(path, &block) [method]
21
+ # Creates a *create* route on the given `path`.
22
+ #
23
+ # This creates a `POST` route in */documents* that accepts JSON data.
24
+ # This route will return the created object as JSON.
25
+ #
26
+ # When getting a request, it does the following:
27
+ #
28
+ # * A new object is created by *yielding* the block you give. (Let's
29
+ # call it `object`.)
30
+ #
31
+ # * For each of the attributes, it uses the `attrib_name=` method in
32
+ # your record. For instance, for an attrib like `title`, it wil lbe
33
+ # calling `object.title = "hello"`.
34
+ #
35
+ # * `object.save` will be called.
36
+ #
37
+ # * `object`'s contents will then be returned to the client as JSON.
38
+ #
39
+ # See the example.
40
+ #
41
+ # class App < Sinatra::Base
42
+ # rest_create "/documents" do
43
+ # Document.new
44
+ # end
45
+ # end
46
+ #
47
+ def rest_create(path, options={}, &blk)
48
+ # Create
49
+ post path do
50
+ @object = yield
51
+ rest_params.each { |k, v| @object.send :"#{k}=", v }
52
+ @object.save
53
+ rest_respond @object.to_hash
54
+ end
55
+ end
56
+
57
+ # ### rest_resource(path, &block) [method]
58
+ # Creates a *get*, *edit* and *delete* route on the given `path`.
59
+ #
60
+ # The block given will be yielded to do a record lookup. If the block returns
61
+ # `nil`, RestAPI will return a *404*.
62
+ #
63
+ # In the example, it creates routes for `/document/:id` to accept HTTP *GET*
64
+ # (for object retrieval), *PUT* (for editing), and *DELETE* (for destroying).
65
+ #
66
+ # Your model needs to implement the following methods:
67
+ #
68
+ # * `save` (called on edit)
69
+ # * `destroy` (called on delete)
70
+ # * `<attrib_name_here>=` (called for each of the attributes on edit)
71
+ #
72
+ # If you only want to create routes for only one or two of the actions, you
73
+ # may individually use:
74
+ #
75
+ # * `rest_get`
76
+ # * `rest_edit`
77
+ # * `rest_delete`
78
+ #
79
+ # All the methods above take the same arguments as `rest_resource`.
80
+ #
81
+ # class App < Sinatra::Base
82
+ # rest_resource "/document/:id" do
83
+ # Document.find(id)
84
+ # end
85
+ # end
86
+ #
87
+ def rest_resource(path, options={}, &blk)
88
+ rest_get path, options, &blk
89
+ rest_edit path, options, &blk
90
+ rest_delete path, options, &blk
91
+ end
92
+
93
+ # ### rest_get(path, &block) [method]
94
+ # This is the same as `rest_resource`, but only handles *GET* requests.
95
+ #
96
+ def rest_get(path, options={}, &blk)
97
+ get path do |id|
98
+ @object = yield(id) or pass
99
+ rest_respond @object
100
+ end
101
+ end
102
+
103
+ # ### rest_edit(path, &block) [method]
104
+ # This is the same as `rest_resource`, but only handles *PUT*/*POST* (edit)
105
+ # requests.
106
+ #
107
+ def rest_edit(path, options={}, &blk)
108
+ callback = Proc.new { |id|
109
+ @object = yield(id) or pass
110
+ rest_params.each { |k, v| @object.send :"#{k}=", v unless k == 'id' }
111
+ @object.save
112
+ rest_respond @object
113
+ }
114
+
115
+ # Make it work with `Backbone.emulateHTTP` on.
116
+ put path, &callback
117
+ post path, &callback
118
+ end
119
+
120
+ # ### rest_delete(path, &block) [method]
121
+ # This is the same as `rest_resource`, but only handles *DELETE* (edit)
122
+ # requests. This uses `Model#destroy` on your model.
123
+ #
124
+ def rest_delete(path, options={}, &blk)
125
+ delete path do |id|
126
+ @object = yield(id) or pass
127
+ @object.destroy
128
+ rest_respond :result => :success
129
+ end
130
+ end
131
+
132
+ # ### JSON conversion
133
+ #
134
+ # The *create* and *get* routes all need to return objects as JSON. RestAPI
135
+ # attempts to convert your model instances to JSON by first trying
136
+ # `object.to_json` on it, then trying `object.to_hash.to_json`.
137
+ #
138
+ # It's recommended you implement `#to_hash` in your models.
139
+
140
+ # ### Helper methods
141
+ # There are some helper methods that are used internally be `RestAPI`,
142
+ # but you can use them too if you need them.
143
+ #
144
+ module Helpers
145
+ # #### rest_respond(object)
146
+ # Responds with a request with the given `object`.
147
+ #
148
+ # This will convert that object to either JSON or XML as needed, depending
149
+ # on the client's preferred type (dictated by the HTTP *Accepts* header).
150
+ #
151
+ def rest_respond(obj)
152
+ case request.preferred_type('*/json', '*/xml')
153
+ when '*/json'
154
+ content_type :json
155
+ rest_convert_to_json obj
156
+
157
+ else
158
+ pass
159
+ end
160
+ end
161
+
162
+ # #### rest_params
163
+ # Returns the object from the request.
164
+ #
165
+ # If the client sent `application/json` (or `text/json`) as the content
166
+ # type, it tries to parse the request body as JSON.
167
+ #
168
+ # If the client sent a standard URL-encoded POST with a `model` key
169
+ # (happens when Backbone uses `Backbone.emulateJSON = true`), it tries
170
+ # to parse it's key as JSON.
171
+ #
172
+ # Otherwise, the params will be returned as is.
173
+ #
174
+ def rest_params
175
+ if File.fnmatch('*/json', request.content_type)
176
+ JSON.parse request.body.read
177
+
178
+ elsif params['model']
179
+ # Account for Backbone.emulateJSON.
180
+ JSON.parse params['model']
181
+
182
+ else
183
+ params
184
+ end
185
+ end
186
+
187
+ def rest_convert_to_json(obj)
188
+ # Convert to JSON. This will almost always work as the JSON lib adds
189
+ # #to_json to everything.
190
+ json = obj.to_json
191
+
192
+ # The default to_json of objects is to JSONify the #to_s of an object,
193
+ # which defaults to #inspect. We don't want that.
194
+ return json unless json[0..2] == '"#<'
195
+
196
+ # Let's hope they redefined to_hash.
197
+ return obj.to_hash.to_json if obj.respond_to?(:to_hash)
198
+
199
+ raise "Can't convert object to JSON"
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,18 @@
1
+ require './lib/sinatra/backbone'
2
+ Gem::Specification.new do |s|
3
+ s.name = "sinatra-backbone"
4
+ s.version = Sinatra::Backbone.version
5
+ s.summary = "Helpful stuff using Sinatra with Backbone."
6
+ s.description = "Provides Rest API access to your models and serves JST pages."
7
+ s.authors = ["Rico Sta. Cruz"]
8
+ s.email = ["rico@sinefunc.com"]
9
+ s.homepage = "http://github.com/rstacruz/sinatra-backbone"
10
+ s.files = `git ls-files`.strip.split("\n")
11
+ s.executables = Dir["bin/*"].map { |f| File.basename(f) }
12
+
13
+ s.add_dependency "sinatra"
14
+ s.add_development_dependency "sequel", ">= 3.25.0"
15
+ s.add_development_dependency "sqlite3", ">= 1.3.4"
16
+ s.add_development_dependency "contest"
17
+ s.add_development_dependency "rack-test"
18
+ end
@@ -0,0 +1 @@
1
+ <%= chrome %>
@@ -0,0 +1,2 @@
1
+ h1
2
+ | Hello
data/test/app_test.rb ADDED
@@ -0,0 +1,50 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ DB.create_table :books do
4
+ primary_key :id
5
+ String :name
6
+ String :author
7
+ end
8
+
9
+ class Book < Sequel::Model
10
+ def to_hash
11
+ { :name => name, :author => author }
12
+ end
13
+ end
14
+
15
+ class AppTest < UnitTest
16
+ class App < Sinatra::Base
17
+ register Sinatra::RestAPI
18
+ disable :show_exceptions
19
+ enable :raise_errors
20
+ rest_resource("/book/:id") { |id| Book[id] }
21
+ end
22
+ def app() App; end
23
+
24
+ describe "Sinatra::RestAPI" do
25
+ setup do
26
+ @book = Book.new
27
+ @book.name = "Darkly Dreaming Dexter"
28
+ @book.author = "Jeff Lindsay"
29
+ @book.save
30
+ header 'Accept', 'application/json, */*'
31
+ end
32
+
33
+ teardown do
34
+ @book.destroy if Book[@book.id]
35
+ end
36
+
37
+ test "should work properly" do
38
+ get "/book/#{@book.id}"
39
+
40
+ assert json_response['name'] == @book.name
41
+ assert json_response['author'] == @book.author
42
+ end
43
+
44
+ test "should 404" do
45
+ get "/book/823978"
46
+
47
+ assert last_response.status == 404
48
+ end
49
+ end
50
+ end
data/test/jst_test.rb ADDED
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class JstTest < UnitTest
4
+ class App < Sinatra::Base
5
+ register Sinatra::JstPages
6
+ disable :show_exceptions
7
+ enable :raise_errors
8
+
9
+ set :views, File.expand_path('../app/views', __FILE__)
10
+ serve_jst '/jst.js'
11
+ end
12
+ def app() App; end
13
+
14
+ test "jst" do
15
+ get '/jst.js'
16
+ body = last_response.body
17
+
18
+ assert body.include? 'window.JST'
19
+
20
+ assert body.include? '["editor/edit"]'
21
+ assert body.include? "Hello"
22
+
23
+ assert body.include? '["chrome"]'
24
+ assert body.include? "chrome"
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'contest'
3
+ require 'sinatra/base'
4
+ require 'sequel'
5
+ require 'rack/test'
6
+ require 'json'
7
+ require 'sinatra/backbone'
8
+
9
+ class UnitTest < Test::Unit::TestCase
10
+ include Rack::Test::Methods
11
+
12
+ def json_response
13
+ JSON.parse last_response.body
14
+ end
15
+ end
16
+
17
+ DB = Sequel.connect('sqlite::memory:')
@@ -0,0 +1,44 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ DB.create_table :albums do
4
+ primary_key :id
5
+ String :title
6
+ String :artist
7
+ end
8
+
9
+ class Album < Sequel::Model
10
+ def to_json
11
+ "X"
12
+ end
13
+
14
+ def to_hash
15
+ { :name => name, :author => author }
16
+ end
17
+
18
+ def to_xml
19
+ "lol"
20
+ end
21
+ end
22
+
23
+ class ToJsonTest < UnitTest
24
+ class App < Sinatra::Base
25
+ register Sinatra::RestAPI
26
+ disable :show_exceptions
27
+ enable :raise_errors
28
+ rest_resource("/album/:id") { |id| Album[id] }
29
+ end
30
+ def app() App; end
31
+
32
+ setup do
33
+ @album = Album.new
34
+ @album.title = "Tanto Tempo"
35
+ @album.artist = "Bebel Gilberto"
36
+ @album.save
37
+ header 'Accept', 'application/json, */*'
38
+ end
39
+
40
+ test "use to_json" do
41
+ get "/album/#{@album.id}"
42
+ assert last_response.body == @album.to_json
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-backbone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.rc1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Rico Sta. Cruz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-12 00:00:00.000000000 +08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ requirement: &2161564340 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2161564340
26
+ - !ruby/object:Gem::Dependency
27
+ name: sequel
28
+ requirement: &2161563580 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.25.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2161563580
37
+ - !ruby/object:Gem::Dependency
38
+ name: sqlite3
39
+ requirement: &2161562920 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: 1.3.4
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2161562920
48
+ - !ruby/object:Gem::Dependency
49
+ name: contest
50
+ requirement: &2161562440 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2161562440
59
+ - !ruby/object:Gem::Dependency
60
+ name: rack-test
61
+ requirement: &2161561800 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *2161561800
70
+ description: Provides Rest API access to your models and serves JST pages.
71
+ email:
72
+ - rico@sinefunc.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - HISTORY.md
79
+ - README.md
80
+ - Rakefile
81
+ - lib/sinatra/backbone.rb
82
+ - lib/sinatra/jstpages.rb
83
+ - lib/sinatra/restapi.rb
84
+ - sinatra-backbone.gemspec
85
+ - test/app/views/chrome.jst.tpl
86
+ - test/app/views/editor/edit.jst.jade
87
+ - test/app_test.rb
88
+ - test/jst_test.rb
89
+ - test/test_helper.rb
90
+ - test/to_json_test.rb
91
+ has_rdoc: true
92
+ homepage: http://github.com/rstacruz/sinatra-backbone
93
+ licenses: []
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>'
108
+ - !ruby/object:Gem::Version
109
+ version: 1.3.1
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.6.2
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Helpful stuff using Sinatra with Backbone.
116
+ test_files: []