rubyoshka 0.4 → 0.5
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/CHANGELOG.md +7 -0
- data/README.md +21 -11
- data/lib/rubyoshka.rb +50 -14
- data/lib/rubyoshka/version.rb +1 -1
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aabb46d1744db33af049b11eec91a9e18a938aea5391ab2f22e41c0bccce77ae
|
4
|
+
data.tar.gz: 7d1a473f5c25ab35f38d0886dee156f2da38bce9306cb48a4e39e47d6d2e818d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5c43c9e8bb8f0b2a076a2a607ce3d735575748be1a6998dedb38ef795bfe3a8a33f2d3039c5ba379085b2750929966d4a9f41201651196dc2c1e5ea280c21c1
|
7
|
+
data.tar.gz: 120ad28457f4c3c1775de5d2b542d365a3abb5fdcdf01946097b251dd1830eaee7d2d6bc63bf1fe72c195073e80b9c2e4b3b0d9bddc2445c81c31d45aa9157a2
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -226,16 +226,17 @@ greeting.render(name: 'world')
|
|
226
226
|
## Templates as components
|
227
227
|
|
228
228
|
Rubyoshka makes it easy to compose multiple separate templates into a whole HTML
|
229
|
-
document. Each template can be defined as a self-contained component that can
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
returns a Rubyoshka instance:
|
229
|
+
document. Each template can be defined as a self-contained component that can be
|
230
|
+
reused inside other components. Components can be defined as either a Rubyoshka
|
231
|
+
instance (using `#H`), a `proc` that returns a Rubyoshka instance, or using
|
232
|
+
`Rubyoshka.component`:
|
234
233
|
|
235
234
|
```ruby
|
235
|
+
# Simple component relying on global/local context
|
236
236
|
Title = H { h1 title }
|
237
237
|
|
238
|
-
#
|
238
|
+
# Proc component that returns a template
|
239
|
+
# Notice how the lambda expression takes keyword arguments
|
239
240
|
Item = ->(id:, text:, checked:) {
|
240
241
|
H {
|
241
242
|
li {
|
@@ -245,20 +246,29 @@ Item = ->(id:, text:, checked:) {
|
|
245
246
|
}
|
246
247
|
}
|
247
248
|
|
248
|
-
|
249
|
+
# Components using Rubyoshka.component (or H.component) are a bit more compact.
|
250
|
+
# Any parameters are passed as arguments to the block.
|
251
|
+
NavBar = Rubyoshka.component do |links|
|
252
|
+
div {
|
253
|
+
links.each { |l| a l[:title], href: l[:url] }
|
254
|
+
}
|
255
|
+
end
|
256
|
+
|
257
|
+
def render_items(items, links)
|
249
258
|
html = H {
|
250
259
|
Title()
|
260
|
+
NavBar(links)
|
251
261
|
ul {
|
252
262
|
items.each { |id, attributes|
|
253
263
|
Item id: id, text: attributes[:text], checked: attributes[:active]
|
254
264
|
}
|
255
265
|
}
|
256
|
-
}.render
|
266
|
+
}.render(title: 'Hello from components')
|
257
267
|
end
|
258
268
|
```
|
259
269
|
|
260
270
|
Note that a component is invoked as a method, which means that if no arguments
|
261
|
-
are passed, you
|
271
|
+
are passed, you must add an empty pair of parens, as shown in the example
|
262
272
|
above.
|
263
273
|
|
264
274
|
In addition to using components defined as constants, you can also use
|
@@ -319,8 +329,8 @@ reused in multiple different templates in your app.
|
|
319
329
|
### Changing the cache store
|
320
330
|
|
321
331
|
Rubyoshka ships with a naïve in-memory cache store built-in. You can use
|
322
|
-
another cache store by overriding the `Rubyoshka.
|
323
|
-
|
332
|
+
another cache store by overriding the `Rubyoshka.cache` method (see API
|
333
|
+
[reference](#rubyoshkacache)).
|
324
334
|
|
325
335
|
## Wrapping arbitrary HTML with a component
|
326
336
|
|
data/lib/rubyoshka.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'modulation/gem'
|
4
3
|
require 'escape_utils'
|
5
4
|
|
6
|
-
export_default :Rubyoshka
|
7
|
-
|
8
5
|
# A Rubyoshka is a template representing a piece of HTML
|
9
6
|
class Rubyoshka
|
10
|
-
# A
|
11
|
-
class
|
7
|
+
# A Renderer is a rendering of a Rubyoshka
|
8
|
+
class Renderer
|
12
9
|
attr_reader :context
|
13
10
|
|
14
11
|
# Initializes attributes and renders the given block
|
@@ -27,8 +24,15 @@ class Rubyoshka
|
|
27
24
|
@buffer
|
28
25
|
end
|
29
26
|
|
30
|
-
|
31
|
-
|
27
|
+
def escape_text(text)
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
def escape_uri(uri)
|
32
|
+
EscapeUtils.escape_uri(v)
|
33
|
+
end
|
34
|
+
|
35
|
+
S_TAG_METHOD_LINE = __LINE__ + 1
|
32
36
|
S_TAG_METHOD = <<~EOF
|
33
37
|
S_TAG_%<TAG>s_PRE = '<%<tag>s'
|
34
38
|
S_TAG_%<TAG>s_CLOSE = '</%<tag>s>'
|
@@ -46,7 +50,7 @@ class Rubyoshka
|
|
46
50
|
emit(text)
|
47
51
|
@buffer << S_TAG_%<TAG>s_CLOSE
|
48
52
|
elsif text
|
49
|
-
@buffer << S_GT <<
|
53
|
+
@buffer << S_GT << escape_text(text.to_s) << S_TAG_%<TAG>s_CLOSE
|
50
54
|
else
|
51
55
|
@buffer << S_SLASH_GT
|
52
56
|
end
|
@@ -65,6 +69,7 @@ class Rubyoshka
|
|
65
69
|
return value if value
|
66
70
|
|
67
71
|
if sym =~ R_CONST_SYM
|
72
|
+
# Component reference (capitalized method name)
|
68
73
|
o = instance_eval(sym.to_s) rescue Rubyoshka.const_get(sym) \
|
69
74
|
rescue Object.const_get(sym)
|
70
75
|
case o
|
@@ -86,7 +91,8 @@ class Rubyoshka
|
|
86
91
|
end
|
87
92
|
else
|
88
93
|
tag = sym.to_s
|
89
|
-
|
94
|
+
code = S_TAG_METHOD % { tag: tag, TAG: tag.upcase }
|
95
|
+
self.class.class_eval(code, __FILE__, S_TAG_METHOD_LINE)
|
90
96
|
send(sym, *args, &block)
|
91
97
|
end
|
92
98
|
end
|
@@ -101,6 +107,7 @@ class Rubyoshka
|
|
101
107
|
when Rubyoshka
|
102
108
|
instance_eval(&o.block)
|
103
109
|
when Module
|
110
|
+
# If module is given, the component is expected to be a const inside the module
|
104
111
|
emit(o::Component)
|
105
112
|
when nil
|
106
113
|
else
|
@@ -126,7 +133,7 @@ class Rubyoshka
|
|
126
133
|
case k
|
127
134
|
when :src, :href
|
128
135
|
@buffer << S_SPACE << k.to_s << S_EQUAL_QUOTE <<
|
129
|
-
|
136
|
+
EscapeUtils.escape_uri(v) << S_QUOTE
|
130
137
|
else
|
131
138
|
case v
|
132
139
|
when true
|
@@ -140,7 +147,7 @@ class Rubyoshka
|
|
140
147
|
}
|
141
148
|
end
|
142
149
|
|
143
|
-
# Emits the p tag
|
150
|
+
# Emits the p tag (overrides Object#p)
|
144
151
|
# @param text [String] text content of tag
|
145
152
|
# @param props [Hash] tag attributes
|
146
153
|
# @para block [Proc] nested HTML block
|
@@ -162,7 +169,7 @@ class Rubyoshka
|
|
162
169
|
# Emits text into the rendering buffer
|
163
170
|
# @param data [String] text
|
164
171
|
def text(data)
|
165
|
-
@buffer <<
|
172
|
+
@buffer << escape_text(data)
|
166
173
|
end
|
167
174
|
|
168
175
|
# Sets a local context for the given block
|
@@ -195,13 +202,27 @@ class Rubyoshka
|
|
195
202
|
end
|
196
203
|
end
|
197
204
|
|
205
|
+
class HTMLRenderer < Renderer
|
206
|
+
def escape_text(text)
|
207
|
+
EscapeUtils.escape_html(text.to_s)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
class XMLRenderer < Renderer
|
213
|
+
def escape_text(text)
|
214
|
+
EscapeUtils.escape_xml(text.to_s)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
198
218
|
attr_reader :block
|
199
219
|
|
200
220
|
# Initializes a Rubyoshka with the given block
|
201
221
|
# @param ctx [Hash] local context
|
202
222
|
# @param block [Proc] nested HTML block
|
203
223
|
# @param [void]
|
204
|
-
def initialize(**ctx, &block)
|
224
|
+
def initialize(mode: :html, **ctx, &block)
|
225
|
+
@mode = mode
|
205
226
|
@block = ctx.empty? ? block : proc { with(ctx, &block) }
|
206
227
|
end
|
207
228
|
|
@@ -211,7 +232,18 @@ class Rubyoshka
|
|
211
232
|
# @param context [Hash] context
|
212
233
|
# @return [String]
|
213
234
|
def render(context = H_EMPTY)
|
214
|
-
|
235
|
+
renderer_class.new(context, &block).to_s
|
236
|
+
end
|
237
|
+
|
238
|
+
def renderer_class
|
239
|
+
case @mode
|
240
|
+
when :html
|
241
|
+
HTMLRenderer
|
242
|
+
when :xml
|
243
|
+
XMLRenderer
|
244
|
+
else
|
245
|
+
raise "Invalid mode #{@mode.inspect}"
|
246
|
+
end
|
215
247
|
end
|
216
248
|
|
217
249
|
@@cache = {}
|
@@ -219,6 +251,10 @@ class Rubyoshka
|
|
219
251
|
def self.cache
|
220
252
|
@@cache
|
221
253
|
end
|
254
|
+
|
255
|
+
def self.component(&block)
|
256
|
+
proc { |*args| new { instance_exec(*args, &block) } }
|
257
|
+
end
|
222
258
|
end
|
223
259
|
|
224
260
|
module ::Kernel
|
data/lib/rubyoshka/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyoshka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: modulation
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.18'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - '='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.18'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: escape_utils
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
115
|
- !ruby/object:Gem::Version
|
130
116
|
version: '0'
|
131
117
|
requirements: []
|
132
|
-
rubygems_version: 3.
|
118
|
+
rubygems_version: 3.1.4
|
133
119
|
signing_key:
|
134
120
|
specification_version: 4
|
135
121
|
summary: 'Rubyoshka: composable HTML templating for Ruby'
|