bruter 0.0.2
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/LICENSE +19 -0
- data/README.md +222 -0
- data/lib/bruter.rb +9 -0
- data/lib/bruter/application.rb +158 -0
- data/lib/bruter/mustache.rb +82 -0
- data/lib/bruter/router.rb +22 -0
- data/lib/bruter/version.rb +3 -0
- metadata +166 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011 by Ted Kimble
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
# Bruter
|
2
|
+
|
3
|
+
Bruter is a miniature Ruby library that allows its bearer the ability to craft elegant Rack-based web applications with ease. Bruter stands on the backs of giants:
|
4
|
+
|
5
|
+
* Servers interface with Bruter -- a [Rack][rack]-compatible application -- with minimal configuration
|
6
|
+
* Variably named paths are routed to their proper destination by [HttpRouter][http_router]
|
7
|
+
* Dynamic assets -- Sass, LESS, CoffeeScript and more -- are compiled and served by [Sprockets][sprockets]
|
8
|
+
* Views and templates are rendered as one by [Mustache][mustache]
|
9
|
+
|
10
|
+
Surely under 200 lines of code without comments, Bruter is meant to be easy to understand and use. But do not underestimate Bruter's small footprint: Bruter's role lies in its ability to delegate responsibility and provide an intuitive syntax.
|
11
|
+
|
12
|
+
## Example
|
13
|
+
|
14
|
+
Bruter can be found hiding in the usual places.
|
15
|
+
|
16
|
+
`gem install bruter`
|
17
|
+
|
18
|
+
You'll need to create a Rackup file.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# config.ru
|
22
|
+
require 'bruter'
|
23
|
+
$:.unshift File.dirname(__FILE__)
|
24
|
+
require 'app/application'
|
25
|
+
require 'app/views/hello' # Note that you need to require any files you'll reference, including views
|
26
|
+
|
27
|
+
run Application.new
|
28
|
+
```
|
29
|
+
|
30
|
+
Routes and asset paths are defined in a subclass of `Bruter::Application`.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
# app/application.rb
|
34
|
+
|
35
|
+
class Application < Bruter::Application
|
36
|
+
|
37
|
+
serve_assets 'assets' # Asset paths are relative to where the method is called
|
38
|
+
get '/hello/:name', to: 'views/hello' # Bruter will look for a Views::Hello class to render
|
39
|
+
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
View classes should subclass `Bruter::Mustache`.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
# app/views/hello.rb
|
47
|
+
|
48
|
+
module Views
|
49
|
+
class Hello < Bruter::Mustache
|
50
|
+
|
51
|
+
def name
|
52
|
+
params[:name]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
Bruter's Mustache will automatically look for an accompanying template in `'../templates'` relative to the view class.
|
60
|
+
|
61
|
+
```html
|
62
|
+
# app/templates/hello.mustache
|
63
|
+
|
64
|
+
<!DOCTYPE html>
|
65
|
+
<html lang="en">
|
66
|
+
<head>
|
67
|
+
<meta charset="utf-8">
|
68
|
+
<title>Hello {{name}}!</title>
|
69
|
+
<link rel="stylesheet" href="/stylesheets/application.css">
|
70
|
+
</head>
|
71
|
+
<body>
|
72
|
+
<h1>Bruter kindly welcomes you, {{name}}!</h1>
|
73
|
+
<img src="/images/bruter.jpg">
|
74
|
+
</body>
|
75
|
+
</html>
|
76
|
+
```
|
77
|
+
|
78
|
+
Place `'bruter.jpg'` in `'app/assets/images'` and a stylesheet of your preferred format in `'app/assets/stylesheets'` and Sprockets will take care of the rest.
|
79
|
+
|
80
|
+
```css
|
81
|
+
# app/assets/stylesheets/application.css.scss
|
82
|
+
|
83
|
+
body {
|
84
|
+
text-align: center
|
85
|
+
h1 { font-size: 1.25em; }
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
Bruter is a Rack application; choose any compatible server.
|
90
|
+
|
91
|
+
`rackup config.ru`
|
92
|
+
|
93
|
+
## Routing
|
94
|
+
|
95
|
+
Routing is handled by HttpRouter. Most applications will subclass `Bruter::Application` and generate routes by calling the class method `:add`. The method accepts a path and a hash of options.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
add(path, options = {})
|
99
|
+
```
|
100
|
+
|
101
|
+
Most routes will want to specify a `:to` option. The `:to` option can be any Rack application.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
add '/welcome', to: [200, {'Content-Type' => 'text/html'}, ['Welcome to Bruter.']]
|
105
|
+
```
|
106
|
+
|
107
|
+
Or more interestingly, it can be a string representing a Mustache view class.
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
add '/welcome', to: 'welcome' # Looks for Welcome
|
111
|
+
add '/hello', to: 'views/hello_there' # Looks for Views::HelloThere
|
112
|
+
```
|
113
|
+
|
114
|
+
The path can include named variables and globs.
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
add '/hello/:name', to: 'hello' # Matches '/hello/bruter' and '/hello/ted'
|
118
|
+
add '/tagged/*tags', to: 'tagged' # Matches '/tagged/web' and '/tagged/volcano/lava/dinosaurs'
|
119
|
+
```
|
120
|
+
|
121
|
+
Routes can be restricted to certain HTTP request methods.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
add '/post/:id', to: 'posts/show', request_method: ['GET', 'HEAD']
|
125
|
+
```
|
126
|
+
|
127
|
+
Routes can be named in order to construct their paths at a later time.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
add '/post/:id', to: 'posts/show', name: :post # In a view, calling path(:post, 5) returns '/post/5'
|
131
|
+
```
|
132
|
+
|
133
|
+
Variable paths can have a regex matching condition placed on them.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
add '/:a-plus-:b-equals', to: 'add', matching: {a: /\d+/, b: /\d+/}
|
137
|
+
```
|
138
|
+
|
139
|
+
### Redirects
|
140
|
+
|
141
|
+
Redirects can be added by setting a `:redirect` option instead of a `:to` option.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
add '/old-path', redirect: '/new-path'
|
145
|
+
```
|
146
|
+
|
147
|
+
### Static Files
|
148
|
+
|
149
|
+
Static files can be served by the router by setting a `:static` option instead of a `:to` option.
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
add '/images', static: 'app/images' # Will look for '/images/logo/large.png' in 'app/images/logo/large.png'
|
153
|
+
```
|
154
|
+
|
155
|
+
### Convenience Methods
|
156
|
+
|
157
|
+
Bruter also provides a number of convenience methods that pass to `:add` but first set their `:request_method` option to correspond to the name of the method.
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
get(path, options = {})
|
161
|
+
post(path, options = {})
|
162
|
+
put(path, options = {})
|
163
|
+
delete(path, options = {})
|
164
|
+
head(path, options = {})
|
165
|
+
options(path, options = {})
|
166
|
+
trace(path, options = {})
|
167
|
+
get(path, options = {})
|
168
|
+
```
|
169
|
+
|
170
|
+
### Under the Hood
|
171
|
+
|
172
|
+
When a new `Bruter::Application` object is instantiated, an `HttpRouter` object is also instantiated and any routes added to the application class are added to the router object. This object can also be accessed directly with the `:router` getter method.
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
app = Bruter::Application.new
|
176
|
+
app.router.add('/').to('my_view')
|
177
|
+
run app
|
178
|
+
```
|
179
|
+
|
180
|
+
See [HttpRouter][http_router] for more information.
|
181
|
+
|
182
|
+
## Assets
|
183
|
+
|
184
|
+
Asset compilation and serving is handled by Sprockets. Asset paths can be added to the asset environment with the class method `:serve_assets`. The method accepts a path, which is relative to the location the method is called.
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
# app/application.rb
|
188
|
+
class Application < Bruter::Application
|
189
|
+
|
190
|
+
serve_assets 'assets'
|
191
|
+
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
This application will compile and serve assets located in `'app/assets'`. For example, a route of `/images/logo.png` will have the asset environment look for a file named `'app/assets/images/logo.png'` and compile (if necessary) and serve it. If it cannot be found, action is passed to the router.
|
196
|
+
|
197
|
+
Like with `HttpRouter`, a new `Sprockets::Environment` object is instantiated and any asset paths appended to it when a new `Bruter::Application` object is instantiated. This environment can be accessed directly with the `:assets` getter method.
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
app = Bruter::Application.new
|
201
|
+
app.assets.append_path('my/assets/path')
|
202
|
+
run app
|
203
|
+
```
|
204
|
+
|
205
|
+
See [Sprockets][sprockets] for more information.
|
206
|
+
|
207
|
+
## Rendering
|
208
|
+
|
209
|
+
Routes can be directed to Rack-compatible applications or to strings that represent Mustache view classes. When the latter occurs the application will instantiate the view class with three objects -- a Rack request object, a Rack response object, and the Router object -- and call render. The view class can simply subclass from `Mustache`, but it will likely want to subclass `Bruter::Mustache`, itself a subclass of `Mustache`.
|
210
|
+
|
211
|
+
`Bruter::Mustache` provides a few helpers. First, it tells any subclasses to look for their templates in `'../template'` relative to the view file. It provides an `:initialize` method that accepts the three previously named objects and then attempts to invoke `:setup` if the view has defined it. It provides getter methods to access the Rack request object (`:request`), the Rack response object (`:response`), the Router object (`:router`), the Rack env (`:env`) and the params set during routing (`:params`). It also defines a `:path` method, which accepts the name of a named route and an optional list of arguments to construct a path string.
|
212
|
+
|
213
|
+
For more information, see [Mustache][mustache].
|
214
|
+
|
215
|
+
## License
|
216
|
+
|
217
|
+
Bruter is Copyright © 2011 by Ted Kimble and distributed under the MIT license; see `LICENSE` for more information.
|
218
|
+
|
219
|
+
[rack]: https://github.com/rack/rack
|
220
|
+
[http_router]: https://github.com/joshbuddy/http_router
|
221
|
+
[sprockets]: https://github.com/sstephenson/sprockets
|
222
|
+
[mustache]: https://github.com/defunkt/mustache
|
data/lib/bruter.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
module Bruter
|
2
|
+
class Application
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :_directory, :routes, :asset_paths
|
6
|
+
|
7
|
+
# Hack to set :_directory to the file location in which this class is
|
8
|
+
# subclassed. Those not subclassing Bruter::Mustache in a file may want
|
9
|
+
# to explicitly set :_directory.
|
10
|
+
def inherited(klass)
|
11
|
+
klass._directory = File.dirname(caller.first[/^[^:]+/])
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieves the absolute path of the argument path relative to where
|
15
|
+
# Bruter::Application was subclassed (:_directory, see above).
|
16
|
+
def absolute_path(path)
|
17
|
+
File.expand_path(path, _directory)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Ensure that :routes defaults to an array.
|
21
|
+
def routes
|
22
|
+
@routes ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
# Ensure that :asset_paths defaults to an array.
|
26
|
+
def asset_paths
|
27
|
+
@asset_paths ||= []
|
28
|
+
end
|
29
|
+
|
30
|
+
# Adds a route to the application. Accepts the path of the route and a
|
31
|
+
# hash of options. The path is required and can include named variables
|
32
|
+
# ('/post/:id') and globs ('/tags/*tags').
|
33
|
+
#
|
34
|
+
# The options hash must include either a :to, :redirect or :static key;
|
35
|
+
# the route will not be recognized if none is present. If more than one
|
36
|
+
# is present the preceding order of keys will serve as precedence.
|
37
|
+
#
|
38
|
+
# The :to key should be either a Rack application or a string
|
39
|
+
# representing a Mustache view class. (eg 'my_blog/index' =>
|
40
|
+
# MyBlog::Index)
|
41
|
+
#
|
42
|
+
# The :redirect key should be a string representing the new path or
|
43
|
+
# url that the route should redirect to.
|
44
|
+
#
|
45
|
+
# The :static key should be a string representing a path on the file
|
46
|
+
# system (relative to where the method was called).
|
47
|
+
#
|
48
|
+
# Additional options:
|
49
|
+
# Add a name to the route (:name => :posts)
|
50
|
+
# Add a regex matching condition (:matching => {:id => /\d+/})
|
51
|
+
# Add a HTTP method constraint (:request_method => ['POST', 'HEAD'])
|
52
|
+
#
|
53
|
+
# Examples:
|
54
|
+
# add '/', to: 'views/posts/index', name: :posts
|
55
|
+
# add '/posts/:id', to: 'views/posts/show', name: :post
|
56
|
+
# add '/posts/:id', to: 'views/posts/update', request_method: ['PUT']
|
57
|
+
# add '/tags/*tags', to: 'views/posts/tagged', name: :tagged
|
58
|
+
#
|
59
|
+
# add '/:i/is-an-integer', to: 'views/integer', matching: {i: /\d+/}
|
60
|
+
#
|
61
|
+
# add '/old-location', redirect: '/new-location'
|
62
|
+
# add '/images/*', static: 'images'
|
63
|
+
#
|
64
|
+
# For more information see the HttpRouter library
|
65
|
+
# (https://github.com/joshbuddy/http_router)
|
66
|
+
def add(path, options = {})
|
67
|
+
routes << {path: path, options: options}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Convenience method setting the :request_method option to 'GET'.
|
71
|
+
def get(path, options = {})
|
72
|
+
add(path, options.merge(request_method: 'GET'))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Convenience method setting the :request_method option to 'POST'.
|
76
|
+
def post(path, options = {})
|
77
|
+
add(path, options.merge(request_method: 'POST'))
|
78
|
+
end
|
79
|
+
|
80
|
+
# Convenience method setting the :request_method option to 'PUT'.
|
81
|
+
def put(path, options = {})
|
82
|
+
add(path, options.merge(request_method: 'PUT'))
|
83
|
+
end
|
84
|
+
|
85
|
+
# Convenience method setting the :request_method option to 'DELETE'.
|
86
|
+
def delete(path, options = {})
|
87
|
+
add(path, options.merge(request_method: 'DELETE'))
|
88
|
+
end
|
89
|
+
|
90
|
+
# Convenience method setting the :request_method option to 'HEAD'.
|
91
|
+
def head(path, options = {})
|
92
|
+
add(path, options.merge(request_method: 'HEAD'))
|
93
|
+
end
|
94
|
+
|
95
|
+
# Convenience method setting the :request_method option to 'OPTIONS'.
|
96
|
+
def options(path, options = {})
|
97
|
+
add(path, options.merge(request_method: 'OPTIONS'))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Convenience method setting the :request_method option to 'TRACE'.
|
101
|
+
def trace(path, options = {})
|
102
|
+
add(path, options.merge(request_method: 'TRACE'))
|
103
|
+
end
|
104
|
+
|
105
|
+
# Tells the application's asset environment to serve and compile assets
|
106
|
+
# in the path argument without passing to the router. The path is
|
107
|
+
# relative to where Bruter::Application is subclassed.
|
108
|
+
def serve_assets(path)
|
109
|
+
asset_paths << path
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
attr_accessor :router, :assets
|
115
|
+
|
116
|
+
# Initializing a new Bruter::Application or a subclass of it will
|
117
|
+
# instantiate a new Router and Sprockets::Environment and subsequently add
|
118
|
+
# all routes to the router and asset paths to the asset environment.
|
119
|
+
def initialize
|
120
|
+
@router = Router.new
|
121
|
+
@assets = Sprockets::Environment.new
|
122
|
+
#
|
123
|
+
self.class.routes.each do |r|
|
124
|
+
path = r[:path]
|
125
|
+
options = r[:options]
|
126
|
+
to = options.delete(:to)
|
127
|
+
redirect = options.delete(:redirect)
|
128
|
+
static = options.delete(:static)
|
129
|
+
route = @router.add(path)
|
130
|
+
if to
|
131
|
+
route.to(to)
|
132
|
+
elsif redirect
|
133
|
+
route.redirect(redirect)
|
134
|
+
elsif static
|
135
|
+
route.static(self.class.absolute_path(static))
|
136
|
+
end
|
137
|
+
options.each { |k, v| route.send(k, v) if route.respond_to?(k) }
|
138
|
+
end
|
139
|
+
#
|
140
|
+
self.class.asset_paths.each do |path|
|
141
|
+
@assets.append_path(self.class.absolute_path(path))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# A call to this application will first check to see if the path is in any
|
146
|
+
# of the asset environment's paths. If so, the asset environment will
|
147
|
+
# attempt to serve and compile the asset; if not, action is passed to the
|
148
|
+
# router.
|
149
|
+
def call(env)
|
150
|
+
if @assets.find_asset(env['PATH_INFO'].gsub(/\A\//, ''))
|
151
|
+
@assets.call(env)
|
152
|
+
else
|
153
|
+
@router.call(env)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Bruter
|
2
|
+
class Mustache < Mustache
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :_directory
|
6
|
+
|
7
|
+
# Hack to set :_directory to the file location in which this class is
|
8
|
+
# subclassed. Those not subclassing Bruter::Mustache in a file may want
|
9
|
+
# to explicitly set :_directory or the @template_path variable with
|
10
|
+
# :template_path=(path).
|
11
|
+
def inherited(klass)
|
12
|
+
klass._directory = File.dirname(caller.first[/^[^:]+/])
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the default template path to '../templates' relative to where the
|
16
|
+
# this class is subclassed.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# # in '/path/to/app/views/tagged.rb'
|
20
|
+
# module Views
|
21
|
+
# class TaggedPosts < Bruter::Mustache
|
22
|
+
# puts self.template_path
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# => '/path/to/app/templates'
|
27
|
+
def template_path
|
28
|
+
if _directory
|
29
|
+
@template_path ||= File.expand_path('../templates', _directory)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sets the default template name to an underscored version of the class
|
36
|
+
# name.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# # in '/path/to/app/views/tagged.rb'
|
40
|
+
# module Views
|
41
|
+
# class TaggedPosts < Bruter::Mustache
|
42
|
+
# puts self.template_name
|
43
|
+
# puts self.template_file
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# => 'tagged_posts'
|
48
|
+
# => '/path/to/app/templates/tagged_posts.mustache'
|
49
|
+
def template_name
|
50
|
+
@template_name ||= self.to_s.underscore.split('/').last
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :request, :response, :router
|
55
|
+
|
56
|
+
# Sets the Rack request and response objects and the calling router
|
57
|
+
# object. Subclasses can define a :setup method that will be invoked after
|
58
|
+
# initialization is complete.
|
59
|
+
def initialize(request, response, router)
|
60
|
+
@request = request
|
61
|
+
@response = response
|
62
|
+
@router = router
|
63
|
+
send :setup if respond_to?(:setup)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Retrieves the Rack request's env.
|
67
|
+
def env
|
68
|
+
@request.env
|
69
|
+
end
|
70
|
+
|
71
|
+
# Retrieves the params from a name variable or globbed route.
|
72
|
+
def params
|
73
|
+
env['router.params']
|
74
|
+
end
|
75
|
+
|
76
|
+
# Retrieves the path for a named route given the name and any arguments.
|
77
|
+
def path(name, *args)
|
78
|
+
args.any? ? router.url(name, *args) : router.url(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bruter
|
2
|
+
class Router < HttpRouter
|
3
|
+
|
4
|
+
# Catches destinations that do not respond to :call(env) and transforms
|
5
|
+
# them into a constant, initializes them with Rack request and response
|
6
|
+
# objects and the router itself, and invokes :render. The Rack response's
|
7
|
+
# body will be set to the result of :render and the response finished.
|
8
|
+
def process_destination_path(path, env)
|
9
|
+
destination = path.route.dest
|
10
|
+
if destination.respond_to?(:call)
|
11
|
+
destination.call(env)
|
12
|
+
else
|
13
|
+
request = ::Rack::Request.new(env)
|
14
|
+
response = ::Rack::Response.new
|
15
|
+
view = destination.camelize.constantize
|
16
|
+
response.body = [view.new(request, response, self).render]
|
17
|
+
response.finish
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bruter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ted Kimble
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-28 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 29
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 3
|
32
|
+
- 3
|
33
|
+
version: 1.3.3
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: http_router
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - "="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 51
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 10
|
48
|
+
- 2
|
49
|
+
version: 0.10.2
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: sprockets
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - "="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 15
|
61
|
+
segments:
|
62
|
+
- 2
|
63
|
+
- 0
|
64
|
+
- 0
|
65
|
+
version: 2.0.0
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: activesupport
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - "="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 3
|
79
|
+
- 1
|
80
|
+
- 0
|
81
|
+
version: 3.1.0
|
82
|
+
type: :runtime
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: i18n
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
type: :runtime
|
97
|
+
version_requirements: *id005
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: mustache
|
100
|
+
prerelease: false
|
101
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ~>
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 411
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
- 99
|
110
|
+
- 4
|
111
|
+
version: 0.99.4
|
112
|
+
type: :runtime
|
113
|
+
version_requirements: *id006
|
114
|
+
description: Bruter is a miniature Ruby library that allows its bearer the ability to craft elegant Rack-based web applications with ease.
|
115
|
+
email: ted@kimble.co
|
116
|
+
executables: []
|
117
|
+
|
118
|
+
extensions: []
|
119
|
+
|
120
|
+
extra_rdoc_files: []
|
121
|
+
|
122
|
+
files:
|
123
|
+
- README.md
|
124
|
+
- LICENSE
|
125
|
+
- lib/bruter/application.rb
|
126
|
+
- lib/bruter/mustache.rb
|
127
|
+
- lib/bruter/router.rb
|
128
|
+
- lib/bruter/version.rb
|
129
|
+
- lib/bruter.rb
|
130
|
+
homepage: https://github.com/tedkimble/bruter
|
131
|
+
licenses: []
|
132
|
+
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
hash: 55
|
144
|
+
segments:
|
145
|
+
- 1
|
146
|
+
- 9
|
147
|
+
- 2
|
148
|
+
version: 1.9.2
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 3
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
version: "0"
|
158
|
+
requirements: []
|
159
|
+
|
160
|
+
rubyforge_project: bruter
|
161
|
+
rubygems_version: 1.8.6
|
162
|
+
signing_key:
|
163
|
+
specification_version: 3
|
164
|
+
summary: Bruter helps you craft elegant Ruby web applications.
|
165
|
+
test_files: []
|
166
|
+
|