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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5f53a3264d04846496a5fab85e4870ca1f1028b5
4
- data.tar.gz: 35f92da74584cca4bf699f0aff237b96f4772a69
3
+ metadata.gz: 7bc21aab645cc1952ee135c2086f2828d577214f
4
+ data.tar.gz: 4a94ac0f8fb7ad6a82ac0e673c51f76d3d34ea64
5
5
  SHA512:
6
- metadata.gz: c5c00ae7fc9c270c20986ec45c9fcfa601dbd64f3cf30ae711ef06192eb86ad4a83e85cf16c3402609b6677ece80db87efe3a68df02284ad0335263f2aacdc84
7
- data.tar.gz: 8290792806560547f80b385b7a95ac22003b262e4b23c033a1b130b27a714c8984846bba9546fd65fe8dfb5cc773dadd8f9aef02b77b929f1381841bb2659ca3
6
+ metadata.gz: 1291da062a0ba09b3c14780319b947ad252b36a3628b6be92c0e9beccbbeab733604b2a619e9ab49714f114e1e432ab30ad656a72f4e19c7481ee117098b2f07
7
+ data.tar.gz: 2042fc238a893d2e232575ae8d8f7af25931e716ed0fa2c1e6d4f809f38d2459cdca013ee2d67b621e00c4c2d0661fce9d192cebb7363136a69912e162913990
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- templet (0.1.0)
4
+ templet (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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, and if such a need arises,
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 an ERb layout,
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 shortened way to render HTML tables and lists.
90
- Their content is determined by a Ruby Hash or Array,
91
- which is given as input.
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 precendence
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 constru
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 contructor arg
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 contructo
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 an array of strings or of *callable*
234
- entities (which themselves return one or more strings).
235
- This array can be nested at any depth.
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, which, typically, contains a number of Partials.
275
+ You begin with a Layout, consists of a number of Partials.
260
276
 
261
- There's no need to have more than a single Layout,
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
- Together, they perform much the same function as their namesakes in Rails.
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 these examples, a *nil* value is passed to the constructor,
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 cases, you pass in a Hash,
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, with a table row for each record.
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
@@ -16,6 +16,6 @@ module Templet
16
16
  end
17
17
 
18
18
  def self.erb(template_path, **locals, &block)
19
- Renderers::Erb.(template_path, **locals, &block)
19
+ Renderers::ERb.(template_path, **locals, &block)
20
20
  end
21
21
  end
@@ -1,10 +1,10 @@
1
1
 
2
- require 'templet'
3
-
4
2
  require 'templet/component/partial'
5
3
  require 'templet/component/layout'
4
+ require 'templet/component/template'
6
5
 
7
6
  module Templet
8
7
  module Component
9
8
  end
10
9
  end
10
+
@@ -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&.new_instance(self, *contexts, **locals) ||
12
- Renderer.new(self, *contexts, **locals)
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
+
@@ -1,6 +1,4 @@
1
1
 
2
- require 'templet'
3
-
4
2
  require 'templet/html/table'
5
3
  require 'templet/html/list'
6
4
  require 'templet/html/definition_list'
@@ -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
@@ -27,7 +27,7 @@ module Templet
27
27
 
28
28
  # The block contains the markup
29
29
  def call(&block)
30
- Renderers::ListPresenter.new.(instance_eval &block)
30
+ Renderers::ListPresenter.new.(instance_eval(&block))
31
31
  end
32
32
 
33
33
  def method_missing(name, *args, &block)
@@ -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 :erb, :context
9
+ attr_accessor :context, :proto_template
10
10
 
11
- # template_path can be a local ERb file, or template text
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(template, **locals)
15
- self.erb = ERB.new get_template(template)
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
- locals_binding = context.instance_eval { binding }
22
+ context_binding = context.instance_eval { ::Kernel.binding }
23
23
 
24
- erb.result locals_binding, &block
24
+ erb.result context_binding, &block
25
25
  end
26
26
 
27
27
  # Shortcut to instance method
28
- def self.call(template_path, **locals, &block)
29
- new(template_path, **locals).(&block)
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 get_template(template)
35
- if template =~ /<%/
36
- template
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
- IO.read template
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
@@ -1,3 +1,3 @@
1
1
  module Templet
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
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.0
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: 2018-11-28 00:00:00.000000000 Z
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