el 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODMwZTM2NDNkZmZhOGU2NTJkNzg5OTJmZGEzNDg5YTE4ODg3MGMwNQ==
5
+ data.tar.gz: !binary |-
6
+ MjNmOWIyOWU5YmZkY2I0NTIxOGI5YjA2NTQ4YmQ3ZWMyOTI5MDlhZg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MDU4MDIyZmVjZTczZmIxMDY4OWMzZGM2OGNiZGQ5YTgwYzdhYWY0MTA2ZWFj
10
+ MzFiNWFlMjM1MTE1MWE3ZTEwZTRjY2RlZDA4ZDg4MDdkYmJkMTZkNDc2Y2Uz
11
+ ZDM1MGQ1ODFmNjE4ZjFhZDIyMjgyNDc4ZTg4NGI4MjBhMjU0ZjM=
12
+ data.tar.gz: !binary |-
13
+ ZWMwNmE1MjYyN2EwM2UwMGQ4NDhmM2E2NjA2ZjQ2NGU5OTUzMTg3MTY5ZmNh
14
+ ZDNiMWRkM2M3YWZhMjQxNWY5ZTU2MGFkZjRkNzI5NjVlODBjYTc4Y2Y1NWU4
15
+ MGQ4YzA1ZGYzM2IyMDkxZmRmYjdjMmM2NWFlNmViNDZiYWZlODg=
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode
6
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+ gem 'rake', '~> 10'
4
+ gem 'specular', '>= 0.2.1'
5
+ gem 'sonar', '>= 0.1.5'
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+
2
+ Copyright (c) 2013 Silviu Rusu <slivuz@gmail.com>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"),
6
+ to deal in the Software without restriction, including without limitation
7
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
+ and/or sell copies of the Software, and to permit persons to whom the Software
9
+ is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,77 @@
1
+ ## Espresso Lungo
2
+
3
+ <a href="https://travis-ci.org/espresso/espresso-lungo">
4
+ <img src="https://travis-ci.org/espresso/espresso-lungo.png" align="right"></a>
5
+
6
+ ### Extra Functionality for [Espresso Framework](https://github.com/espresso/espresso)
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ $ gem install el
12
+ ```
13
+
14
+ or add `gem 'el'` to your `Gemfile`
15
+
16
+ ## Load
17
+
18
+ Ignore this if `el` added to `Gemfile` and `Bundler.require` used.
19
+
20
+ Otherwise you'll have to load `el` gem explicitly.
21
+
22
+ Just add `require 'el'` to the top of your app.
23
+
24
+ That's all. Now your `Espresso` applications contains extra functionality.
25
+
26
+ ## Use
27
+
28
+ ### CRUD
29
+
30
+ [Intro](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#intro) |
31
+ [Resource](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#resource) |
32
+ [Excluded Params](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#excluded-params) |
33
+ [Root](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#root) |
34
+ [Response](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#response) |
35
+ [Error Handler](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#error-handler) |
36
+ [Access Restriction](https://github.com/espresso/espresso-lungo/blob/master/docs/CRUD.md#access-restriction)
37
+
38
+ ### Assets
39
+
40
+ [Specialized Tags](https://github.com/espresso/espresso-lungo/blob/master/docs/Assets.md#specialized-tags) |
41
+ [Mapper](https://github.com/espresso/espresso-lungo/blob/master/docs/Assets.md#assets-mapper) |
42
+ [Sprockets](https://github.com/espresso/espresso-lungo/blob/master/docs/Assets.md#sprockets)
43
+
44
+ ### Content Helpers
45
+
46
+ [content_for](https://github.com/espresso/espresso-lungo/blob/master/docs/ContentHelpers.md#content_for) |
47
+ [capture_html](https://github.com/espresso/espresso-lungo/blob/master/docs/ContentHelpers.md#capture_html)
48
+
49
+ ### [Tag Factory](https://github.com/espresso/espresso-lungo/blob/master/docs/TagFactory.md)
50
+
51
+ ### [Cache Manager](https://github.com/espresso/espresso-lungo/blob/master/docs/Cache.md)
52
+
53
+
54
+ ## Contributing
55
+
56
+ - Fork `el` repository
57
+ - optionally create a new branch
58
+ - make your changes
59
+ - submit a pull request
60
+
61
+ <hr>
62
+
63
+ <p>
64
+ Issues/Bugs:
65
+ <a href="https://github.com/espresso/espresso-lungo/issues">
66
+ github.com/espresso/espresso-lungo/issues</a>
67
+ </p>
68
+ <p>
69
+ Mailing List: <a href="https://groups.google.com/forum/?fromgroups#!forum/espresso-framework">
70
+ groups.google.com/.../espresso-framework</a>
71
+ </p>
72
+ <p>
73
+ IRC channel: #espressorb on irc.freenode.net
74
+ </p>
75
+
76
+
77
+ ### Author - [Silviu Rusu](https://github.com/slivu). License - [MIT](https://github.com/espresso/espresso-lungo/blob/master/LICENSE).
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+ require 'bundler/gem_helper'
3
+ require './test/setup'
4
+ Dir['./test/**/test__*.rb'].each { |f| require f }
5
+
6
+ tasks = %w[crud assets content_helpers tag_factory cache ipcm]
7
+
8
+ namespace :test do
9
+
10
+ def run unit
11
+ puts "\n***\nTesting %s ..." % unit
12
+ session = session(unit)
13
+ session.run /ELTest__#{unit}/
14
+ puts session.failures if session.failed?
15
+ puts session.summary
16
+ session.exit_code == 0 || fail
17
+ end
18
+
19
+ def session unit
20
+ session = Specular.new
21
+ session.boot do
22
+ include Sonar
23
+ include ELSpecHelper
24
+ end
25
+ session.before do |tested_app|
26
+ if tested_app && EUtils.is_app?(tested_app)
27
+ tested_app.use Rack::Lint
28
+ app tested_app.mount
29
+ map tested_app.base_url
30
+ end
31
+ end
32
+ session
33
+ end
34
+
35
+ tasks.each do |t|
36
+ desc 'Run %s tests' % t
37
+ task t do
38
+ run t
39
+ end
40
+ end
41
+ end
42
+
43
+ desc 'Run all tests'
44
+ task test: tasks.reject {|t| t == 'ipcm'}.map {|u| 'test:' + u}
45
+ task default: :test
46
+
47
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,157 @@
1
+
2
+ ## Specialized Tags
3
+
4
+ `Espresso Lungo` offers specialized helpers for JavaScript, CSS and image tags.
5
+
6
+ ```ruby
7
+ js_tag :application
8
+ #=> <script src="/assets/application.js" ...
9
+
10
+ css_tag :application
11
+ #=> <link href="/assets/application.css" ...
12
+
13
+ png_tag 'icons/edit'
14
+ #=> <img src="/assets/icons/edit.png">
15
+ ```
16
+
17
+ Other helpers:
18
+
19
+ - jpg_tag
20
+ - jpeg_tag
21
+ - png_tag
22
+ - gif_tag
23
+ - tif_tag
24
+ - tiff_tag
25
+ - bmp_tag
26
+ - svg_tag
27
+ - xpm_tag
28
+
29
+
30
+ Specialized helpers will use assets URL as prefix:
31
+
32
+ ```ruby
33
+ # --- app.rb ---
34
+ class App < E
35
+ # ...
36
+
37
+ def index
38
+ render
39
+ end
40
+ end
41
+
42
+ app = E.new do
43
+ assets_url '/public'
44
+ end
45
+
46
+ # --- view/app/index.erb ---
47
+
48
+ js_tag :ui
49
+ #=> <script src="/public/ui.js" ...
50
+
51
+ png_tag 'images/header'
52
+ #=> <img src="/public/images/header.png"
53
+ ```
54
+
55
+ If you need to load some asset directly, without assets URL prefix, use `:src` option for js/images and `:href` for css:
56
+
57
+ ```ruby
58
+ js_tag src: "/jquery"
59
+ #=> <script src="/jquery.js" ...
60
+
61
+ css_tag href: "http://my.cdn/theme"
62
+ #=> <link href="http://my.cdn/theme.css" ...
63
+
64
+ png_tag src: 'icons/edit'
65
+ #=> <img src="icons/edit.png">
66
+ ```
67
+
68
+
69
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
70
+
71
+
72
+ ## Assets Mapper
73
+
74
+ `assets_mapper` allow to avoid repetitive path typing when loading assets.
75
+
76
+ **Example:** - long way:
77
+
78
+ ```ruby
79
+ js_tag 'vendor/jquery'
80
+
81
+ js_tag 'vendor/bootstrap/js/bootstrap'
82
+ css_tag 'vendor/bootstrap/css/bootstrap'
83
+
84
+ js_tag 'vendor/select2/select2.min'
85
+ css_tag 'vendor/select2/select2'
86
+ ```
87
+
88
+ **Example:** - using `assets_mapper`
89
+
90
+ ```ruby
91
+ assets_mapper :vendor do
92
+ js_tag 'jquery'
93
+
94
+ cd 'bootstrap'
95
+ js_tag 'js/bootstrap'
96
+ css_tag 'css/bootstrap'
97
+
98
+ cd '../select2'
99
+ js_tag 'select2.min'
100
+ css_tag 'select2'
101
+ ```
102
+
103
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
104
+
105
+
106
+ ## Sprockets
107
+
108
+ To enable and use Sprockets, simply call `assets_url` at app level:
109
+
110
+ ```ruby
111
+ app = E.new
112
+ app.assets_url '/assets'
113
+ app.assets.append_path 'assets'
114
+ app.run
115
+ ```
116
+
117
+ **Note:** by default no paths will be added to Sprockets environment, so it is up to you to do this by using `assets.append_path` or `assets.prepend_path`.
118
+
119
+ **Note:** Sprockets environment will use app root as base path, so folders containing assets should reside in your app root.
120
+
121
+ ```ruby
122
+ app = E.new do
123
+ assets_url '/assets'
124
+ assets.append_path 'assets'
125
+ assets.append_path 'public'
126
+ end
127
+ app.run
128
+ ```
129
+
130
+ `assets` method can be used to fully setup Sprockets environment:
131
+
132
+ ```ruby
133
+ app = E.new do
134
+ assets_url '/assets'
135
+ assets.compile = true
136
+ assets.compress = false
137
+ assets.js_compressor = :uglifier
138
+ # etc.
139
+ end
140
+
141
+ app.run
142
+ ```
143
+
144
+ To access assets inside controllers/templates, use `assets` method as well:
145
+
146
+ ```ruby
147
+ class App < E
148
+ # ...
149
+
150
+ def some_action
151
+ assets['application.js'] #=> #<Sprockets::BundledAsset ...>
152
+ end
153
+
154
+ end
155
+ ```
156
+
157
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
@@ -0,0 +1,255 @@
1
+
2
+ ## CRUD Helper
3
+
4
+ `crudify` method will automatically create CRUD actions that will map HTTP requests to corresponding methods on given Resource.
5
+
6
+ <pre>
7
+ Request Resource
8
+ -------------------------------------
9
+ GET /id #get(id)
10
+
11
+ POST / with POST data #create(params)
12
+
13
+ PUT /id with POST data #get(id).update(params) for DataMapper
14
+ #get(id).update_attributes(params) for ActiveRecord
15
+
16
+ PATCH /id with POST data #get(id).update(params) for DataMapper
17
+ #get(id).update_attributes(params) for ActiveRecord
18
+
19
+ DELETE /id #get(id).destroy
20
+
21
+ HEAD /id #get(id)
22
+
23
+ OPTIONS / returns actions available to client
24
+ </pre>
25
+
26
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
27
+
28
+
29
+ ## Resource
30
+
31
+
32
+ First argument is required and should provide the CRUDified resource.<br>
33
+ Resource should respond to `get` and `create` methods.<br>
34
+ Objects created/returned by resource should respond to `update`/`update_attributes` and `destroy` methods.
35
+
36
+ If your resource/objects behaves differently, you can map its methods by passing them as options.<br>
37
+
38
+ **Example:** - Force destroying objects
39
+
40
+ ```ruby
41
+ crudify ModelName, :delete => :destroy!
42
+ ```
43
+
44
+ **Example:** - Using a resource that creating records by `new` instead of `create`
45
+
46
+ ```ruby
47
+ crudify ModelName, :post => :new
48
+ ```
49
+
50
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
51
+
52
+
53
+ ## Excluded Params
54
+
55
+ By default all params will be sent to resource.
56
+
57
+ Good enough, however sometimes you need to exclude some of them.
58
+
59
+ This is easily accomplished by using `:exclude` option.
60
+
61
+ To exclude a single param, pass it as a string.
62
+
63
+ ```ruby
64
+ crudify Resource, :exclude => '__stream_uuid__'
65
+ ```
66
+
67
+ To exclude multiple params, pass them as an array.
68
+
69
+ ```ruby
70
+ crudify Resource, :exclude => ['__stream_uuid__', 'user']
71
+ ```
72
+
73
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
74
+
75
+
76
+ ## Root
77
+
78
+
79
+ By default, `crudify` will create actions that respond to controllers root path.
80
+
81
+ ```ruby
82
+ class App < E
83
+ map '/'
84
+
85
+ crudify SomeModel
86
+ end
87
+ ```
88
+
89
+ This will create following actions:
90
+
91
+ - get_index
92
+ - head_index
93
+ - post_index
94
+ - put_index
95
+ - patch_index
96
+ - delete_index
97
+ - options_index
98
+
99
+
100
+ To route CRUD actions to a different path, simply pass it as second argument:
101
+
102
+ ```ruby
103
+ class App < E
104
+ map '/'
105
+
106
+ crudify UsersModel, :users
107
+ end
108
+ ```
109
+
110
+ This will create following actions:
111
+
112
+ - get_users
113
+ - head_users
114
+ - post_users
115
+ - put_users
116
+ - patch_users
117
+ - delete_users
118
+ - options_users
119
+
120
+
121
+ **IMPORTANT!** When you need to override some CRUD action, define it using the corresponding verb.<br>
122
+ Verbless actions will have no effect cause **verbified actions has priority over verbless ones, regardless definition order**:
123
+
124
+ ```ruby
125
+ class App < E
126
+ map '/'
127
+
128
+ crudify SomeModel
129
+
130
+ def index
131
+ # will have no effect at all
132
+ end
133
+
134
+ def get_index
135
+ # will override crudified method that responds to GET requests
136
+ end
137
+ end
138
+ ```
139
+
140
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
141
+
142
+
143
+ ## Response
144
+
145
+ Crudifier will try to return the value of primary key of extracted/created/updated object.
146
+
147
+ By default `:id` is used as primary key.
148
+
149
+ To use a custom primary key, pass it via `:pkey` option:
150
+
151
+ ```ruby
152
+ crudify Resource, :pkey => 'prodID'
153
+ ```
154
+
155
+ If objects created by your resource does respond to `:[]` and does contain the pkey column, the value of `object[pkey column]` will be returned.
156
+
157
+ Otherwise if objects created by your resource does respond to a method of same name as `pkey`,
158
+ the value of `object.send(pkey)` will be returned.
159
+
160
+ Otherwise the object itself will be returned.
161
+
162
+ However, if you have a custom logic rather than simply return primary key, use a block.
163
+
164
+ The block will receive the object as first argument:
165
+
166
+ ```ruby
167
+ crudify UsersModel do |obj|
168
+ case
169
+ when post?, put?, patch?
170
+ obj.id
171
+ when head?
172
+ last_modified obj.last_modified
173
+ else
174
+ content_type '.json'
175
+ obj.to_json
176
+ end
177
+ end
178
+ ```
179
+
180
+ This will return object ID on POST, PUT, and PATCH requests.<br>
181
+
182
+ On HEAD requests, the framework is always sending an empty body,
183
+ so we only update the headers.<br>
184
+ This way the client may decide when to fetch the object.
185
+
186
+ On GET requests it will convert the object to JSON before it is sent to client.<br>
187
+ Also `content_type` is used to set proper content type.
188
+
189
+ DELETE action does not need a handler cause it ever returns an empty string.
190
+
191
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**
192
+
193
+ ## Error Handler
194
+
195
+ If your objects responds to `:errors` method,
196
+ crudifier will try to extract and format errors accordingly.
197
+
198
+ In case of errors, crudifier will behave depending on given options and proc.
199
+
200
+ If a proc given, crudifier will NOT halt the request.<br>
201
+ It will pass error to given proc via second argument instead.
202
+
203
+ To halt the request when a proc given, set `:halt_on_errors` to true.
204
+
205
+ If no proc given, request will be halted unconditionally.
206
+
207
+ By default the 500 status code will be used when halting.
208
+
209
+ To use a custom status code pass it via `:halt_with` option.
210
+
211
+ ## Access Restriction
212
+
213
+
214
+ Using `auth` will instruct client to require authorization.<br>
215
+ Access can be restricted to some or all actions.
216
+
217
+ In example below we will restrict access to Create, Update and Delete actions:
218
+
219
+ ```ruby
220
+ class App < E
221
+ # ...
222
+
223
+ auth :post_index, :put_index, :patch_index, :delete_index do |user, pass|
224
+ [user, pass] = ['admin', 'someReally?secretPass']
225
+ end
226
+
227
+ crudify ModelName
228
+ end
229
+ ```
230
+
231
+ Now, when the client will want to POST, PUT, PATCH, DELETE,
232
+ it will be asked for authorization.
233
+
234
+ And an OPTIONS request will return all actions for authorized clients and
235
+ only GET, HEAD, OPTIONS for non-authorized clients.
236
+
237
+ If a root path given, `crudify` will create actions that responds to that root,
238
+ thus actions name will contain given root.
239
+
240
+ In example below, `crudify` will create actions like `get_users`, `post_users`, `put_users` etc.<br>
241
+ That's why we should specify proper action name in `auth` for authorization to work:
242
+
243
+ ```ruby
244
+ class App < E
245
+ # ...
246
+
247
+ auth :post_users, :put_users, :patch_users, :delete_users do |user, pass|
248
+ [user, pass] = ['admin', 'someReally?secretPass']
249
+ end
250
+
251
+ crudify UsersModel, :users
252
+ end
253
+ ```
254
+
255
+ **[ [contents &uarr;](https://github.com/espresso/espresso-lungo#use) ]**