el 0.5.0

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.
@@ -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) ]**