liquid-render-tag 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +23 -0
- data/Rakefile +2 -0
- data/lib/liquid-render-tag.rb +20 -0
- data/lib/liquid-render-tag/block_body.rb +219 -0
- data/lib/liquid-render-tag/context.rb +261 -0
- data/lib/liquid-render-tag/partial_cache.rb +24 -0
- data/lib/liquid-render-tag/register.rb +6 -0
- data/lib/liquid-render-tag/registers/disabled_tags.rb +32 -0
- data/lib/liquid-render-tag/static_registers.rb +36 -0
- data/lib/liquid-render-tag/strainer_factory.rb +36 -0
- data/lib/liquid-render-tag/strainer_template.rb +53 -0
- data/lib/liquid-render-tag/tag.rb +73 -0
- data/lib/liquid-render-tag/tags/render.rb +84 -0
- data/lib/liquid-render-tag/template.rb +274 -0
- data/lib/liquid-render-tag/template_factory.rb +9 -0
- data/lib/liquid-render-tag/tokenizer.rb +39 -0
- data/lib/liquid-render-tag/variable.rb +170 -0
- data/lib/liquid-render-tag/version.rb +3 -0
- data/liquid-render-tag.gemspec +27 -0
- metadata +108 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Liquid
|
4
|
+
class Tokenizer
|
5
|
+
attr_reader :line_number, :for_liquid_tag
|
6
|
+
|
7
|
+
def initialize(source, line_numbers = false, line_number: nil, for_liquid_tag: false)
|
8
|
+
@source = source
|
9
|
+
@line_number = line_number || (line_numbers ? 1 : nil)
|
10
|
+
@for_liquid_tag = for_liquid_tag
|
11
|
+
@tokens = tokenize
|
12
|
+
end
|
13
|
+
|
14
|
+
def shift
|
15
|
+
(token = @tokens.shift) || return
|
16
|
+
|
17
|
+
if @line_number
|
18
|
+
@line_number += @for_liquid_tag ? 1 : token.count("\n")
|
19
|
+
end
|
20
|
+
|
21
|
+
token
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def tokenize
|
27
|
+
return [] if @source.to_s.empty?
|
28
|
+
|
29
|
+
return @source.split("\n") if @for_liquid_tag
|
30
|
+
|
31
|
+
tokens = @source.split(TemplateParser)
|
32
|
+
|
33
|
+
# removes the rogue empty element at the beginning of the array
|
34
|
+
tokens.shift if tokens[0]&.empty?
|
35
|
+
|
36
|
+
tokens
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Liquid
|
4
|
+
# Holds variables. Variables are only loaded "just in time"
|
5
|
+
# and are not evaluated as part of the render stage
|
6
|
+
#
|
7
|
+
# {{ monkey }}
|
8
|
+
# {{ user.name }}
|
9
|
+
#
|
10
|
+
# Variables can be combined with filters:
|
11
|
+
#
|
12
|
+
# {{ user | link }}
|
13
|
+
#
|
14
|
+
class Variable
|
15
|
+
FilterMarkupRegex = /#{FilterSeparator}\s*(.*)/om
|
16
|
+
FilterParser = /(?:\s+|#{QuotedFragment}|#{ArgumentSeparator})+/o
|
17
|
+
FilterArgsRegex = /(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o
|
18
|
+
JustTagAttributes = /\A#{TagAttributes}\z/o
|
19
|
+
MarkupWithQuotedFragment = /(#{QuotedFragment})(.*)/om
|
20
|
+
|
21
|
+
attr_accessor :filters, :name, :line_number
|
22
|
+
attr_reader :parse_context
|
23
|
+
alias_method :options, :parse_context
|
24
|
+
|
25
|
+
include ParserSwitching
|
26
|
+
|
27
|
+
def initialize(markup, parse_context)
|
28
|
+
@markup = markup
|
29
|
+
@name = nil
|
30
|
+
@parse_context = parse_context
|
31
|
+
@line_number = parse_context.line_number
|
32
|
+
|
33
|
+
parse_with_selected_parser(markup)
|
34
|
+
end
|
35
|
+
|
36
|
+
def raw
|
37
|
+
@markup
|
38
|
+
end
|
39
|
+
|
40
|
+
def markup_context(markup)
|
41
|
+
"in \"{{#{markup}}}\""
|
42
|
+
end
|
43
|
+
|
44
|
+
def lax_parse(markup)
|
45
|
+
@filters = []
|
46
|
+
return unless markup =~ MarkupWithQuotedFragment
|
47
|
+
|
48
|
+
name_markup = Regexp.last_match(1)
|
49
|
+
filter_markup = Regexp.last_match(2)
|
50
|
+
@name = Expression.parse(name_markup)
|
51
|
+
if filter_markup =~ FilterMarkupRegex
|
52
|
+
filters = Regexp.last_match(1).scan(FilterParser)
|
53
|
+
filters.each do |f|
|
54
|
+
next unless f =~ /\w+/
|
55
|
+
filtername = Regexp.last_match(0)
|
56
|
+
filterargs = f.scan(FilterArgsRegex).flatten
|
57
|
+
@filters << parse_filter_expressions(filtername, filterargs)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def strict_parse(markup)
|
63
|
+
@filters = []
|
64
|
+
p = Parser.new(markup)
|
65
|
+
|
66
|
+
@name = Expression.parse(p.expression)
|
67
|
+
while p.consume?(:pipe)
|
68
|
+
filtername = p.consume(:id)
|
69
|
+
filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
|
70
|
+
@filters << parse_filter_expressions(filtername, filterargs)
|
71
|
+
end
|
72
|
+
p.consume(:end_of_string)
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse_filterargs(p)
|
76
|
+
# first argument
|
77
|
+
filterargs = [p.argument]
|
78
|
+
# followed by comma separated others
|
79
|
+
filterargs << p.argument while p.consume?(:comma)
|
80
|
+
filterargs
|
81
|
+
end
|
82
|
+
|
83
|
+
def render(context)
|
84
|
+
obj = @filters.inject(context.evaluate(@name)) do |output, (filter_name, filter_args, filter_kwargs)|
|
85
|
+
filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
86
|
+
context.invoke(filter_name, output, *filter_args)
|
87
|
+
end
|
88
|
+
|
89
|
+
obj = context.apply_global_filter(obj)
|
90
|
+
taint_check(context, obj)
|
91
|
+
obj
|
92
|
+
end
|
93
|
+
|
94
|
+
def render_to_output_buffer(context, output)
|
95
|
+
obj = render(context)
|
96
|
+
|
97
|
+
if obj.is_a?(Array)
|
98
|
+
output << obj.join
|
99
|
+
elsif obj.nil?
|
100
|
+
else
|
101
|
+
output << obj.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
output
|
105
|
+
end
|
106
|
+
|
107
|
+
def disabled?(_context)
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
111
|
+
def disabled_tags
|
112
|
+
[]
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def parse_filter_expressions(filter_name, unparsed_args)
|
118
|
+
filter_args = []
|
119
|
+
keyword_args = nil
|
120
|
+
unparsed_args.each do |a|
|
121
|
+
if (matches = a.match(JustTagAttributes))
|
122
|
+
keyword_args ||= {}
|
123
|
+
keyword_args[matches[1]] = Expression.parse(matches[2])
|
124
|
+
else
|
125
|
+
filter_args << Expression.parse(a)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
result = [filter_name, filter_args]
|
129
|
+
result << keyword_args if keyword_args
|
130
|
+
result
|
131
|
+
end
|
132
|
+
|
133
|
+
def evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
134
|
+
parsed_args = filter_args.map { |expr| context.evaluate(expr) }
|
135
|
+
if filter_kwargs
|
136
|
+
parsed_kwargs = {}
|
137
|
+
filter_kwargs.each do |key, expr|
|
138
|
+
parsed_kwargs[key] = context.evaluate(expr)
|
139
|
+
end
|
140
|
+
parsed_args << parsed_kwargs
|
141
|
+
end
|
142
|
+
parsed_args
|
143
|
+
end
|
144
|
+
|
145
|
+
def taint_check(context, obj)
|
146
|
+
return if Template.taint_mode == :lax
|
147
|
+
return unless obj.tainted?
|
148
|
+
|
149
|
+
@markup =~ QuotedFragment
|
150
|
+
name = Regexp.last_match(0)
|
151
|
+
|
152
|
+
error = TaintedError.new("variable '#{name}' is tainted and was not escaped")
|
153
|
+
error.line_number = line_number
|
154
|
+
error.template_name = context.template_name
|
155
|
+
|
156
|
+
case Template.taint_mode
|
157
|
+
when :warn
|
158
|
+
context.warnings << error
|
159
|
+
when :error
|
160
|
+
raise error
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
165
|
+
def children
|
166
|
+
[@node.name] + @node.filters.flatten
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "liquid-render-tag/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "liquid-render-tag"
|
8
|
+
spec.version = LiquidRenderTag::VERSION
|
9
|
+
spec.authors = "Bridgetown Team"
|
10
|
+
spec.email = "maintainers@bridgetownrb.com"
|
11
|
+
|
12
|
+
spec.summary = %q{Backported Render tag and related changes from Liquid master to work with 4.0.3}
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = "https://github.com/bridgetownrb/liquid-render-tag"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
26
|
+
spec.add_development_dependency "liquid", "~> 4.0.3"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: liquid-render-tag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bridgetown Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: liquid
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.0.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.0.3
|
55
|
+
description: Backported Render tag and related changes from Liquid master to work
|
56
|
+
with 4.0.3
|
57
|
+
email: maintainers@bridgetownrb.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/liquid-render-tag.rb
|
68
|
+
- lib/liquid-render-tag/block_body.rb
|
69
|
+
- lib/liquid-render-tag/context.rb
|
70
|
+
- lib/liquid-render-tag/partial_cache.rb
|
71
|
+
- lib/liquid-render-tag/register.rb
|
72
|
+
- lib/liquid-render-tag/registers/disabled_tags.rb
|
73
|
+
- lib/liquid-render-tag/static_registers.rb
|
74
|
+
- lib/liquid-render-tag/strainer_factory.rb
|
75
|
+
- lib/liquid-render-tag/strainer_template.rb
|
76
|
+
- lib/liquid-render-tag/tag.rb
|
77
|
+
- lib/liquid-render-tag/tags/render.rb
|
78
|
+
- lib/liquid-render-tag/template.rb
|
79
|
+
- lib/liquid-render-tag/template_factory.rb
|
80
|
+
- lib/liquid-render-tag/tokenizer.rb
|
81
|
+
- lib/liquid-render-tag/variable.rb
|
82
|
+
- lib/liquid-render-tag/version.rb
|
83
|
+
- liquid-render-tag.gemspec
|
84
|
+
homepage: https://github.com/bridgetownrb/liquid-render-tag
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.0.6
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Backported Render tag and related changes from Liquid master to work with
|
107
|
+
4.0.3
|
108
|
+
test_files: []
|