sinatra-backbone 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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: []