liquid 5.6.0 → 5.8.7
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/History.md +67 -2
- data/README.md +1 -1
- data/lib/liquid/context.rb +5 -1
- data/lib/liquid/expression.rb +97 -21
- data/lib/liquid/lexer.rb +69 -127
- data/lib/liquid/locales/en.yml +2 -0
- data/lib/liquid/parse_context.rb +25 -3
- data/lib/liquid/parser.rb +2 -2
- data/lib/liquid/range_lookup.rb +3 -3
- data/lib/liquid/standardfilters.rb +153 -61
- data/lib/liquid/tags/cycle.rb +7 -1
- data/lib/liquid/tags/decrement.rb +1 -1
- data/lib/liquid/tags/doc.rb +81 -0
- data/lib/liquid/tags/for.rb +1 -1
- data/lib/liquid/tags/if.rb +1 -1
- data/lib/liquid/tags/include.rb +1 -1
- data/lib/liquid/tags/increment.rb +1 -1
- data/lib/liquid/tags/render.rb +1 -1
- data/lib/liquid/tags.rb +2 -0
- data/lib/liquid/tokenizer.rb +129 -13
- data/lib/liquid/utils.rb +96 -0
- data/lib/liquid/variable.rb +3 -3
- data/lib/liquid/variable_lookup.rb +13 -5
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +4 -1
- metadata +6 -5
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'cgi'
|
4
4
|
require 'base64'
|
5
5
|
require 'bigdecimal'
|
6
|
-
|
7
6
|
module Liquid
|
8
7
|
module StandardFilters
|
9
8
|
MAX_I32 = (1 << 31) - 1
|
@@ -64,7 +63,7 @@ module Liquid
|
|
64
63
|
# @liquid_syntax string | downcase
|
65
64
|
# @liquid_return [string]
|
66
65
|
def downcase(input)
|
67
|
-
|
66
|
+
Utils.to_s(input).downcase
|
68
67
|
end
|
69
68
|
|
70
69
|
# @liquid_public_docs
|
@@ -75,7 +74,7 @@ module Liquid
|
|
75
74
|
# @liquid_syntax string | upcase
|
76
75
|
# @liquid_return [string]
|
77
76
|
def upcase(input)
|
78
|
-
|
77
|
+
Utils.to_s(input).upcase
|
79
78
|
end
|
80
79
|
|
81
80
|
# @liquid_public_docs
|
@@ -86,7 +85,7 @@ module Liquid
|
|
86
85
|
# @liquid_syntax string | capitalize
|
87
86
|
# @liquid_return [string]
|
88
87
|
def capitalize(input)
|
89
|
-
|
88
|
+
Utils.to_s(input).capitalize
|
90
89
|
end
|
91
90
|
|
92
91
|
# @liquid_public_docs
|
@@ -97,7 +96,7 @@ module Liquid
|
|
97
96
|
# @liquid_syntax string | escape
|
98
97
|
# @liquid_return [string]
|
99
98
|
def escape(input)
|
100
|
-
CGI.escapeHTML(
|
99
|
+
CGI.escapeHTML(Utils.to_s(input)) unless input.nil?
|
101
100
|
end
|
102
101
|
alias_method :h, :escape
|
103
102
|
|
@@ -109,7 +108,7 @@ module Liquid
|
|
109
108
|
# @liquid_syntax string | escape_once
|
110
109
|
# @liquid_return [string]
|
111
110
|
def escape_once(input)
|
112
|
-
|
111
|
+
Utils.to_s(input).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
113
112
|
end
|
114
113
|
|
115
114
|
# @liquid_public_docs
|
@@ -124,7 +123,7 @@ module Liquid
|
|
124
123
|
# @liquid_syntax string | url_encode
|
125
124
|
# @liquid_return [string]
|
126
125
|
def url_encode(input)
|
127
|
-
CGI.escape(
|
126
|
+
CGI.escape(Utils.to_s(input)) unless input.nil?
|
128
127
|
end
|
129
128
|
|
130
129
|
# @liquid_public_docs
|
@@ -138,7 +137,7 @@ module Liquid
|
|
138
137
|
def url_decode(input)
|
139
138
|
return if input.nil?
|
140
139
|
|
141
|
-
result = CGI.unescape(
|
140
|
+
result = CGI.unescape(Utils.to_s(input))
|
142
141
|
raise Liquid::ArgumentError, "invalid byte sequence in #{result.encoding}" unless result.valid_encoding?
|
143
142
|
|
144
143
|
result
|
@@ -152,7 +151,7 @@ module Liquid
|
|
152
151
|
# @liquid_syntax string | base64_encode
|
153
152
|
# @liquid_return [string]
|
154
153
|
def base64_encode(input)
|
155
|
-
Base64.strict_encode64(
|
154
|
+
Base64.strict_encode64(Utils.to_s(input))
|
156
155
|
end
|
157
156
|
|
158
157
|
# @liquid_public_docs
|
@@ -163,7 +162,7 @@ module Liquid
|
|
163
162
|
# @liquid_syntax string | base64_decode
|
164
163
|
# @liquid_return [string]
|
165
164
|
def base64_decode(input)
|
166
|
-
input =
|
165
|
+
input = Utils.to_s(input)
|
167
166
|
StandardFilters.try_coerce_encoding(Base64.strict_decode64(input), encoding: input.encoding)
|
168
167
|
rescue ::ArgumentError
|
169
168
|
raise Liquid::ArgumentError, "invalid base64 provided to base64_decode"
|
@@ -177,7 +176,7 @@ module Liquid
|
|
177
176
|
# @liquid_syntax string | base64_url_safe_encode
|
178
177
|
# @liquid_return [string]
|
179
178
|
def base64_url_safe_encode(input)
|
180
|
-
Base64.urlsafe_encode64(
|
179
|
+
Base64.urlsafe_encode64(Utils.to_s(input))
|
181
180
|
end
|
182
181
|
|
183
182
|
# @liquid_public_docs
|
@@ -188,7 +187,7 @@ module Liquid
|
|
188
187
|
# @liquid_syntax string | base64_url_safe_decode
|
189
188
|
# @liquid_return [string]
|
190
189
|
def base64_url_safe_decode(input)
|
191
|
-
input =
|
190
|
+
input = Utils.to_s(input)
|
192
191
|
StandardFilters.try_coerce_encoding(Base64.urlsafe_decode64(input), encoding: input.encoding)
|
193
192
|
rescue ::ArgumentError
|
194
193
|
raise Liquid::ArgumentError, "invalid base64 provided to base64_url_safe_decode"
|
@@ -212,7 +211,7 @@ module Liquid
|
|
212
211
|
if input.is_a?(Array)
|
213
212
|
input.slice(offset, length) || []
|
214
213
|
else
|
215
|
-
|
214
|
+
Utils.to_s(input).slice(offset, length) || ''
|
216
215
|
end
|
217
216
|
rescue RangeError
|
218
217
|
if I64_RANGE.cover?(length) && I64_RANGE.cover?(offset)
|
@@ -236,10 +235,10 @@ module Liquid
|
|
236
235
|
# @liquid_return [string]
|
237
236
|
def truncate(input, length = 50, truncate_string = "...")
|
238
237
|
return if input.nil?
|
239
|
-
input_str =
|
238
|
+
input_str = Utils.to_s(input)
|
240
239
|
length = Utils.to_integer(length)
|
241
240
|
|
242
|
-
truncate_string_str =
|
241
|
+
truncate_string_str = Utils.to_s(truncate_string)
|
243
242
|
|
244
243
|
l = length - truncate_string_str.length
|
245
244
|
l = 0 if l < 0
|
@@ -263,7 +262,7 @@ module Liquid
|
|
263
262
|
# @liquid_return [string]
|
264
263
|
def truncatewords(input, words = 15, truncate_string = "...")
|
265
264
|
return if input.nil?
|
266
|
-
input =
|
265
|
+
input = Utils.to_s(input)
|
267
266
|
words = Utils.to_integer(words)
|
268
267
|
words = 1 if words <= 0
|
269
268
|
|
@@ -277,7 +276,8 @@ module Liquid
|
|
277
276
|
return input if wordlist.length <= words
|
278
277
|
|
279
278
|
wordlist.pop
|
280
|
-
|
279
|
+
truncate_string = Utils.to_s(truncate_string)
|
280
|
+
wordlist.join(" ").concat(truncate_string)
|
281
281
|
end
|
282
282
|
|
283
283
|
# @liquid_public_docs
|
@@ -288,7 +288,9 @@ module Liquid
|
|
288
288
|
# @liquid_syntax string | split: string
|
289
289
|
# @liquid_return [array[string]]
|
290
290
|
def split(input, pattern)
|
291
|
-
|
291
|
+
pattern = Utils.to_s(pattern)
|
292
|
+
input = Utils.to_s(input)
|
293
|
+
input.split(pattern)
|
292
294
|
end
|
293
295
|
|
294
296
|
# @liquid_public_docs
|
@@ -299,7 +301,8 @@ module Liquid
|
|
299
301
|
# @liquid_syntax string | strip
|
300
302
|
# @liquid_return [string]
|
301
303
|
def strip(input)
|
302
|
-
input.to_s
|
304
|
+
input = Utils.to_s(input)
|
305
|
+
input.strip
|
303
306
|
end
|
304
307
|
|
305
308
|
# @liquid_public_docs
|
@@ -310,7 +313,8 @@ module Liquid
|
|
310
313
|
# @liquid_syntax string | lstrip
|
311
314
|
# @liquid_return [string]
|
312
315
|
def lstrip(input)
|
313
|
-
input.to_s
|
316
|
+
input = Utils.to_s(input)
|
317
|
+
input.lstrip
|
314
318
|
end
|
315
319
|
|
316
320
|
# @liquid_public_docs
|
@@ -321,7 +325,8 @@ module Liquid
|
|
321
325
|
# @liquid_syntax string | rstrip
|
322
326
|
# @liquid_return [string]
|
323
327
|
def rstrip(input)
|
324
|
-
input.to_s
|
328
|
+
input = Utils.to_s(input)
|
329
|
+
input.rstrip
|
325
330
|
end
|
326
331
|
|
327
332
|
# @liquid_public_docs
|
@@ -332,8 +337,9 @@ module Liquid
|
|
332
337
|
# @liquid_syntax string | strip_html
|
333
338
|
# @liquid_return [string]
|
334
339
|
def strip_html(input)
|
340
|
+
input = Utils.to_s(input)
|
335
341
|
empty = ''
|
336
|
-
result = input.
|
342
|
+
result = input.gsub(STRIP_HTML_BLOCKS, empty)
|
337
343
|
result.gsub!(STRIP_HTML_TAGS, empty)
|
338
344
|
result
|
339
345
|
end
|
@@ -346,7 +352,8 @@ module Liquid
|
|
346
352
|
# @liquid_syntax string | strip_newlines
|
347
353
|
# @liquid_return [string]
|
348
354
|
def strip_newlines(input)
|
349
|
-
input.to_s
|
355
|
+
input = Utils.to_s(input)
|
356
|
+
input.gsub(/\r?\n/, '')
|
350
357
|
end
|
351
358
|
|
352
359
|
# @liquid_public_docs
|
@@ -357,6 +364,7 @@ module Liquid
|
|
357
364
|
# @liquid_syntax array | join
|
358
365
|
# @liquid_return [string]
|
359
366
|
def join(input, glue = ' ')
|
367
|
+
glue = Utils.to_s(glue)
|
360
368
|
InputIterator.new(input, context).join(glue)
|
361
369
|
end
|
362
370
|
|
@@ -424,29 +432,59 @@ module Liquid
|
|
424
432
|
# @liquid_syntax array | where: string, string
|
425
433
|
# @liquid_return [array[untyped]]
|
426
434
|
def where(input, property, target_value = nil)
|
427
|
-
ary
|
435
|
+
filter_array(input, property, target_value) { |ary, &block| ary.select(&block) }
|
436
|
+
end
|
428
437
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
438
|
+
# @liquid_public_docs
|
439
|
+
# @liquid_type filter
|
440
|
+
# @liquid_category array
|
441
|
+
# @liquid_summary
|
442
|
+
# Filters an array to exclude items with a specific property value.
|
443
|
+
# @liquid_description
|
444
|
+
# This requires you to provide both the property name and the associated value.
|
445
|
+
# @liquid_syntax array | reject: string, string
|
446
|
+
# @liquid_return [array[untyped]]
|
447
|
+
def reject(input, property, target_value = nil)
|
448
|
+
filter_array(input, property, target_value) { |ary, &block| ary.reject(&block) }
|
449
|
+
end
|
450
|
+
|
451
|
+
# @liquid_public_docs
|
452
|
+
# @liquid_type filter
|
453
|
+
# @liquid_category array
|
454
|
+
# @liquid_summary
|
455
|
+
# Tests if any item in an array has a specific property value.
|
456
|
+
# @liquid_description
|
457
|
+
# This requires you to provide both the property name and the associated value.
|
458
|
+
# @liquid_syntax array | has: string, string
|
459
|
+
# @liquid_return [boolean]
|
460
|
+
def has(input, property, target_value = nil)
|
461
|
+
filter_array(input, property, target_value, false) { |ary, &block| ary.any?(&block) }
|
462
|
+
end
|
463
|
+
|
464
|
+
# @liquid_public_docs
|
465
|
+
# @liquid_type filter
|
466
|
+
# @liquid_category array
|
467
|
+
# @liquid_summary
|
468
|
+
# Returns the first item in an array with a specific property value.
|
469
|
+
# @liquid_description
|
470
|
+
# This requires you to provide both the property name and the associated value.
|
471
|
+
# @liquid_syntax array | find: string, string
|
472
|
+
# @liquid_return [untyped]
|
473
|
+
def find(input, property, target_value = nil)
|
474
|
+
filter_array(input, property, target_value, nil) { |ary, &block| ary.find(&block) }
|
475
|
+
end
|
476
|
+
|
477
|
+
# @liquid_public_docs
|
478
|
+
# @liquid_type filter
|
479
|
+
# @liquid_category array
|
480
|
+
# @liquid_summary
|
481
|
+
# Returns the index of the first item in an array with a specific property value.
|
482
|
+
# @liquid_description
|
483
|
+
# This requires you to provide both the property name and the associated value.
|
484
|
+
# @liquid_syntax array | find_index: string, string
|
485
|
+
# @liquid_return [number]
|
486
|
+
def find_index(input, property, target_value = nil)
|
487
|
+
filter_array(input, property, target_value, nil) { |ary, &block| ary.find_index(&block) }
|
450
488
|
end
|
451
489
|
|
452
490
|
# @liquid_public_docs
|
@@ -543,7 +581,10 @@ module Liquid
|
|
543
581
|
# @liquid_syntax string | replace: string, string
|
544
582
|
# @liquid_return [string]
|
545
583
|
def replace(input, string, replacement = '')
|
546
|
-
|
584
|
+
string = Utils.to_s(string)
|
585
|
+
replacement = Utils.to_s(replacement)
|
586
|
+
input = Utils.to_s(input)
|
587
|
+
input.gsub(string, replacement)
|
547
588
|
end
|
548
589
|
|
549
590
|
# @liquid_public_docs
|
@@ -554,7 +595,10 @@ module Liquid
|
|
554
595
|
# @liquid_syntax string | replace_first: string, string
|
555
596
|
# @liquid_return [string]
|
556
597
|
def replace_first(input, string, replacement = '')
|
557
|
-
|
598
|
+
string = Utils.to_s(string)
|
599
|
+
replacement = Utils.to_s(replacement)
|
600
|
+
input = Utils.to_s(input)
|
601
|
+
input.sub(string, replacement)
|
558
602
|
end
|
559
603
|
|
560
604
|
# @liquid_public_docs
|
@@ -565,9 +609,9 @@ module Liquid
|
|
565
609
|
# @liquid_syntax string | replace_last: string, string
|
566
610
|
# @liquid_return [string]
|
567
611
|
def replace_last(input, string, replacement)
|
568
|
-
input =
|
569
|
-
string =
|
570
|
-
replacement =
|
612
|
+
input = Utils.to_s(input)
|
613
|
+
string = Utils.to_s(string)
|
614
|
+
replacement = Utils.to_s(replacement)
|
571
615
|
|
572
616
|
start_index = input.rindex(string)
|
573
617
|
|
@@ -619,7 +663,9 @@ module Liquid
|
|
619
663
|
# @liquid_syntax string | append: string
|
620
664
|
# @liquid_return [string]
|
621
665
|
def append(input, string)
|
622
|
-
input
|
666
|
+
input = Utils.to_s(input)
|
667
|
+
string = Utils.to_s(string)
|
668
|
+
input + string
|
623
669
|
end
|
624
670
|
|
625
671
|
# @liquid_public_docs
|
@@ -648,7 +694,9 @@ module Liquid
|
|
648
694
|
# @liquid_syntax string | prepend: string
|
649
695
|
# @liquid_return [string]
|
650
696
|
def prepend(input, string)
|
651
|
-
|
697
|
+
input = Utils.to_s(input)
|
698
|
+
string = Utils.to_s(string)
|
699
|
+
string + input
|
652
700
|
end
|
653
701
|
|
654
702
|
# @liquid_public_docs
|
@@ -659,10 +707,20 @@ module Liquid
|
|
659
707
|
# @liquid_syntax string | newline_to_br
|
660
708
|
# @liquid_return [string]
|
661
709
|
def newline_to_br(input)
|
662
|
-
input.to_s
|
710
|
+
input = Utils.to_s(input)
|
711
|
+
input.gsub(/\r?\n/, "<br />\n")
|
663
712
|
end
|
664
713
|
|
665
|
-
#
|
714
|
+
# @liquid_public_docs
|
715
|
+
# @liquid_type filter
|
716
|
+
# @liquid_category date
|
717
|
+
# @liquid_summary
|
718
|
+
# Formats a date according to a specified format string.
|
719
|
+
# @liquid_description
|
720
|
+
# This filter formats a date using various format specifiers. If the format string is empty,
|
721
|
+
# the original input is returned. If the input cannot be converted to a date, the original input is returned.
|
722
|
+
#
|
723
|
+
# The following format specifiers can be used:
|
666
724
|
#
|
667
725
|
# %a - The abbreviated weekday name (``Sun'')
|
668
726
|
# %A - The full weekday name (``Sunday'')
|
@@ -691,14 +749,15 @@ module Liquid
|
|
691
749
|
# %Y - Year with century
|
692
750
|
# %Z - Time zone name
|
693
751
|
# %% - Literal ``%'' character
|
694
|
-
#
|
695
|
-
#
|
752
|
+
# @liquid_syntax date | date: string
|
753
|
+
# @liquid_return [string]
|
696
754
|
def date(input, format)
|
697
|
-
|
755
|
+
str_format = Utils.to_s(format)
|
756
|
+
return input if str_format.empty?
|
698
757
|
|
699
758
|
return input unless (date = Utils.to_date(input))
|
700
759
|
|
701
|
-
date.strftime(
|
760
|
+
date.strftime(str_format)
|
702
761
|
end
|
703
762
|
|
704
763
|
# @liquid_public_docs
|
@@ -918,8 +977,27 @@ module Liquid
|
|
918
977
|
|
919
978
|
attr_reader :context
|
920
979
|
|
980
|
+
def filter_array(input, property, target_value, default_value = [], &block)
|
981
|
+
ary = InputIterator.new(input, context)
|
982
|
+
|
983
|
+
return default_value if ary.empty?
|
984
|
+
|
985
|
+
block.call(ary) do |item|
|
986
|
+
if target_value.nil?
|
987
|
+
item[property]
|
988
|
+
else
|
989
|
+
item[property] == target_value
|
990
|
+
end
|
991
|
+
rescue TypeError
|
992
|
+
raise_property_error(property)
|
993
|
+
rescue NoMethodError
|
994
|
+
return nil unless item.respond_to?(:[])
|
995
|
+
raise
|
996
|
+
end
|
997
|
+
end
|
998
|
+
|
921
999
|
def raise_property_error(property)
|
922
|
-
raise Liquid::ArgumentError, "cannot select the property '#{property}'"
|
1000
|
+
raise Liquid::ArgumentError, "cannot select the property '#{Utils.to_s(property)}'"
|
923
1001
|
end
|
924
1002
|
|
925
1003
|
def apply_operation(input, operand, operation)
|
@@ -968,7 +1046,18 @@ module Liquid
|
|
968
1046
|
end
|
969
1047
|
|
970
1048
|
def join(glue)
|
971
|
-
|
1049
|
+
first = true
|
1050
|
+
output = +""
|
1051
|
+
each do |item|
|
1052
|
+
if first
|
1053
|
+
first = false
|
1054
|
+
else
|
1055
|
+
output << glue
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
output << Liquid::Utils.to_s(item)
|
1059
|
+
end
|
1060
|
+
output
|
972
1061
|
end
|
973
1062
|
|
974
1063
|
def concat(args)
|
@@ -980,7 +1069,10 @@ module Liquid
|
|
980
1069
|
end
|
981
1070
|
|
982
1071
|
def uniq(&block)
|
983
|
-
to_a.uniq
|
1072
|
+
to_a.uniq do |item|
|
1073
|
+
item = Utils.to_liquid_value(item)
|
1074
|
+
block ? yield(item) : item
|
1075
|
+
end
|
984
1076
|
end
|
985
1077
|
|
986
1078
|
def compact
|
data/lib/liquid/tags/cycle.rb
CHANGED
@@ -68,7 +68,13 @@ module Liquid
|
|
68
68
|
def variables_from_string(markup)
|
69
69
|
markup.split(',').collect do |var|
|
70
70
|
var =~ /\s*(#{QuotedFragment})\s*/o
|
71
|
-
|
71
|
+
next unless Regexp.last_match(1)
|
72
|
+
|
73
|
+
# Expression Parser returns cached objects, and we need to dup them to
|
74
|
+
# start the cycle over for each new cycle call.
|
75
|
+
# Liquid-C does not have a cache, so we don't need to dup the object.
|
76
|
+
var = parse_expression(Regexp.last_match(1))
|
77
|
+
var.is_a?(VariableLookup) ? var.dup : var
|
72
78
|
end.compact
|
73
79
|
end
|
74
80
|
|
@@ -10,7 +10,7 @@ module Liquid
|
|
10
10
|
# @liquid_description
|
11
11
|
# Variables that are declared with `decrement` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),
|
12
12
|
# or [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across
|
13
|
-
# [snippets](/themes/architecture
|
13
|
+
# [snippets](/themes/architecture/snippets) included in the file.
|
14
14
|
#
|
15
15
|
# Similarly, variables that are created with `decrement` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)
|
16
16
|
# and [`capture`](/docs/api/liquid/tags/capture). However, `decrement` and [`increment`](/docs/api/liquid/tags/increment) share
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Liquid
|
4
|
+
# @liquid_public_docs
|
5
|
+
# @liquid_type tag
|
6
|
+
# @liquid_category syntax
|
7
|
+
# @liquid_name doc
|
8
|
+
# @liquid_summary
|
9
|
+
# Documents template elements with annotations.
|
10
|
+
# @liquid_description
|
11
|
+
# The `doc` tag allows developers to include documentation within Liquid
|
12
|
+
# templates. Any content inside `doc` tags is not rendered or outputted.
|
13
|
+
# Liquid code inside will be parsed but not executed. This facilitates
|
14
|
+
# tooling support for features like code completion, linting, and inline
|
15
|
+
# documentation.
|
16
|
+
#
|
17
|
+
# For detailed documentation syntax and examples, see the
|
18
|
+
# [`LiquidDoc` reference](/docs/storefronts/themes/tools/liquid-doc).
|
19
|
+
#
|
20
|
+
# @liquid_syntax
|
21
|
+
# {% doc %}
|
22
|
+
# Renders a message.
|
23
|
+
#
|
24
|
+
# @param {string} foo - A string value.
|
25
|
+
# @param {string} [bar] - An optional string value.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# {% render 'message', foo: 'Hello', bar: 'World' %}
|
29
|
+
# {% enddoc %}
|
30
|
+
class Doc < Block
|
31
|
+
NO_UNEXPECTED_ARGS = /\A\s*\z/
|
32
|
+
|
33
|
+
def initialize(tag_name, markup, parse_context)
|
34
|
+
super
|
35
|
+
ensure_valid_markup(tag_name, markup, parse_context)
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse(tokens)
|
39
|
+
@body = +""
|
40
|
+
|
41
|
+
while (token = tokens.shift)
|
42
|
+
tag_name = token =~ BlockBody::FullTokenPossiblyInvalid && Regexp.last_match(2)
|
43
|
+
|
44
|
+
raise_nested_doc_error if tag_name == @tag_name
|
45
|
+
|
46
|
+
if tag_name == block_delimiter
|
47
|
+
parse_context.trim_whitespace = (token[-3] == WhitespaceControl)
|
48
|
+
@body << Regexp.last_match(1) if Regexp.last_match(1) != ""
|
49
|
+
return
|
50
|
+
end
|
51
|
+
@body << token unless token.empty?
|
52
|
+
end
|
53
|
+
|
54
|
+
raise_tag_never_closed(block_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def render_to_output_buffer(_context, output)
|
58
|
+
output
|
59
|
+
end
|
60
|
+
|
61
|
+
def blank?
|
62
|
+
@body.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def nodelist
|
66
|
+
[@body]
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def ensure_valid_markup(tag_name, markup, parse_context)
|
72
|
+
unless NO_UNEXPECTED_ARGS.match?(markup)
|
73
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.block_tag_unexpected_args", tag: tag_name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def raise_nested_doc_error
|
78
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.doc_invalid_nested")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/liquid/tags/for.rb
CHANGED
data/lib/liquid/tags/if.rb
CHANGED
data/lib/liquid/tags/include.rb
CHANGED
@@ -6,7 +6,7 @@ module Liquid
|
|
6
6
|
# @liquid_category theme
|
7
7
|
# @liquid_name include
|
8
8
|
# @liquid_summary
|
9
|
-
# Renders a [snippet](/themes/architecture
|
9
|
+
# Renders a [snippet](/themes/architecture/snippets).
|
10
10
|
# @liquid_description
|
11
11
|
# Inside the snippet, you can access and alter variables that are [created](/docs/api/liquid/tags/variable-tags) outside of the
|
12
12
|
# snippet.
|
@@ -10,7 +10,7 @@ module Liquid
|
|
10
10
|
# @liquid_description
|
11
11
|
# Variables that are declared with `increment` are unique to the [layout](/themes/architecture/layouts), [template](/themes/architecture/templates),
|
12
12
|
# or [section](/themes/architecture/sections) file that they're created in. However, the variable is shared across
|
13
|
-
# [snippets](/themes/architecture
|
13
|
+
# [snippets](/themes/architecture/snippets) included in the file.
|
14
14
|
#
|
15
15
|
# Similarly, variables that are created with `increment` are independent from those created with [`assign`](/docs/api/liquid/tags/assign)
|
16
16
|
# and [`capture`](/docs/api/liquid/tags/capture). However, `increment` and [`decrement`](/docs/api/liquid/tags/decrement) share
|
data/lib/liquid/tags/render.rb
CHANGED
@@ -6,7 +6,7 @@ module Liquid
|
|
6
6
|
# @liquid_category theme
|
7
7
|
# @liquid_name render
|
8
8
|
# @liquid_summary
|
9
|
-
# Renders a [snippet](/themes/architecture
|
9
|
+
# Renders a [snippet](/themes/architecture/snippets) or [app block](/themes/architecture/sections/section-schema#render-app-blocks).
|
10
10
|
# @liquid_description
|
11
11
|
# Inside snippets and app blocks, you can't directly access variables that are [created](/docs/api/liquid/tags/variable-tags) outside
|
12
12
|
# of the snippet or app block. However, you can [specify variables as parameters](/docs/api/liquid/tags/render#render-passing-variables-to-a-snippet)
|
data/lib/liquid/tags.rb
CHANGED
@@ -19,6 +19,7 @@ require_relative "tags/comment"
|
|
19
19
|
require_relative "tags/raw"
|
20
20
|
require_relative "tags/render"
|
21
21
|
require_relative "tags/cycle"
|
22
|
+
require_relative "tags/doc"
|
22
23
|
|
23
24
|
module Liquid
|
24
25
|
module Tags
|
@@ -42,6 +43,7 @@ module Liquid
|
|
42
43
|
'if' => If,
|
43
44
|
'echo' => Echo,
|
44
45
|
'tablerow' => TableRow,
|
46
|
+
'doc' => Doc,
|
45
47
|
}.freeze
|
46
48
|
end
|
47
49
|
end
|