templet 0.1.0 → 0.1.1
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/Gemfile.lock +1 -1
- data/README.md +44 -26
- data/lib/templet.rb +1 -1
- data/lib/templet/component.rb +2 -2
- data/lib/templet/component/partial.rb +5 -2
- data/lib/templet/component/template.rb +16 -0
- data/lib/templet/html.rb +0 -2
- data/lib/templet/html/table.rb +2 -2
- data/lib/templet/renderer.rb +1 -1
- data/lib/templet/renderers/erb.rb +52 -12
- data/lib/templet/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bc21aab645cc1952ee135c2086f2828d577214f
|
4
|
+
data.tar.gz: 4a94ac0f8fb7ad6a82ac0e673c51f76d3d34ea64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1291da062a0ba09b3c14780319b947ad252b36a3628b6be92c0e9beccbbeab733604b2a619e9ab49714f114e1e432ab30ad656a72f4e19c7481ee117098b2f07
|
7
|
+
data.tar.gz: 2042fc238a893d2e232575ae8d8f7af25931e716ed0fa2c1e6d4f809f38d2459cdca013ee2d67b621e00c4c2d0661fce9d192cebb7363136a69912e162913990
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -21,17 +21,20 @@ It has three main sections:
|
|
21
21
|
|
22
22
|
3. Helper methods for rendering HTML tables and lists.
|
23
23
|
|
24
|
-
_Incidentally,
|
24
|
+
_Incidentally, if such a need arises,
|
25
25
|
there is another renderer class, *Templet::Renderers::ERb*,
|
26
|
-
that you may use to insert markup inside of
|
26
|
+
that you may use to insert markup inside of a main ERb layout,
|
27
27
|
either on file or as a string._
|
28
28
|
|
29
|
+
> To load these classes you add the line: `require 'templet'`.
|
30
|
+
|
29
31
|
## The basic DSL (Renderer)
|
30
32
|
|
31
33
|
The DSL processing (i.e. HTML rendering) is handled by
|
32
34
|
the class, *Templet::Renderer*.
|
33
35
|
But don't expect anything earth-shattering,
|
34
36
|
as this class breaks no new ground.
|
37
|
+
|
35
38
|
It's as simple a DSL as you're likely to come across.
|
36
39
|
Also, there are a good few others that are similar,
|
37
40
|
e.g. XML Builder, Markaby, Arbre, and Fortitude.
|
@@ -83,12 +86,21 @@ But there's no need for you to embark on such a venture yourself,
|
|
83
86
|
as these things are implemented in the related gem:
|
84
87
|
[templet\_rails](https://github.com/srycyk/templet_rails).
|
85
88
|
|
89
|
+
> There is a third kind of component, *Templet::Component::Template*
|
90
|
+
> that renders an auxiliary ERb template, _(like a Rails partial)_.
|
91
|
+
> However, this experimental feature is inefficient and, besides,
|
92
|
+
> it merely regurgitates existing functionality that this gem
|
93
|
+
> sets out to replace!
|
94
|
+
> Having said this, there may be some *corner* cases where using this
|
95
|
+
> kind of Component will make sense.
|
96
|
+
> _This Component isn't explained here, but the tests outline usage._
|
97
|
+
|
86
98
|
## HTML Helpers
|
87
99
|
|
88
100
|
Some further classes are included (in the *templet/html/* sub-directory),
|
89
|
-
that provide a
|
90
|
-
|
91
|
-
|
101
|
+
that provide a short-hand way to render HTML lists and tables.
|
102
|
+
A stardard HTML list is generated from a given Ruby Array, similarly,
|
103
|
+
an HTML table (or definition list) is generated from a Ruby Hash.
|
92
104
|
|
93
105
|
Examples of using these are given towards the end.
|
94
106
|
|
@@ -99,7 +111,8 @@ it's best not to construct an instance of a *Renderer* explicitly,
|
|
99
111
|
even though this is illustrated in the examples which follow.
|
100
112
|
|
101
113
|
As noted, it's neater to use the *Renderer* implicitly,
|
102
|
-
that is, by means of a *Layout* containing a number of *Partials
|
114
|
+
that is, by means of a *Layout* containing a number of *Partials*,
|
115
|
+
which both contain an instance of a *Renderer*.
|
103
116
|
|
104
117
|
Still, it is useful to have a grounding in the basic rules and techniques,
|
105
118
|
as they apply to the Components as well.
|
@@ -171,26 +184,23 @@ require 'templet'
|
|
171
184
|
|
172
185
|
# The first two arguments are contexts for method lookups
|
173
186
|
#
|
174
|
-
# The final argument list local variables which take
|
187
|
+
# The final argument list local variables which take precedence
|
175
188
|
#
|
176
189
|
# The block renders the markup
|
177
190
|
# Note the shortcut call, this call is stated in full in the above example
|
178
191
|
html = Templet.(self, Lister.new, title: 'A Title') do
|
179
192
|
more_content = 'More content'
|
180
193
|
|
181
|
-
# +title+ is (in effect) a local variable passed into the
|
182
|
-
ctor
|
194
|
+
# +title+ is (in effect) a local variable passed into the constructor
|
183
195
|
[ -> { h1(title, :strong) }, # you can include anything callable
|
184
196
|
|
185
|
-
# Calls +items+ from Lister instance, given as a
|
186
|
-
ument
|
197
|
+
# Calls +items+ from Lister instance, given as a constructor argument
|
187
198
|
# The +_p+ call renders a <p> tag
|
188
199
|
# without the underscore the Kernel#p method would override
|
189
200
|
_p(ul(:list_unstyled) { items.map {|item| li item } }),
|
190
201
|
|
191
202
|
div(:row) do
|
192
|
-
# Calls +content+ because +self+ is passed into the
|
193
|
-
r
|
203
|
+
# Calls +content+ because +self+ is passed into the constructor
|
194
204
|
# +col_tag+ is a closure variable defined above
|
195
205
|
[ col_tag.(content), col_tag.(more_content), col_tag.('...')
|
196
206
|
]
|
@@ -224,15 +234,19 @@ This produces the following HTML:
|
|
224
234
|
|
225
235
|
## Notes on Usage
|
226
236
|
|
237
|
+
### Return Types
|
238
|
+
|
227
239
|
The main quirk is that the *Renderer* only outputs
|
228
240
|
the actual return value of a given block.
|
229
241
|
That is, statements preceding the very last one won't
|
230
242
|
show up in the resultant markup.
|
231
243
|
*This behaviour differs from that of most other markup API's.*
|
232
244
|
|
233
|
-
A block's return type must be either
|
234
|
-
|
235
|
-
|
245
|
+
A block's return type must be either strings or *callable* entities
|
246
|
+
(which themselves return one or more strings), or else an array of such.
|
247
|
+
If an array is returned, it can be nested to any depth (as it's flattened).
|
248
|
+
|
249
|
+
### Renderer Context
|
236
250
|
|
237
251
|
Importantly, the block, passed to *Renderer#call*, is **not**
|
238
252
|
executed in its natural local (i.e. lexical) scope.
|
@@ -244,8 +258,10 @@ as one of the initial arguments.
|
|
244
258
|
*To put this in more practical terms: be aware that if an error does occur,
|
245
259
|
its origin may be flagrantly misreported in the stack trace.*
|
246
260
|
|
261
|
+
### Further Guidance
|
262
|
+
|
247
263
|
The tests have more examples of usage,
|
248
|
-
also, the source code is easy to follow and is commented.
|
264
|
+
also, the source code is easy to follow and is liberally commented.
|
249
265
|
|
250
266
|
But don't dig too deep.
|
251
267
|
There's not a lot you need to learn to get started,
|
@@ -256,12 +272,12 @@ and you should be able to pick up the rest as you go along.
|
|
256
272
|
As said, Components facilitate a modular (object oriented) approach
|
257
273
|
to rendering markup.
|
258
274
|
|
259
|
-
You begin with a Layout,
|
275
|
+
You begin with a Layout, consists of a number of Partials.
|
260
276
|
|
261
|
-
There
|
277
|
+
There is often no need to have more than a single Layout,
|
262
278
|
since Partials can be nested inside one another.
|
263
279
|
|
264
|
-
|
280
|
+
They perform much the same function as their namesakes in Rails.
|
265
281
|
|
266
282
|
### Examples of a Layout with Partials
|
267
283
|
|
@@ -359,12 +375,10 @@ This produces the following HTML:
|
|
359
375
|
|
360
376
|
## Examples of Rendering HTML Composites
|
361
377
|
|
362
|
-
In
|
378
|
+
In the following examples, a **nil** value is passed to the constructor,
|
363
379
|
but in application code, this will be, in nearly all cases,
|
364
380
|
replaced by an instance of a *Renderer*.
|
365
381
|
|
366
|
-
> To load these claases you must add: `require 'templet/html'`.
|
367
|
-
|
368
382
|
### An Unordered List
|
369
383
|
|
370
384
|
```ruby
|
@@ -384,7 +398,7 @@ This produces the following HTML:
|
|
384
398
|
|
385
399
|
### A Definition List
|
386
400
|
|
387
|
-
In basic
|
401
|
+
In the most basic use, you pass in a Hash,
|
388
402
|
where the key is the title (the *dt* tag),
|
389
403
|
and the value is the data (the *dd* tag).
|
390
404
|
This is done as follows:
|
@@ -414,6 +428,7 @@ If a Symbol is given then it's used as a (Hash) key,
|
|
414
428
|
as in `record[key]`.
|
415
429
|
If a Proc is given then it's called with the
|
416
430
|
record passed as the first parameter, as in `func.call(record)`.
|
431
|
+
_Where *func* is the passed-in Proc_
|
417
432
|
|
418
433
|
```ruby
|
419
434
|
record = OpenStruct.new(field_1: 'Value 1', field_2: 'Value 2')
|
@@ -437,8 +452,8 @@ This produces the following HTML:
|
|
437
452
|
### A Table
|
438
453
|
|
439
454
|
To render an HTML table you pass to the *call* method,
|
440
|
-
a control Hash (as set out just above),
|
441
|
-
and a list of records, obviously,
|
455
|
+
a control Hash (as set out for the Definition List just above),
|
456
|
+
and a list of records which, obviously, map to a table row.
|
442
457
|
|
443
458
|
```ruby
|
444
459
|
controls = { 'Title 1' => nil, # shows the whole of the 'numbers' hash
|
@@ -526,6 +541,9 @@ Or install it yourself as:
|
|
526
541
|
$ gem install templet
|
527
542
|
```
|
528
543
|
|
544
|
+
Or get it from Github at
|
545
|
+
[github.com/srycyk/templet](https://github.com/srycyk/templet).
|
546
|
+
|
529
547
|
## Licence
|
530
548
|
|
531
549
|
The gem is available as open source under the terms
|
data/lib/templet.rb
CHANGED
data/lib/templet/component.rb
CHANGED
@@ -8,8 +8,11 @@ module Templet
|
|
8
8
|
# +contexts+:: A list containing objects whose methods will be looked up
|
9
9
|
# +locals+:: Objects you can reference by the name given as the key
|
10
10
|
def initialize(renderer, *contexts, **locals)
|
11
|
-
self.renderer = renderer
|
12
|
-
|
11
|
+
self.renderer = if renderer
|
12
|
+
renderer.new_instance(self, *contexts, **locals)
|
13
|
+
else
|
14
|
+
Renderer.new(self, *contexts, **locals)
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
18
|
# Entry point - the block returns markup
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module Templet
|
3
|
+
module Component
|
4
|
+
# Used for ERb support
|
5
|
+
class Template < Templet::Renderers::ERb
|
6
|
+
# +template+:: Given as string or file or at __END__
|
7
|
+
# +locals+:: Objects you can reference by the name given as the key
|
8
|
+
def initialize(renderer, template=nil, **locals)
|
9
|
+
self.proto_template = template
|
10
|
+
|
11
|
+
self.context = renderer.new_instance(self, **locals)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/templet/html.rb
CHANGED
data/lib/templet/html/table.rb
CHANGED
@@ -20,7 +20,7 @@ module Templet
|
|
20
20
|
if title.respond_to?(:call)
|
21
21
|
th title.(self, opaque_heading, opaque_row)
|
22
22
|
else
|
23
|
-
th heading(title)
|
23
|
+
th heading(title.to_s)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -56,7 +56,7 @@ module Templet
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def heading(title)
|
59
|
-
title[0] == '_' ? '' : title.capitalize
|
59
|
+
title[0] == '_' ? '' : title.capitalize.tr('_', ' ')
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
data/lib/templet/renderer.rb
CHANGED
@@ -6,38 +6,78 @@ module Templet
|
|
6
6
|
module Renderers
|
7
7
|
# For rendering a supplied block within an ERb template
|
8
8
|
class ERb
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :context, :proto_template
|
10
10
|
|
11
|
-
# template_path can be a local ERb file, or
|
11
|
+
# template_path can be a local ERb file, template string, or DATA append
|
12
12
|
#
|
13
13
|
# locals are local variables for the ERb template alone
|
14
|
-
def initialize(
|
15
|
-
self.
|
14
|
+
def initialize(proto_template=nil, **locals)
|
15
|
+
self.proto_template = proto_template
|
16
16
|
|
17
17
|
self.context = OpenStruct.new(**locals)
|
18
18
|
end
|
19
19
|
|
20
20
|
# The return value from the block in substituted in <%= yield %>
|
21
21
|
def call(&block)
|
22
|
-
|
22
|
+
context_binding = context.instance_eval { ::Kernel.binding }
|
23
23
|
|
24
|
-
erb.result
|
24
|
+
erb.result context_binding, &block
|
25
25
|
end
|
26
26
|
|
27
27
|
# Shortcut to instance method
|
28
|
-
def self.call(
|
29
|
-
new(
|
28
|
+
def self.call(template=nil, **locals, &block)
|
29
|
+
new(template, **locals).(&block)
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
34
|
+
def erb
|
35
|
+
@erb ||= ERB.new get_template
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_template
|
39
|
+
if proto_template
|
40
|
+
if proto_template =~ /(<%)|(\s\s)|(\n)/m
|
41
|
+
proto_template
|
42
|
+
else
|
43
|
+
IO.read proto_template
|
44
|
+
end
|
45
|
+
else
|
46
|
+
template or ''
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def template(read_from=false)
|
51
|
+
if read_from
|
52
|
+
call_stack = caller
|
53
|
+
|
54
|
+
read_erb(call_stack) or read_end(call_stack)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def read_erb(call_stack)
|
59
|
+
path = erb_path(call_stack)
|
60
|
+
|
61
|
+
IO.read(path) if File.file?(path)
|
62
|
+
end
|
63
|
+
|
64
|
+
def erb_path(call_stack)
|
65
|
+
source_path(call_stack, 0).sub(/\.rb$/, '.erb')
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_end(call_stack)
|
69
|
+
if defined? DATA
|
70
|
+
DATA.read
|
37
71
|
else
|
38
|
-
|
72
|
+
path = source_path(call_stack, 0)
|
73
|
+
|
74
|
+
IO.read(path).split(/\s__END__\s/, 2)&.last
|
39
75
|
end
|
40
76
|
end
|
77
|
+
|
78
|
+
def source_path(call_stack, index)
|
79
|
+
call_stack[index].split(":").first
|
80
|
+
end
|
41
81
|
end
|
42
82
|
end
|
43
83
|
end
|
data/lib/templet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: templet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stephen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/templet/component.rb
|
74
74
|
- lib/templet/component/layout.rb
|
75
75
|
- lib/templet/component/partial.rb
|
76
|
+
- lib/templet/component/template.rb
|
76
77
|
- lib/templet/html.rb
|
77
78
|
- lib/templet/html/definition_list.rb
|
78
79
|
- lib/templet/html/list.rb
|