lotus-view 0.0.0 → 0.1.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.
- checksums.yaml +4 -4
- data/.gitignore +6 -15
- data/.travis.yml +6 -0
- data/.yardopts +3 -0
- data/Gemfile +13 -2
- data/README.md +514 -3
- data/Rakefile +17 -1
- data/lib/lotus/layout.rb +132 -0
- data/lib/lotus/presenter.rb +70 -0
- data/lib/lotus/view/dsl.rb +247 -0
- data/lib/lotus/view/inheritable.rb +50 -0
- data/lib/lotus/view/rendering/layout_finder.rb +104 -0
- data/lib/lotus/view/rendering/layout_registry.rb +63 -0
- data/lib/lotus/view/rendering/layout_scope.rb +138 -0
- data/lib/lotus/view/rendering/null_layout.rb +52 -0
- data/lib/lotus/view/rendering/null_template.rb +79 -0
- data/lib/lotus/view/rendering/partial.rb +29 -0
- data/lib/lotus/view/rendering/partial_finder.rb +41 -0
- data/lib/lotus/view/rendering/registry.rb +129 -0
- data/lib/lotus/view/rendering/scope.rb +48 -0
- data/lib/lotus/view/rendering/template.rb +56 -0
- data/lib/lotus/view/rendering/template_finder.rb +53 -0
- data/lib/lotus/view/rendering/templates_finder.rb +85 -0
- data/lib/lotus/view/rendering/view_finder.rb +37 -0
- data/lib/lotus/view/rendering.rb +265 -0
- data/lib/lotus/view/template.rb +45 -0
- data/lib/lotus/view/version.rb +4 -1
- data/lib/lotus/view.rb +180 -2
- data/lib/lotus-view.rb +1 -0
- data/lotus-view.gemspec +15 -11
- data/test/fixtures/templates/app/app_view.html.erb +0 -0
- data/test/fixtures/templates/app/view.html.erb +0 -0
- data/test/fixtures/templates/application.html.erb +10 -0
- data/test/fixtures/templates/articles/_form.html.erb +4 -0
- data/test/fixtures/templates/articles/alternative_new.html.erb +1 -0
- data/test/fixtures/templates/articles/index.atom.erb +5 -0
- data/test/fixtures/templates/articles/index.html.erb +3 -0
- data/test/fixtures/templates/articles/index.json.erb +9 -0
- data/test/fixtures/templates/articles/index.rss.erb +0 -0
- data/test/fixtures/templates/articles/new.html.erb +7 -0
- data/test/fixtures/templates/articles/show.html.erb +1 -0
- data/test/fixtures/templates/articles/show.json.erb +5 -0
- data/test/fixtures/templates/contacts/show.html.haml +1 -0
- data/test/fixtures/templates/dashboard/index.html.erb +2 -0
- data/test/fixtures/templates/hello_world_view.html.erb +1 -0
- data/test/fixtures/templates/index_view.html.erb +1 -0
- data/test/fixtures/templates/json_render_view.json.erb +3 -0
- data/test/fixtures/templates/render_view.html.erb +1 -0
- data/test/fixtures/templates/shared/_sidebar.html.erb +1 -0
- data/test/fixtures.rb +187 -0
- data/test/layout_test.rb +10 -0
- data/test/load_test.rb +79 -0
- data/test/presenter_test.rb +31 -0
- data/test/rendering_test.rb +125 -0
- data/test/root_test.rb +38 -0
- data/test/test_helper.rb +24 -0
- data/test/version_test.rb +7 -0
- data/test/view_test.rb +27 -0
- metadata +137 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73dd8583d5b48a96229bf72a847120710d701d0e
|
4
|
+
data.tar.gz: 99c9a9ce462407779c7a14113dddd4c8129c4dfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 098ee9925947868c1f65424e0d443ba6722866f904ba4279fc9d9a79a9f7cb41229723b8f79ddd1aedb80dc521fb880056ce04344a8ad210175f776051a717b8
|
7
|
+
data.tar.gz: 3fd4ac2c4c5738c15aed901ea82df7e2fb26234df758e1eea35794721ae4f6adc50cd9d7744e8fccd38a2077e0d9eab6b2e1d64265a9f586e91fd4ba10924490
|
data/.gitignore
CHANGED
@@ -1,17 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
1
|
+
.devnotes
|
2
|
+
.greenbar
|
6
3
|
Gemfile.lock
|
7
|
-
|
8
|
-
|
9
|
-
coverage
|
4
|
+
coverage/
|
5
|
+
.yardoc/
|
10
6
|
doc/
|
11
|
-
|
12
|
-
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
7
|
+
*.gem
|
8
|
+
.bundle
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
if !ENV['TRAVIS']
|
4
|
+
gem 'byebug', require: false, platforms: :ruby if RUBY_VERSION == '2.1.1'
|
5
|
+
gem 'yard', require: false
|
6
|
+
gem 'lotus-utils', require: false, path: '../lotus-utils'
|
7
|
+
else
|
8
|
+
gem 'lotus-utils'
|
9
|
+
end
|
10
|
+
|
11
|
+
gem 'rake'
|
12
|
+
gem 'tilt', '~> 2.0.1', '>= 2.0.1'
|
13
|
+
gem 'haml', require: false
|
14
|
+
gem 'simplecov', require: false
|
15
|
+
gem 'coveralls', require: false
|
data/README.md
CHANGED
@@ -1,6 +1,39 @@
|
|
1
1
|
# Lotus::View
|
2
2
|
|
3
|
-
|
3
|
+
A View layer for [Lotus](http://lotusrb.org).
|
4
|
+
|
5
|
+
It's based on a **separation between views and templates**.
|
6
|
+
|
7
|
+
A _view_ is an object that encapsulates the presentation logic of a page.
|
8
|
+
A _template_ is a file that defines the semantic and visual elements of a page.
|
9
|
+
In order to show a result to an user, a template must be _rendered_ by a view.
|
10
|
+
|
11
|
+
Keeping things separated, helps to declutter templates and models from presentation logic.
|
12
|
+
Also, since views are objects they are easily testable.
|
13
|
+
If you ever used [Mustache](http://mustache.github.io/), you are already aware of the advantages.
|
14
|
+
|
15
|
+
Like all the other Lotus compontents it can be used as a standalone framework, or within a full Lotus application.
|
16
|
+
|
17
|
+
## Status
|
18
|
+
|
19
|
+
[](http://badge.fury.io/rb/lotus-view)
|
20
|
+
[](http://travis-ci.org/lotus/view?branch=master)
|
21
|
+
[](https://coveralls.io/r/lotus/view)
|
22
|
+
[](https://codeclimate.com/github/lotus/view)
|
23
|
+
[](https://gemnasium.com/lotus/view)
|
24
|
+
[](http://inch-pages.github.io/github/lotus/view)
|
25
|
+
|
26
|
+
## Contact
|
27
|
+
|
28
|
+
* Home page: http://lotusrb.org
|
29
|
+
* Mailing List: http://lotusrb.org/mailing-list
|
30
|
+
* API Doc: http://rdoc.info/gems/lotus-view
|
31
|
+
* Bugs/Issues: https://github.com/lotus/view/issues
|
32
|
+
* Support: http://stackoverflow.com/questions/tagged/lotus-ruby
|
33
|
+
|
34
|
+
## Rubies
|
35
|
+
|
36
|
+
__Lotus::View__ supports Ruby (MRI) 2+
|
4
37
|
|
5
38
|
## Installation
|
6
39
|
|
@@ -18,12 +51,490 @@ Or install it yourself as:
|
|
18
51
|
|
19
52
|
## Usage
|
20
53
|
|
21
|
-
|
54
|
+
### Conventions
|
55
|
+
|
56
|
+
* Templates are searched under `Lotus::View.root`, set this value according to your app structure (eg. `"app/templates"`).
|
57
|
+
* A view will look for a template with a file name that is composed by its full class name (eg. `"articles/index"`).
|
58
|
+
* A template must have two concatenated extensions: one for the format one for the engine (eg. `".html.erb"`).
|
59
|
+
* The framework must be loaded before to render for the first time: `Lotus::View.load!`.
|
60
|
+
|
61
|
+
### Views
|
62
|
+
|
63
|
+
A simple view looks like this:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'lotus/view'
|
67
|
+
|
68
|
+
module Articles
|
69
|
+
class Index
|
70
|
+
include Lotus::View
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Suppose that we want to render a list of `articles`:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
require 'lotus/view'
|
79
|
+
|
80
|
+
module Articles
|
81
|
+
class Index
|
82
|
+
include Lotus::View
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
Lotus::View.root = 'app/templates'
|
87
|
+
Lotus::View.load!
|
88
|
+
|
89
|
+
path = Lotus::View.root.join('articles/index.html.erb')
|
90
|
+
template = Lotus::View::Template.new(path)
|
91
|
+
articles = ArticleRepository.all
|
92
|
+
|
93
|
+
Articles::Index.new(template, articles: articles).render
|
94
|
+
```
|
95
|
+
|
96
|
+
While this code is working fine, it's inefficient and verbose, because we are loading a template from the filesystem for each rendering attempt.
|
97
|
+
Also, this is strictly related to the HTML format, what if we want to manage other formats?
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
require 'lotus/view'
|
101
|
+
|
102
|
+
module Articles
|
103
|
+
class Index
|
104
|
+
include Lotus::View
|
105
|
+
end
|
106
|
+
|
107
|
+
class AtomIndex < Index
|
108
|
+
format :atom
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
Lotus::View.root = 'app/templates'
|
113
|
+
Lotus::View.load!
|
114
|
+
|
115
|
+
articles = ArticleRepository.all
|
116
|
+
|
117
|
+
Articles::Index.render(format: :html, articles: articles)
|
118
|
+
# => This will use Articles::Index
|
119
|
+
# and "articles/index.html.erb"
|
120
|
+
|
121
|
+
Articles::Index.render(format: :atom, articles: articles)
|
122
|
+
# => This will use Articles::AtomIndex
|
123
|
+
# and "articles/index.atom.erb"
|
124
|
+
|
125
|
+
Articles::Index.render(format: :xml, articles: articles)
|
126
|
+
# => This will raise a Lotus::View::MissingTemplateError
|
127
|
+
```
|
128
|
+
|
129
|
+
### Locals
|
130
|
+
|
131
|
+
All the objects passed in the context are called _locals_, they are available both in the view and in the template:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
require 'lotus/view'
|
135
|
+
|
136
|
+
module Articles
|
137
|
+
class Show
|
138
|
+
include Lotus::View
|
139
|
+
|
140
|
+
def authors
|
141
|
+
article.map(&:author).join ', '
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
```erb
|
148
|
+
<h1><%= article.title %></h1>
|
149
|
+
<article>
|
150
|
+
<%= article.content %>
|
151
|
+
</article>
|
152
|
+
```
|
153
|
+
|
154
|
+
All the methods defined in the view are accessible in the template:
|
155
|
+
|
156
|
+
```erb
|
157
|
+
<h2><%= authors %></h2>
|
158
|
+
```
|
159
|
+
|
160
|
+
For convenience, they are also available as an Hash `locals` in the view.
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
require 'lotus/view'
|
164
|
+
|
165
|
+
module Articles
|
166
|
+
class Show
|
167
|
+
include Lotus::View
|
168
|
+
|
169
|
+
# This view, already responds to `#article` because there is an element in
|
170
|
+
# the locals with the same key.
|
171
|
+
#
|
172
|
+
# In order to allow developers to override those methods, and decorate a
|
173
|
+
# single locals object, a view has an Hash with the same values.
|
174
|
+
#
|
175
|
+
# If we had implemented this method like this:
|
176
|
+
#
|
177
|
+
# def article
|
178
|
+
# ArticlePresenter.new(article)
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# We would have generated a `SystemStackError` (stack level too deep).
|
182
|
+
def article
|
183
|
+
ArticlePresenter.new(locals[:article])
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
### Custom rendering
|
190
|
+
|
191
|
+
Since a view is an object, you can override `#render` and provide your own rendering policy:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
require 'lotus/view'
|
195
|
+
|
196
|
+
module Articles
|
197
|
+
class Show
|
198
|
+
include Lotus::View
|
199
|
+
format :json
|
200
|
+
|
201
|
+
def render
|
202
|
+
ArticleSerializer.new(article).to_json
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
Articles::Show.render({format: :json, article: article})
|
208
|
+
# => This will render from ArticleSerializer,
|
209
|
+
# without the need of a template
|
210
|
+
```
|
211
|
+
|
212
|
+
### Format
|
213
|
+
|
214
|
+
The `.format` DSL is used to declare one or more mime types that a view is able to render.
|
215
|
+
These values are **arbitrary**, just **be sure to create a corresponding template**.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
require 'lotus/view'
|
219
|
+
|
220
|
+
module Articles
|
221
|
+
class Show
|
222
|
+
include Lotus::View
|
223
|
+
format :custom
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
Articles::Show.render({format: :custom, article: article})
|
228
|
+
# => This will render "articles/show.custom.erb"
|
229
|
+
```
|
230
|
+
|
231
|
+
### Engines
|
232
|
+
|
233
|
+
The builtin rendering engine is [ERb](http://en.wikipedia.org/wiki/ERuby).
|
234
|
+
However, Lotus::View supports countless rendering engines out of the box.
|
235
|
+
Require your library of choice **before** of requiring `'lotus/view'`, and it will just work.
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
require 'haml'
|
239
|
+
require 'lotus/view'
|
240
|
+
|
241
|
+
module Articles
|
242
|
+
class Show
|
243
|
+
include Lotus::View
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
Articles::Show.render({format: :html, article: article})
|
248
|
+
# => This will render "articles/show.html.haml"
|
249
|
+
```
|
250
|
+
|
251
|
+
This is the list of the supported engines.
|
252
|
+
They are listed in order of **higher precedence**, for a given extension.
|
253
|
+
For instance, if [ERubis](http://www.kuwata-lab.com/erubis/) is loaded, it will be preferred over ERb to render `.erb` templates.
|
254
|
+
|
255
|
+
<table>
|
256
|
+
<tr>
|
257
|
+
<th>Engine</th>
|
258
|
+
<th>Extensions</th>
|
259
|
+
</tr>
|
260
|
+
<tr>
|
261
|
+
<td>Erubis</td>
|
262
|
+
<td>erb, rhtml, erubis</td>
|
263
|
+
</tr>
|
264
|
+
<tr>
|
265
|
+
<td>ERb</td>
|
266
|
+
<td>erb, rhtml</td>
|
267
|
+
</tr>
|
268
|
+
<tr>
|
269
|
+
<td>Redcarpet</td>
|
270
|
+
<td>markdown, mkd, md</td>
|
271
|
+
</tr>
|
272
|
+
<tr>
|
273
|
+
<td>RDiscount</td>
|
274
|
+
<td>markdown, mkd, md</td>
|
275
|
+
</tr>
|
276
|
+
<tr>
|
277
|
+
<td>Kramdown</td>
|
278
|
+
<td>markdown, mkd, md</td>
|
279
|
+
</tr>
|
280
|
+
<tr>
|
281
|
+
<td>Maruku</td>
|
282
|
+
<td>markdown, mkd, md</td>
|
283
|
+
</tr>
|
284
|
+
<tr>
|
285
|
+
<td>BlueCloth</td>
|
286
|
+
<td>markdown, mkd, md</td>
|
287
|
+
</tr>
|
288
|
+
<tr>
|
289
|
+
<td>Asciidoctor</td>
|
290
|
+
<td>ad, adoc, asciidoc</td>
|
291
|
+
</tr>
|
292
|
+
<tr>
|
293
|
+
<td>Builder</td>
|
294
|
+
<td>builder</td>
|
295
|
+
</tr>
|
296
|
+
<tr>
|
297
|
+
<td>CSV</td>
|
298
|
+
<td>rcsv</td>
|
299
|
+
</tr>
|
300
|
+
<tr>
|
301
|
+
<td>CoffeeScript</td>
|
302
|
+
<td>coffee</td>
|
303
|
+
</tr>
|
304
|
+
<tr>
|
305
|
+
<td>WikiCloth</td>
|
306
|
+
<td>wiki, mediawiki, mw</td>
|
307
|
+
</tr>
|
308
|
+
<tr>
|
309
|
+
<td>Creole</td>
|
310
|
+
<td>wiki, creole</td>
|
311
|
+
</tr>
|
312
|
+
<tr>
|
313
|
+
<td>Etanni</td>
|
314
|
+
<td>etn, etanni</td>
|
315
|
+
</tr>
|
316
|
+
<tr>
|
317
|
+
<td>Haml</td>
|
318
|
+
<td>haml</td>
|
319
|
+
</tr>
|
320
|
+
<tr>
|
321
|
+
<td>Less</td>
|
322
|
+
<td>less</td>
|
323
|
+
</tr>
|
324
|
+
<tr>
|
325
|
+
<td>Liquid</td>
|
326
|
+
<td>liquid</td>
|
327
|
+
</tr>
|
328
|
+
<tr>
|
329
|
+
<td>Markaby</td>
|
330
|
+
<td>mab</td>
|
331
|
+
</tr>
|
332
|
+
<tr>
|
333
|
+
<td>Nokogiri</td>
|
334
|
+
<td>nokogiri</td>
|
335
|
+
</tr>
|
336
|
+
<tr>
|
337
|
+
<td>Plain</td>
|
338
|
+
<td>html</td>
|
339
|
+
</tr>
|
340
|
+
<tr>
|
341
|
+
<td>RDoc</td>
|
342
|
+
<td>rdoc</td>
|
343
|
+
</tr>
|
344
|
+
<tr>
|
345
|
+
<td>Radius</td>
|
346
|
+
<td>radius</td>
|
347
|
+
</tr>
|
348
|
+
<tr>
|
349
|
+
<td>RedCloth</td>
|
350
|
+
<td>textile</td>
|
351
|
+
</tr>
|
352
|
+
<tr>
|
353
|
+
<td>Sass</td>
|
354
|
+
<td>sass</td>
|
355
|
+
</tr>
|
356
|
+
<tr>
|
357
|
+
<td>Scss</td>
|
358
|
+
<td>scss</td>
|
359
|
+
</tr>
|
360
|
+
<tr>
|
361
|
+
<td>String</td>
|
362
|
+
<td>str</td>
|
363
|
+
</tr>
|
364
|
+
<tr>
|
365
|
+
<td>Yajl</td>
|
366
|
+
<td>yajl</td>
|
367
|
+
</tr>
|
368
|
+
</table>
|
369
|
+
|
370
|
+
### Root
|
371
|
+
|
372
|
+
Templates lookup is performed under the `Lotus::View.root` directory. Single views can specify a different path:
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
class ViewWithDifferentRoot
|
376
|
+
include Lotus::View
|
377
|
+
|
378
|
+
root 'path/to/root'
|
379
|
+
end
|
380
|
+
```
|
381
|
+
|
382
|
+
### Template
|
383
|
+
|
384
|
+
The template file must be located under the relevant `root` and must match the class name:
|
385
|
+
|
386
|
+
```ruby
|
387
|
+
puts Lotus::View.root # => #<Pathname:app/templates>
|
388
|
+
Articles::Index.template # => "articles/index"
|
389
|
+
```
|
390
|
+
|
391
|
+
Each view can specify a different template:
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
module Articles
|
395
|
+
class Create
|
396
|
+
include Lotus::View
|
397
|
+
|
398
|
+
template 'articles/new'
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
Articles::Index.template # => "articles/new"
|
403
|
+
```
|
404
|
+
|
405
|
+
### Partials
|
406
|
+
|
407
|
+
Partials can be rendered within a template:
|
408
|
+
|
409
|
+
```erb
|
410
|
+
<%= render partial: 'articles/form', locals: { secret: 23 } %>
|
411
|
+
```
|
412
|
+
|
413
|
+
It will look for a template `articles/_form.html.erb` and it will make available both the view's and partial's locals (eg. `article` and `secret`).
|
414
|
+
|
415
|
+
### Templates
|
416
|
+
|
417
|
+
Templates can be rendered within another template:
|
418
|
+
|
419
|
+
```erb
|
420
|
+
<%= render template: 'articles/new', locals: { errors: {} } %>
|
421
|
+
```
|
422
|
+
|
423
|
+
It will render `articles/new.html.erb` and it will make available both the view's and templates's locals (eg. `article` and `errors`).
|
424
|
+
|
425
|
+
### Layouts
|
426
|
+
|
427
|
+
Layouts are wrappers for views, they can be a way to reuse common markup.
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
class ApplicationLayout
|
431
|
+
include Lotus::Layout
|
432
|
+
|
433
|
+
def page_title
|
434
|
+
'Title:'
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
module Articles
|
439
|
+
class Index
|
440
|
+
include Lotus::View
|
441
|
+
layout :application
|
442
|
+
|
443
|
+
def page_title
|
444
|
+
"#{ layout.page_title } articles"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
class RssIndex < Index
|
449
|
+
format :rss
|
450
|
+
layout nil
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
Articles::Index.render(format: :html) # => Will use ApplicationLayout
|
455
|
+
Articles::Index.render(format: :rss) # => Will use nothing
|
456
|
+
```
|
457
|
+
|
458
|
+
As per convention, layouts' templates are located under `Lotus::View.root` or `ApplicationLayout.root` and they uses the underscored name (eg. `ApplicationLayout => application.html.erb`).
|
459
|
+
|
460
|
+
### Presenters
|
461
|
+
|
462
|
+
They are a way to wrap and reuse presentational logic for an object.
|
463
|
+
|
464
|
+
```ruby
|
465
|
+
class Map
|
466
|
+
attr_reader :locations
|
467
|
+
|
468
|
+
def initialize(locations)
|
469
|
+
@locations = locations
|
470
|
+
end
|
471
|
+
|
472
|
+
def location_names
|
473
|
+
@locations.join(', ')
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
class MapPresenter
|
478
|
+
include Lotus::Presenter
|
479
|
+
|
480
|
+
def count
|
481
|
+
locations.count
|
482
|
+
end
|
483
|
+
|
484
|
+
def location_names
|
485
|
+
super.upcase
|
486
|
+
end
|
487
|
+
|
488
|
+
def inspect_object
|
489
|
+
@object.inspect
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
map = Map.new(['Rome', 'Boston'])
|
494
|
+
presenter = MapPresenter.new(map)
|
495
|
+
|
496
|
+
# access a map method
|
497
|
+
puts presenter.locations # => ['Rome', 'Boston']
|
498
|
+
|
499
|
+
# access presenter concrete methods
|
500
|
+
puts presenter.count # => 1
|
501
|
+
|
502
|
+
# uses super to access original object implementation
|
503
|
+
puts presenter.location_names # => 'ROME, BOSTON'
|
504
|
+
|
505
|
+
# it has private access to the original object
|
506
|
+
puts presenter.inspect_object # => #<Map:0x007fdeada0b2f0 @locations=["Rome", "Boston"]>
|
507
|
+
```
|
508
|
+
|
509
|
+
### Thread safety
|
510
|
+
|
511
|
+
**Lotus::View**'s is thread safe during the runtime, but it isn't during the loading process.
|
512
|
+
Please load the framework as the last thing before your application starts.
|
513
|
+
Also, be sure that your app provides a thread safe context while it's loaded.
|
514
|
+
|
515
|
+
|
516
|
+
```ruby
|
517
|
+
Mutex.new.synchronize do
|
518
|
+
Lotus::View.load!
|
519
|
+
end
|
520
|
+
```
|
521
|
+
|
522
|
+
After this operation, all the class variables are frozen, in order to prevent accidental modifications at the run time.
|
523
|
+
|
524
|
+
**This is not necessary, when Lotus::View is used within a Lotus application.**
|
525
|
+
|
526
|
+
## Versioning
|
527
|
+
|
528
|
+
__Lotus::View__ uses [Semantic Versioning 2.0.0](http://semver.org)
|
22
529
|
|
23
530
|
## Contributing
|
24
531
|
|
25
|
-
1. Fork it
|
532
|
+
1. Fork it
|
26
533
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
534
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
535
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
536
|
5. Create new Pull Request
|
537
|
+
|
538
|
+
## Copyright
|
539
|
+
|
540
|
+
Copyright 2014 Luca Guidi – Released under MIT License
|
data/Rakefile
CHANGED
@@ -1 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.pattern = 'test/**/*_test.rb'
|
7
|
+
t.libs.push 'test'
|
8
|
+
end
|
9
|
+
|
10
|
+
namespace :test do
|
11
|
+
task :coverage do
|
12
|
+
ENV['COVERAGE'] = 'true'
|
13
|
+
Rake::Task['test'].invoke
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
task default: :test
|