rubyoshka 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|