superfluid 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
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +439 -49
- data/lib/superfluid/configuration.rb +26 -0
- data/lib/superfluid/environment.rb +40 -42
- data/lib/superfluid/filters/container.rb +34 -0
- data/lib/superfluid/registries/filter.rb +58 -37
- data/lib/superfluid/registries/tag.rb +34 -0
- data/lib/superfluid/renderer.rb +8 -2
- data/lib/superfluid/tags/container.rb +14 -0
- data/lib/superfluid.rb +1 -1
- data/superfluid.gemspec +4 -2
- data.tar.gz.sig +0 -0
- metadata +36 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5048f50c8bdaff6ed69041a2c0fac3deaf00c77df45031249f4afdb2b1543279
|
|
4
|
+
data.tar.gz: bd9a01bc4d9005f580e50970d9f3ba008ee0e3dc10ece706b8cc52a7a3120cef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 44aed258d521395ad2ec7352d26eda342f1262a56efdc3431f51a9f5ca59ed02601ae7d9a31cf72c2394d62c8cac7092a2d7e04228af63ed43d818db39928798
|
|
7
|
+
data.tar.gz: 4a08908b8979771fe0dfe4840990764f1bd1f4bd9b0a1ff744f50f6e887586da19202241bf7b1bd722ef3959fdff11f6f7388c330f3bd7ae959bbf2f6654eddb
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.adoc
CHANGED
|
@@ -3,19 +3,25 @@
|
|
|
3
3
|
:figure-caption!:
|
|
4
4
|
|
|
5
5
|
:command_pattern_link: link:https://alchemists.io/articles/command_pattern[Command Pattern]
|
|
6
|
+
:containable_link: link:https://alchemists.io/projects/containable[Containable]
|
|
6
7
|
:core_link: link:https://alchemists.io/projects/core[Core]
|
|
8
|
+
:functionable_link: link:https://alchemists.io/projects/functionable[Functionable]
|
|
7
9
|
:liquid_link: link:https://shopify.github.io/liquid/[Liquid]
|
|
8
|
-
:
|
|
10
|
+
:struct_link: link:https://alchemists.io/articles/ruby_structs[Struct]
|
|
9
11
|
|
|
10
12
|
= Superfluid
|
|
11
13
|
|
|
14
|
+
Enhances {liquid_link} by smoothing out the rough edges with a strong focus on object composition and functional design. This includes a fully functional filter and tag registry so you can reuse lower level filters and tags within all aspects of your view layer.
|
|
15
|
+
|
|
12
16
|
toc::[]
|
|
13
17
|
|
|
14
18
|
== Features
|
|
15
19
|
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
20
|
+
* Uses a customizable default environment with a cleaner Object API.
|
|
21
|
+
* Uses {containable_link} for filter and tag registries.
|
|
22
|
+
* Registers filters via a `Module`, {functionable_link}, commands (see {command_pattern_link} for details), or containers (see {containable_link} for details).
|
|
23
|
+
* Registers tags via classes or containers (see {containable_link} for details).
|
|
24
|
+
* Provides a default renderer for quick rendering of templates and associated data.
|
|
19
25
|
|
|
20
26
|
== Requirements
|
|
21
27
|
|
|
@@ -63,18 +69,47 @@ The quickest way to get started is to create a new instance:
|
|
|
63
69
|
renderer = Superfluid.new
|
|
64
70
|
----
|
|
65
71
|
|
|
66
|
-
|
|
72
|
+
Then you can render your template and associated data:
|
|
67
73
|
|
|
68
74
|
[source,ruby]
|
|
69
75
|
----
|
|
70
|
-
renderer.call "
|
|
76
|
+
renderer.call "Hi, this is a {{ value }}.", "value" => "demo"
|
|
71
77
|
----
|
|
72
78
|
|
|
73
79
|
The above will yield the following output:
|
|
74
80
|
|
|
75
81
|
----
|
|
76
|
-
"
|
|
82
|
+
"Hi, this is a demo."
|
|
83
|
+
----
|
|
84
|
+
|
|
85
|
+
The following sections detail how you can configure your environment, register filters, and register tags.
|
|
86
|
+
|
|
87
|
+
=== Configuration
|
|
88
|
+
|
|
89
|
+
The configuration is used by the environment. This is created for you automatically but if you want an instance of the default configuration, use:
|
|
90
|
+
|
|
91
|
+
[source,ruby]
|
|
77
92
|
----
|
|
93
|
+
configuration = Superfluid::Configuration.new
|
|
94
|
+
|
|
95
|
+
#<Struct:Superfluid::Configuration:0x00001780
|
|
96
|
+
default_resource_limits = {},
|
|
97
|
+
error_mode = :strict,
|
|
98
|
+
exception_renderer = #<Proc:0x0000000131200ee0 (lambda)>,
|
|
99
|
+
file_system = #<data Superfluid::Systems::Memory:0x000017b0 templates = {}>,
|
|
100
|
+
filter_registry = #<Superfluid::Registries::Filter:0x000000012f5a1290 @container=Superfluid::Filters::Container, @mode=:strict>,
|
|
101
|
+
tag_registry = #<Superfluid::Registries::Tag:0x000000012f5860d0 @container=Superfluid::Tags::Container>
|
|
102
|
+
>
|
|
103
|
+
----
|
|
104
|
+
|
|
105
|
+
As you can see, the configuration is a {struct_link} which means you can customize using any of these attributes:
|
|
106
|
+
|
|
107
|
+
* `default_resource_limits`: Limits the resources that a template can consume. Default: `{}`.
|
|
108
|
+
* `error_mode`: The error mode (link:https://github.com/Shopify/liquid#error-modes[details]). Default: `:strict`.
|
|
109
|
+
* `exception_renderer`: The function used to render error messages. Default: `Core::Identity` (see {core_link}).
|
|
110
|
+
* `file_system`: The file system. Default: `Superfluid::Systems::Memory.new`.
|
|
111
|
+
* `filter_registry`: The filter registry. Default: `Superfluid::Registries::Filter.new`.
|
|
112
|
+
* `tag_registry`: The tag registry. Default: `Superfluid::Registries::Tag.new`.
|
|
78
113
|
|
|
79
114
|
=== Environments
|
|
80
115
|
|
|
@@ -85,100 +120,455 @@ To build the default environment, use:
|
|
|
85
120
|
environment = Superfluid.build
|
|
86
121
|
----
|
|
87
122
|
|
|
88
|
-
|
|
123
|
+
To build the default environment directly (which is what the above does), use:
|
|
89
124
|
|
|
90
125
|
[source,ruby]
|
|
91
126
|
----
|
|
92
|
-
environment = Superfluid::Environment.
|
|
127
|
+
environment = Superfluid::Environment.new
|
|
93
128
|
----
|
|
94
129
|
|
|
95
|
-
|
|
130
|
+
If you'd like to build a custom environment, you can do this several ways. For demonstration purposes, only the `error_mode` is used below but all configuration attributes are accepted:
|
|
96
131
|
|
|
97
132
|
[source,ruby]
|
|
98
133
|
----
|
|
99
|
-
environment = Superfluid
|
|
134
|
+
environment = Superfluid.build error_mode: :lax
|
|
135
|
+
environment = Superfluid::Environment.for error_mode: :lax
|
|
136
|
+
environment = Superfluid::Environment.new Superfluid::Configuration[error_mode: :lax]
|
|
100
137
|
----
|
|
101
138
|
|
|
102
|
-
You can
|
|
139
|
+
You can also freeze the environment -- which also freezes the filter and tag registries -- once you've registered any/all filters and tags as follows:
|
|
103
140
|
|
|
104
141
|
[source,ruby]
|
|
105
142
|
----
|
|
106
143
|
environment.freeze
|
|
107
144
|
----
|
|
108
145
|
|
|
109
|
-
|
|
146
|
+
=== Filters
|
|
110
147
|
|
|
111
|
-
|
|
148
|
+
By default, {liquid_link} only allows registration of filters as instance methods on a namespace (`Module`). Unfortunately, this leads to terrible design, bad practices, and unnecessarily hard to test objects. You can still register namespaces but this gem encourages the use of commands (see {command_pattern_link} for further details) and containers via {containable_link} which allows you tap into Functional Programming by using procs, lambdas, and any object that responds to `#call`. This allows you to build -- and reuse -- more powerful filters. The following details the different kinds of filters you can use, each broken down by category.
|
|
112
149
|
|
|
113
|
-
|
|
114
|
-
* `error_mode`: The error mode. Default: `:strict`.
|
|
115
|
-
* `exception_renderer`: The exception renderer. Default: `Core::Identity` (see {core_link} for details).
|
|
116
|
-
* `file_system`: The file system. Default: `Superfluid::Systems::Memory.new`.
|
|
117
|
-
* `filter_registry`: The filter registry. Default: `Superfluid::Registries::Filter.new`.
|
|
118
|
-
* `tags`: The default tags. Default: `Liquid::Tags::STANDARD_TAGS`.
|
|
150
|
+
==== Defaults
|
|
119
151
|
|
|
120
|
-
|
|
152
|
+
Default filters are provided for you automatically and can be viewed via your environment. Example:
|
|
153
|
+
|
|
154
|
+
[source,ruby]
|
|
155
|
+
----
|
|
156
|
+
environment = Superfluid.build
|
|
157
|
+
environment.filter_registry.names
|
|
158
|
+
----
|
|
159
|
+
|
|
160
|
+
The above will produce a list of all registered filters. These including all filters provided by {liquid_link} and those unique to this gem which are:
|
|
161
|
+
|
|
162
|
+
*jsonify*
|
|
163
|
+
|
|
164
|
+
Renders objects as JSON. Example:
|
|
165
|
+
|
|
166
|
+
[source,ruby]
|
|
167
|
+
----
|
|
168
|
+
renderer.call(%({{ data | jsonify }}), {"data" => {"a" => 1}})
|
|
169
|
+
# "{\"a\":1}"
|
|
170
|
+
----
|
|
171
|
+
|
|
172
|
+
*parse_json*
|
|
173
|
+
|
|
174
|
+
Parses JSON as a primitive. Example:
|
|
175
|
+
|
|
176
|
+
[source,ruby]
|
|
177
|
+
----
|
|
178
|
+
renderer.call(
|
|
179
|
+
"{% assign data = payload | parse_json %}{{ data.one }}",
|
|
180
|
+
{"payload" => %({"one": 1, "two": 2})}
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# "1"
|
|
184
|
+
----
|
|
185
|
+
|
|
186
|
+
*pluralize*
|
|
187
|
+
|
|
188
|
+
Renders a plural string. Example:
|
|
189
|
+
|
|
190
|
+
[source,ruby]
|
|
191
|
+
----
|
|
192
|
+
renderer.call(%({{ text | pluralize: 0 }}), {"text" => "apple"})
|
|
193
|
+
# "0 apples"
|
|
194
|
+
|
|
195
|
+
renderer.call(%({{ text | pluralize: 1 }}), {"text" => "apple"})
|
|
196
|
+
# "1 apple"
|
|
197
|
+
|
|
198
|
+
renderer.call(%({{ text | pluralize: 2 }}), {"text" => "apple"})
|
|
199
|
+
# "2 apples"
|
|
200
|
+
|
|
201
|
+
renderer.call(%({{ text | pluralize: 3, "i", "us" }}), {"text" => "octopus"})
|
|
202
|
+
# "3 octopi"
|
|
203
|
+
----
|
|
204
|
+
|
|
205
|
+
*singularize*
|
|
206
|
+
|
|
207
|
+
Renders a singular string. Example:
|
|
208
|
+
|
|
209
|
+
[source,ruby]
|
|
210
|
+
----
|
|
211
|
+
renderer.call(%({{ text | singularize: 0 }}), {"text" => "apples"})
|
|
212
|
+
# "0 apples"
|
|
213
|
+
|
|
214
|
+
renderer.call(%({{ text | singularize: 1 }}), {"text" => "apples"})
|
|
215
|
+
# "1 apple"
|
|
216
|
+
|
|
217
|
+
renderer.call(%({{ text | singularize: 2 }}), {"text" => "apples"})
|
|
218
|
+
# "2 apples"
|
|
219
|
+
|
|
220
|
+
renderer.call(%({{ text | singularize: 1, "i", "us" }}), {"text" => "octopi"})
|
|
221
|
+
# "1 octopus"
|
|
222
|
+
----
|
|
223
|
+
|
|
224
|
+
*trim_end*
|
|
225
|
+
|
|
226
|
+
Renders string with trimmed end. Example:
|
|
227
|
+
|
|
228
|
+
[source,ruby]
|
|
229
|
+
----
|
|
230
|
+
renderer.call(%({{ text | trim_end: 10 }}), {"text" => "A demo."})
|
|
231
|
+
# "A demo."
|
|
232
|
+
|
|
233
|
+
renderer.call(%({{ text | trim_end: 10 }}), {"text" => "This is a demo."})
|
|
234
|
+
# "This is..."
|
|
235
|
+
|
|
236
|
+
renderer.call(%({{ text | trim_end: 10, "", "---" }}), {"text" => "This is a demo."})
|
|
237
|
+
# "This is---"
|
|
238
|
+
|
|
239
|
+
renderer.call(%({{ text | trim_end: 10, "", "" }}), {"text" => "This is a demo."})
|
|
240
|
+
# "This is a"
|
|
241
|
+
----
|
|
242
|
+
|
|
243
|
+
*trim_middle*
|
|
244
|
+
|
|
245
|
+
Renders string with trimmed middle. Example:
|
|
246
|
+
|
|
247
|
+
[source,ruby]
|
|
248
|
+
----
|
|
249
|
+
renderer.call(%({{ text | trim_middle: 20 }}), {"text" => "This is a demo."})
|
|
250
|
+
# "A demo."
|
|
251
|
+
|
|
252
|
+
renderer.call(%({{ text | trim_middle: 13 }}), {"text" => "This is a demo."})
|
|
253
|
+
# "This...demo."
|
|
254
|
+
|
|
255
|
+
renderer.call(%({{ text | trim_middle: 13, "--" }}), {"text" => "This is a demo."})
|
|
256
|
+
# "This--demo."
|
|
257
|
+
----
|
|
258
|
+
|
|
259
|
+
==== Modules
|
|
260
|
+
|
|
261
|
+
Module instance methods are what {liquid_link} supports by default. You only need to define instance methods within a module and then register your module. Example:
|
|
262
|
+
|
|
263
|
+
[source,ruby]
|
|
264
|
+
----
|
|
265
|
+
# Namespaces
|
|
266
|
+
module Primary
|
|
267
|
+
def echo(text) = text
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
module Secondary
|
|
271
|
+
def capitalize(text) = text.capitalize
|
|
272
|
+
|
|
273
|
+
def suffix(text, count = 1) = "#{text}-#{count}"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Renderer
|
|
277
|
+
renderer = Superfluid.new { it.register_filters Primary, Secondary }
|
|
278
|
+
|
|
279
|
+
# Results
|
|
280
|
+
renderer.call %({{ "demo" | echo }}) # "demo"
|
|
281
|
+
renderer.call %({{ "demo" | capitalize }}) # "Demo"
|
|
282
|
+
renderer.call %({{ "demo" | suffix }}) # "demo-1"
|
|
283
|
+
renderer.call %({{ "demo" | suffix: 2 }}) # "demo-2"
|
|
284
|
+
----
|
|
285
|
+
|
|
286
|
+
As you can see, all three methods via the two namespaces are properly registered and immediately available for use. You'll also notice multiple namespaces were registered at once but you can register them individually and/or chain them. Examples:
|
|
287
|
+
|
|
288
|
+
[source,ruby]
|
|
289
|
+
----
|
|
290
|
+
Superfluid.new do |environment|
|
|
291
|
+
# Single.
|
|
292
|
+
environment.register_filter Primary
|
|
293
|
+
|
|
294
|
+
# Multiple.
|
|
295
|
+
environment.register_filters Primary, Secondary
|
|
296
|
+
|
|
297
|
+
# Chained.
|
|
298
|
+
environment.register_filter(Primary)
|
|
299
|
+
.register_filter(Secondary)
|
|
300
|
+
.register_filters(Primary, Secondary)
|
|
301
|
+
end
|
|
302
|
+
----
|
|
303
|
+
|
|
304
|
+
==== Functionables
|
|
305
|
+
|
|
306
|
+
{functionable_link} modules are identical to the module examples, as shown above, except you require and extend instead. Example:
|
|
307
|
+
|
|
308
|
+
[source,ruby]
|
|
309
|
+
----
|
|
310
|
+
require "functionable"
|
|
311
|
+
|
|
312
|
+
# Namespaces
|
|
313
|
+
module Primary
|
|
314
|
+
extend Functionable
|
|
315
|
+
|
|
316
|
+
def echo(text) = text
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
module Secondary
|
|
320
|
+
extend Functionable
|
|
321
|
+
|
|
322
|
+
def capitalize(text) = text.capitalize
|
|
121
323
|
|
|
122
|
-
|
|
324
|
+
def suffix(text, count = 1) = "#{text}-#{count}"
|
|
325
|
+
end
|
|
326
|
+
----
|
|
327
|
+
|
|
328
|
+
This allows you to use purely functionable methods (see {functionable_link} documentation for details). At this point, you can register your functionable namespaces as follows:
|
|
329
|
+
|
|
330
|
+
[source,ruby]
|
|
331
|
+
----
|
|
332
|
+
# Renderer
|
|
333
|
+
renderer = Superfluid.new { it.register_filters Primary, Secondary }
|
|
334
|
+
|
|
335
|
+
# Results
|
|
336
|
+
renderer.call %({{ "demo" | echo }}) # "demo"
|
|
337
|
+
renderer.call %({{ "demo" | capitalize }}) # "Demo"
|
|
338
|
+
renderer.call %({{ "demo" | suffix }}) # "demo-1"
|
|
339
|
+
renderer.call %({{ "demo" | suffix: 2 }}) # "demo-2"
|
|
340
|
+
----
|
|
341
|
+
|
|
342
|
+
Registration is identical to modules:
|
|
343
|
+
|
|
344
|
+
[source,ruby]
|
|
345
|
+
----
|
|
346
|
+
Superfluid.new do |environment|
|
|
347
|
+
# Single.
|
|
348
|
+
environment.register_filter Primary
|
|
349
|
+
|
|
350
|
+
# Multiple.
|
|
351
|
+
environment.register_filters Primary, Secondary
|
|
352
|
+
|
|
353
|
+
# Chained.
|
|
354
|
+
environment.register_filter(Primary)
|
|
355
|
+
.register_filter(Secondary)
|
|
356
|
+
.register_filters(Primary, Secondary)
|
|
357
|
+
end
|
|
358
|
+
----
|
|
359
|
+
|
|
360
|
+
==== Procs and Lambdas
|
|
361
|
+
|
|
362
|
+
Procs and lambdas are not supported by {liquid_link} but are via this gem. Example:
|
|
363
|
+
|
|
364
|
+
[source,ruby]
|
|
365
|
+
----
|
|
366
|
+
# Setup
|
|
367
|
+
|
|
368
|
+
echo = proc { it }
|
|
369
|
+
capitalize = -> text { text.capitalize }
|
|
370
|
+
suffix = -> text, count = 1 { "#{text}-#{count}" }
|
|
371
|
+
|
|
372
|
+
# Renderer
|
|
373
|
+
renderer = Superfluid.new { it.register_filters echo:, capitalize:, suffix: }
|
|
374
|
+
|
|
375
|
+
# Results
|
|
376
|
+
|
|
377
|
+
renderer.call %({{ "demo" | echo }}) # "demo"
|
|
378
|
+
renderer.call %({{ "demo" | capitalize }}) # "Demo"
|
|
379
|
+
renderer.call %({{ "demo" | suffix }}) # "demo-1"
|
|
380
|
+
renderer.call %({{ "demo" | suffix: 2 }}) # "demo-2"
|
|
381
|
+
----
|
|
382
|
+
|
|
383
|
+
Registration can be singular, plural, or chained:
|
|
123
384
|
|
|
124
385
|
[source,ruby]
|
|
125
386
|
----
|
|
126
|
-
|
|
387
|
+
renderer = Superfluid.new do |environment|
|
|
388
|
+
# Single.
|
|
389
|
+
environment.register_filter(echo:)
|
|
127
390
|
|
|
128
|
-
|
|
129
|
-
|
|
391
|
+
# Multiple.
|
|
392
|
+
environment.register_filters(echo:, capitalize:, suffix:)
|
|
130
393
|
|
|
131
|
-
|
|
394
|
+
# Chained.
|
|
395
|
+
environment.register_filter(echo:)
|
|
396
|
+
.register_filter(capitalize:)
|
|
397
|
+
.register_filters(echo:, capitalize:, suffix:)
|
|
132
398
|
end
|
|
399
|
+
----
|
|
400
|
+
|
|
401
|
+
==== Classes
|
|
402
|
+
|
|
403
|
+
Classes, especially composable classes, are not supported by {liquid_link} but are via this gem. You only need to ensure you include `Core::Composable` and implement the `#call` method. Example:
|
|
404
|
+
|
|
405
|
+
[source,ruby]
|
|
406
|
+
----
|
|
407
|
+
require "core"
|
|
133
408
|
|
|
134
|
-
|
|
135
|
-
|
|
409
|
+
class Suffixer
|
|
410
|
+
include Core::Composable
|
|
136
411
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
@prefix = prefix
|
|
412
|
+
def initialize default: 1
|
|
413
|
+
@default = default
|
|
140
414
|
end
|
|
141
415
|
|
|
142
|
-
def call(
|
|
416
|
+
def call(text, suffix = default) = "#{text}-#{suffix}"
|
|
143
417
|
|
|
144
418
|
private
|
|
145
419
|
|
|
146
|
-
attr_reader :
|
|
420
|
+
attr_reader :default
|
|
147
421
|
end
|
|
422
|
+
----
|
|
423
|
+
|
|
424
|
+
Now you can register and render with the above class as follows:
|
|
425
|
+
|
|
426
|
+
[source,ruby]
|
|
427
|
+
----
|
|
428
|
+
# Renderer
|
|
429
|
+
renderer = Superfluid.new { it.register_filters suffix: Suffixer.new }
|
|
430
|
+
|
|
431
|
+
# Results
|
|
148
432
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
433
|
+
renderer.call %({{ "demo" | suffix }}) # "demo-1"
|
|
434
|
+
renderer.call %({{ "demo" | suffix: 2 }}) # "demo-2"
|
|
435
|
+
----
|
|
436
|
+
|
|
437
|
+
Registration can be singular, plural, or chained:
|
|
438
|
+
|
|
439
|
+
[source,ruby]
|
|
440
|
+
----
|
|
441
|
+
suffix = Suffixer.new
|
|
442
|
+
|
|
443
|
+
renderer = Superfluid.new do |environment|
|
|
444
|
+
# Single.
|
|
445
|
+
environment.register_filter(suffix:)
|
|
446
|
+
|
|
447
|
+
# Multiple.
|
|
448
|
+
environment.register_filters(suffix:)
|
|
449
|
+
|
|
450
|
+
# Chained.
|
|
451
|
+
environment.register_filter(suffix:)
|
|
452
|
+
.register_filters(suffix:)
|
|
153
453
|
end
|
|
154
454
|
----
|
|
155
455
|
|
|
156
|
-
|
|
456
|
+
==== Containers
|
|
457
|
+
|
|
458
|
+
Containers are not supported by {liquid_link} but are via this gem using {containable_link}. To use, create a container and then register your dependencies:
|
|
459
|
+
|
|
460
|
+
[source,ruby]
|
|
461
|
+
----
|
|
462
|
+
require "containable"
|
|
463
|
+
|
|
464
|
+
module Container
|
|
465
|
+
extend Containable
|
|
466
|
+
|
|
467
|
+
register(:echo) { |text| text }
|
|
468
|
+
register(:suffix) { |text, count = 1| "#{text}-#{count}" }
|
|
469
|
+
end
|
|
470
|
+
----
|
|
471
|
+
|
|
472
|
+
Now you can merge the container as follows:
|
|
473
|
+
|
|
474
|
+
[source,ruby]
|
|
475
|
+
----
|
|
476
|
+
renderer = Superfluid.new { it.merge_filters Container }
|
|
477
|
+
----
|
|
478
|
+
|
|
479
|
+
You can also selectively merge by supplying only the filters you care about from the container:
|
|
480
|
+
|
|
481
|
+
[source,ruby]
|
|
482
|
+
----
|
|
483
|
+
renderer = Superfluid.new { it.merge_filters Container, :suffix }
|
|
484
|
+
----
|
|
485
|
+
|
|
486
|
+
Once registered, then you can use as follows:
|
|
487
|
+
|
|
488
|
+
[source,ruby]
|
|
489
|
+
----
|
|
490
|
+
renderer.call %({{ "demo" | echo }}) # "demo"
|
|
491
|
+
renderer.call %({{ "demo" | suffix }}) # "demo-1"
|
|
492
|
+
renderer.call %({{ "demo" | suffix: 2 }}) # "demo-2"
|
|
493
|
+
----
|
|
494
|
+
|
|
495
|
+
With containers, you have the full capabilities of the {containable_link}. The above only scratches the surface of what's possible.
|
|
157
496
|
|
|
158
497
|
=== Tags
|
|
159
498
|
|
|
160
|
-
As per {liquid_link} documentation, tags only need to inherit from `Liquid::Tag` and be initialized with `tag_name`, `factor`, and `tokens
|
|
499
|
+
As per {liquid_link} documentation, tags only need to inherit from `Liquid::Tag` and be initialized with `tag_name`, `factor`, and `tokens` parameters. Then you can implement a render method which accepts a `context`. Example:
|
|
161
500
|
|
|
162
501
|
[source,ruby]
|
|
163
502
|
----
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
end
|
|
503
|
+
# Tag
|
|
504
|
+
class Sample < Liquid::Block
|
|
505
|
+
def render(context) = super.sub("<placeholder>", rand(100).to_s)
|
|
506
|
+
end
|
|
169
507
|
|
|
170
|
-
|
|
508
|
+
# Renderer
|
|
509
|
+
renderer = Superfluid.new { it.register_tag :sample, Sample }
|
|
171
510
|
|
|
172
|
-
|
|
511
|
+
# Results
|
|
512
|
+
renderer.call "{% sample %}Your value is: <placeholder>.{% endsample %}"
|
|
513
|
+
# "Your value is: 80."
|
|
514
|
+
----
|
|
173
515
|
|
|
174
|
-
|
|
516
|
+
You can also register single or multiple tags at once:
|
|
517
|
+
|
|
518
|
+
[source,ruby]
|
|
519
|
+
----
|
|
520
|
+
renderer = Superfluid.new do |environment|
|
|
521
|
+
# Single.
|
|
522
|
+
environment.register_tag(:sample, Sample)
|
|
523
|
+
|
|
524
|
+
# Multiple.
|
|
525
|
+
environment.register_tags(one: Sample, two: Sample)
|
|
526
|
+
|
|
527
|
+
# Chained.
|
|
528
|
+
environment.register_tag(:sample, Sample)
|
|
529
|
+
.register_tags(one: Sample, two: Sample)
|
|
175
530
|
end
|
|
531
|
+
----
|
|
532
|
+
|
|
533
|
+
==== Containers
|
|
176
534
|
|
|
177
|
-
|
|
178
|
-
|
|
535
|
+
Containers are not supported by {liquid_link} but are via this gem using {containable_link}. To use, create a container and then register your dependencies:
|
|
536
|
+
|
|
537
|
+
[source,ruby]
|
|
538
|
+
----
|
|
539
|
+
require "containable"
|
|
540
|
+
|
|
541
|
+
module Container
|
|
542
|
+
extend Containable
|
|
543
|
+
|
|
544
|
+
register :sample, Sample
|
|
179
545
|
end
|
|
180
546
|
----
|
|
181
547
|
|
|
548
|
+
Now you can merge the container as follows:
|
|
549
|
+
|
|
550
|
+
[source,ruby]
|
|
551
|
+
----
|
|
552
|
+
renderer = Superfluid.new { it.merge_tags Container }
|
|
553
|
+
----
|
|
554
|
+
|
|
555
|
+
You can also selectively merge by supplying only the tags you care about from the container:
|
|
556
|
+
|
|
557
|
+
[source,ruby]
|
|
558
|
+
----
|
|
559
|
+
renderer = Superfluid.new { it.merge_tags Container, :sample }
|
|
560
|
+
----
|
|
561
|
+
|
|
562
|
+
Once registered, then you can use as follows:
|
|
563
|
+
|
|
564
|
+
[source,ruby]
|
|
565
|
+
----
|
|
566
|
+
renderer.call "{% sample %}Your value is: <placeholder>.{% endsample %}"
|
|
567
|
+
# "Your value is: 85."
|
|
568
|
+
----
|
|
569
|
+
|
|
570
|
+
With containers, you have the full capabilities of the {containable_link}. The above only scratches the surface of what's possible.
|
|
571
|
+
|
|
182
572
|
== Development
|
|
183
573
|
|
|
184
574
|
To contribute, run:
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "core"
|
|
4
|
+
|
|
5
|
+
module Superfluid
|
|
6
|
+
# The default configuration.
|
|
7
|
+
Configuration = Struct.new(
|
|
8
|
+
:default_resource_limits,
|
|
9
|
+
:error_mode,
|
|
10
|
+
:exception_renderer,
|
|
11
|
+
:file_system,
|
|
12
|
+
:filter_registry,
|
|
13
|
+
:tag_registry
|
|
14
|
+
) do
|
|
15
|
+
def initialize(**)
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
self[:default_resource_limits] ||= Core::EMPTY_HASH
|
|
19
|
+
self[:error_mode] ||= :strict
|
|
20
|
+
self[:exception_renderer] ||= Core::Identity
|
|
21
|
+
self[:file_system] ||= Systems::Memory.new
|
|
22
|
+
self[:filter_registry] ||= Registries::Filter.new mode: error_mode
|
|
23
|
+
self[:tag_registry] ||= Registries::Tag.new
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,84 +1,82 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "core"
|
|
4
|
+
require "forwardable"
|
|
4
5
|
|
|
5
6
|
module Superfluid
|
|
6
|
-
# The default
|
|
7
|
-
Environment
|
|
8
|
-
|
|
9
|
-
:error_mode,
|
|
10
|
-
:exception_renderer,
|
|
11
|
-
:file_system,
|
|
12
|
-
:filter_registry,
|
|
13
|
-
:tags
|
|
14
|
-
) do
|
|
15
|
-
def self.for(**)
|
|
16
|
-
instance = new(**)
|
|
17
|
-
|
|
18
|
-
yield instance if block_given?
|
|
19
|
-
|
|
20
|
-
instance.freeze
|
|
21
|
-
end
|
|
7
|
+
# The default environment.
|
|
8
|
+
class Environment
|
|
9
|
+
extend Forwardable
|
|
22
10
|
|
|
23
11
|
def self.default
|
|
24
12
|
@default ||= new
|
|
25
13
|
end
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
delegate Configuration.members => :configuration
|
|
16
|
+
delegate Configuration.members.map { :"#{it}=" } => :configuration
|
|
29
17
|
|
|
30
|
-
|
|
31
|
-
self[:error_mode] ||= :strict
|
|
32
|
-
self[:exception_renderer] ||= Core::Identity
|
|
33
|
-
self[:file_system] ||= Systems::Memory.new
|
|
34
|
-
self[:filter_registry] ||= Registries::Filter.for mode: error_mode
|
|
35
|
-
self[:tags] ||= Liquid::Tags::STANDARD_TAGS.dup
|
|
18
|
+
def self.for(configuration = Configuration, **, &) = new(configuration[**], &)
|
|
36
19
|
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
def initialize configuration = Configuration.new
|
|
21
|
+
@configuration = configuration
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
namespace: Liquid::StandardFilters
|
|
43
|
-
return filter_registry if filters.empty?
|
|
23
|
+
yield self if block_given?
|
|
24
|
+
end
|
|
44
25
|
|
|
45
|
-
|
|
26
|
+
def create_filter_registry _context = nil, filters = Core::EMPTY_ARRAY
|
|
27
|
+
filters.empty? ? filter_registry : filter_registry.add(*filters)
|
|
46
28
|
end
|
|
47
29
|
|
|
48
|
-
|
|
30
|
+
alias create_strainer create_filter_registry
|
|
49
31
|
|
|
50
|
-
def filter_names = filter_registry.names
|
|
32
|
+
def filter_names = configuration.filter_registry.names
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
alias filter_method_names filter_names
|
|
53
35
|
|
|
54
|
-
def
|
|
55
|
-
|
|
56
|
-
|
|
36
|
+
def merge_filters(container, *)
|
|
37
|
+
filter_registry.merge(container, *)
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def merge_tags(container, *)
|
|
42
|
+
tag_registry.merge(container, *)
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def register_filter(*, **)
|
|
47
|
+
filter_registry.add(*, **)
|
|
57
48
|
self
|
|
58
49
|
end
|
|
59
50
|
|
|
60
51
|
def register_filters(*, **)
|
|
61
|
-
filters_cache.clear
|
|
62
52
|
filter_registry.add(*, **)
|
|
63
53
|
self
|
|
64
54
|
end
|
|
65
55
|
|
|
66
56
|
def register_tag name, klass
|
|
67
|
-
|
|
57
|
+
tag_registry.add name => klass
|
|
58
|
+
self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def register_tags(**)
|
|
62
|
+
tag_registry.add(**)
|
|
68
63
|
self
|
|
69
64
|
end
|
|
70
65
|
|
|
71
66
|
def find_tag(name) = tags[name.to_s]
|
|
72
67
|
|
|
73
|
-
|
|
68
|
+
alias tag_for_name find_tag
|
|
69
|
+
|
|
70
|
+
def tags = tag_registry.to_h
|
|
74
71
|
|
|
75
72
|
def freeze
|
|
76
|
-
|
|
73
|
+
filter_registry.freeze
|
|
74
|
+
tag_registry.freeze
|
|
77
75
|
super
|
|
78
76
|
end
|
|
79
77
|
|
|
80
78
|
private
|
|
81
79
|
|
|
82
|
-
attr_reader :
|
|
80
|
+
attr_reader :configuration
|
|
83
81
|
end
|
|
84
82
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "containable"
|
|
4
|
+
require "core"
|
|
5
|
+
require "json"
|
|
6
|
+
require "refinements/string"
|
|
7
|
+
|
|
8
|
+
module Superfluid
|
|
9
|
+
module Filters
|
|
10
|
+
# A container of filter dependencies.
|
|
11
|
+
module Container
|
|
12
|
+
extend Containable
|
|
13
|
+
|
|
14
|
+
using Refinements::String
|
|
15
|
+
|
|
16
|
+
register(:jsonify) { |value| JSON.generate value }
|
|
17
|
+
register(:parse_json) { |value| JSON.parse value }
|
|
18
|
+
|
|
19
|
+
register :pluralize do |value, count = 0, suffix = "s", replace = /$/|
|
|
20
|
+
"#{count} #{value.pluralize suffix, count, replace:}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
register :singularize do |value, count = 0, suffix = "s", replace = Core::EMPTY_STRING|
|
|
24
|
+
"#{count} #{value.singularize suffix, count, replace:}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
register :trim_end do |value, maximum, trailer = "..."|
|
|
28
|
+
value.trim_end maximum, nil, trailer:
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
register(:trim_middle) { |value, maximum, gap = "..."| value.trim_middle maximum, gap: }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "core"
|
|
4
|
+
require "functionable"
|
|
5
|
+
|
|
3
6
|
module Superfluid
|
|
4
7
|
module Registries
|
|
5
|
-
#
|
|
6
|
-
Filter
|
|
7
|
-
|
|
8
|
+
# The default filter registry.
|
|
9
|
+
class Filter
|
|
10
|
+
attr_reader :mode
|
|
11
|
+
|
|
12
|
+
def initialize container = Filters::Container,
|
|
13
|
+
defaults: Liquid::StandardFilters,
|
|
14
|
+
mode: :strict
|
|
15
|
+
@container = container
|
|
16
|
+
@mode = mode
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
super
|
|
18
|
+
add defaults
|
|
11
19
|
end
|
|
12
20
|
|
|
13
21
|
def add(*, **)
|
|
@@ -16,61 +24,74 @@ module Superfluid
|
|
|
16
24
|
self
|
|
17
25
|
end
|
|
18
26
|
|
|
27
|
+
def merge(other, *)
|
|
28
|
+
container.merge(other, *)
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
19
32
|
def call(name, *)
|
|
20
33
|
dispatch(name, *)
|
|
21
34
|
rescue ArgumentError => error
|
|
22
35
|
raise Liquid::ArgumentError, error.message, error.backtrace
|
|
23
36
|
end
|
|
24
37
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def clear
|
|
28
|
-
commands.clear
|
|
29
|
-
self
|
|
30
|
-
end
|
|
38
|
+
alias invoke call
|
|
31
39
|
|
|
32
|
-
def names =
|
|
40
|
+
def names = container.keys
|
|
33
41
|
|
|
34
42
|
private
|
|
35
43
|
|
|
36
|
-
|
|
44
|
+
attr_reader :container
|
|
45
|
+
|
|
46
|
+
def add_namespaces(*collection) = collection.each { add_methods it }
|
|
37
47
|
|
|
38
48
|
def add_methods namespace
|
|
49
|
+
# Order matters.
|
|
50
|
+
case namespace
|
|
51
|
+
in Class
|
|
52
|
+
fail Liquid::ArgumentError,
|
|
53
|
+
"Invalid type (#{namespace}) for namespace. Must be a Module or Functionable."
|
|
54
|
+
in Functionable then add_function_methods namespace
|
|
55
|
+
in Module then add_instance_methods namespace
|
|
56
|
+
# simplecov:disable
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def add_function_methods namespace
|
|
61
|
+
namespace.function_methods
|
|
62
|
+
.each
|
|
63
|
+
.with_object({}) { |name, all| all[name] = namespace.method name }
|
|
64
|
+
.then { add_commands(**it) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def add_instance_methods namespace
|
|
39
68
|
shadow = Class.new.include(namespace).new
|
|
40
69
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
collection = namespace.instance_methods
|
|
71
|
+
.each
|
|
72
|
+
.with_object({}) do |method, all|
|
|
73
|
+
name = method.name
|
|
74
|
+
all[name] = shadow.method name
|
|
75
|
+
end
|
|
47
76
|
|
|
48
|
-
add_commands(**
|
|
77
|
+
add_commands(**collection)
|
|
49
78
|
end
|
|
50
79
|
|
|
51
|
-
def add_commands(**
|
|
80
|
+
def add_commands(**collection) = collection.each { |name, command| add_command name, command }
|
|
52
81
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
key = name.to_s
|
|
82
|
+
def add_command name, callable
|
|
83
|
+
return if container.key? name
|
|
56
84
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
case function
|
|
60
|
-
in Proc | Method | Object if function.respond_to? :call then commands[key] = function
|
|
85
|
+
case callable
|
|
86
|
+
in Proc | Method | Core::Composable then container.register(name) { callable }
|
|
61
87
|
else fail Liquid::ArgumentError, "Filter must be callable."
|
|
62
88
|
end
|
|
63
89
|
end
|
|
64
90
|
|
|
65
|
-
def dispatch name, *
|
|
66
|
-
key
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
commands[key].call(*positionals)
|
|
70
|
-
elsif mode == :strict
|
|
71
|
-
fail Liquid::UndefinedFilter, "Undefined filter: #{name}."
|
|
72
|
-
else
|
|
73
|
-
positionals.first
|
|
91
|
+
def dispatch name, *arguments
|
|
92
|
+
if container.key? name then container[name].call(*arguments)
|
|
93
|
+
elsif mode == :strict then fail Liquid::UndefinedFilter, "Undefined filter: #{name}."
|
|
94
|
+
else arguments.first
|
|
74
95
|
end
|
|
75
96
|
end
|
|
76
97
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Superfluid
|
|
4
|
+
module Registries
|
|
5
|
+
# The default tag registry.
|
|
6
|
+
class Tag
|
|
7
|
+
def initialize container = Tags::Container, defaults: Liquid::Tags::STANDARD_TAGS
|
|
8
|
+
@container = container
|
|
9
|
+
|
|
10
|
+
add(**defaults)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add **collection
|
|
14
|
+
collection.each { |name, tag| container.register name, tag unless container.key? name }
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def merge(other, *)
|
|
19
|
+
container.merge(other, *)
|
|
20
|
+
self
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def get(name) = (container[name] if container.key? name)
|
|
24
|
+
|
|
25
|
+
def names = container.keys
|
|
26
|
+
|
|
27
|
+
def to_h = container.each.to_h
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
attr_reader :container
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/superfluid/renderer.rb
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "core"
|
|
4
|
+
|
|
3
5
|
module Superfluid
|
|
4
6
|
# Renders template and associated data.
|
|
5
7
|
class Renderer
|
|
6
|
-
def initialize environment: Environment.
|
|
8
|
+
def initialize environment: Environment.new, parser: Liquid::Template
|
|
7
9
|
@environment = environment
|
|
8
10
|
@parser = parser
|
|
11
|
+
|
|
12
|
+
yield environment if block_given?
|
|
13
|
+
|
|
14
|
+
environment.freeze
|
|
9
15
|
end
|
|
10
16
|
|
|
11
|
-
def call(template, data) = parser.parse(template, environment:).render data
|
|
17
|
+
def call(template, data = Core::EMPTY_HASH) = parser.parse(template, environment:).render data
|
|
12
18
|
|
|
13
19
|
private
|
|
14
20
|
|
data/lib/superfluid.rb
CHANGED
data/superfluid.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = "superfluid"
|
|
5
|
-
spec.version = "0.
|
|
5
|
+
spec.version = "0.1.0"
|
|
6
6
|
spec.authors = ["Brooke Kuhlmann"]
|
|
7
7
|
spec.email = ["brooke@alchemists.io"]
|
|
8
8
|
spec.homepage = "https://alchemists.io/projects/superfluid"
|
|
@@ -25,7 +25,9 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.required_ruby_version = ">= 4.0"
|
|
26
26
|
|
|
27
27
|
spec.add_dependency "base64", "~> 0.3"
|
|
28
|
-
spec.add_dependency "
|
|
28
|
+
spec.add_dependency "containable", "~> 2.5"
|
|
29
|
+
spec.add_dependency "core", "~> 3.4"
|
|
30
|
+
spec.add_dependency "functionable", "~> 1.4"
|
|
29
31
|
spec.add_dependency "liquid", "~> 5.13"
|
|
30
32
|
spec.add_dependency "refinements", "~> 14.0"
|
|
31
33
|
spec.add_dependency "zeitwerk", "~> 2.8"
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: superfluid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brooke Kuhlmann
|
|
@@ -49,20 +49,48 @@ dependencies:
|
|
|
49
49
|
- - "~>"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '0.3'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: containable
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - "~>"
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '2.5'
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - "~>"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '2.5'
|
|
52
66
|
- !ruby/object:Gem::Dependency
|
|
53
67
|
name: core
|
|
54
68
|
requirement: !ruby/object:Gem::Requirement
|
|
55
69
|
requirements:
|
|
56
70
|
- - "~>"
|
|
57
71
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '3.
|
|
72
|
+
version: '3.4'
|
|
73
|
+
type: :runtime
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3.4'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: functionable
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '1.4'
|
|
59
87
|
type: :runtime
|
|
60
88
|
prerelease: false
|
|
61
89
|
version_requirements: !ruby/object:Gem::Requirement
|
|
62
90
|
requirements:
|
|
63
91
|
- - "~>"
|
|
64
92
|
- !ruby/object:Gem::Version
|
|
65
|
-
version: '
|
|
93
|
+
version: '1.4'
|
|
66
94
|
- !ruby/object:Gem::Dependency
|
|
67
95
|
name: liquid
|
|
68
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -116,10 +144,14 @@ files:
|
|
|
116
144
|
- LICENSE.adoc
|
|
117
145
|
- README.adoc
|
|
118
146
|
- lib/superfluid.rb
|
|
147
|
+
- lib/superfluid/configuration.rb
|
|
119
148
|
- lib/superfluid/environment.rb
|
|
149
|
+
- lib/superfluid/filters/container.rb
|
|
120
150
|
- lib/superfluid/registries/filter.rb
|
|
151
|
+
- lib/superfluid/registries/tag.rb
|
|
121
152
|
- lib/superfluid/renderer.rb
|
|
122
153
|
- lib/superfluid/systems/memory.rb
|
|
154
|
+
- lib/superfluid/tags/container.rb
|
|
123
155
|
- lib/superfluid/tags/template.rb
|
|
124
156
|
- superfluid.gemspec
|
|
125
157
|
homepage: https://alchemists.io/projects/superfluid
|
|
@@ -147,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
147
179
|
- !ruby/object:Gem::Version
|
|
148
180
|
version: '0'
|
|
149
181
|
requirements: []
|
|
150
|
-
rubygems_version: 4.0.
|
|
182
|
+
rubygems_version: 4.0.20
|
|
151
183
|
specification_version: 4
|
|
152
184
|
summary: Enhances Liquid with object composition and functional design.
|
|
153
185
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|