rblade 0.5.0 → 0.6.1
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 +13 -1
- data/README.md +107 -502
- data/lib/rblade/compiler/compiles_components.rb +1 -1
- data/lib/rblade/compiler/compiles_ruby.rb +1 -1
- data/lib/rblade/compiler/compiles_statements.rb +21 -13
- data/lib/rblade/compiler/statements/compiles_conditionals.rb +40 -0
- data/lib/rblade/compiler/statements/compiles_form.rb +48 -0
- data/lib/rblade/compiler/statements/compiles_stacks.rb +39 -15
- data/lib/rblade/compiler/tokenizes_statements.rb +13 -2
- data/lib/rblade/component_store.rb +1 -1
- data/lib/rblade/helpers/attributes_manager.rb +30 -6
- data/lib/rblade/helpers/slot_manager.rb +8 -0
- data/rblade.gemspec +1 -1
- metadata +7 -7
- data/TODO.md +0 -2
@@ -73,7 +73,7 @@ module RBlade
|
|
73
73
|
|
74
74
|
def compile_component_end component
|
75
75
|
code = "_slot=RBlade::SlotManager.new(_out);_out=_c#{component[:index]}_swap;"
|
76
|
-
code << "_out<<#{ComponentStore.component(component[:name])}(_slot,_c#{component[:index]}_attr);"
|
76
|
+
code << "_out<<#{ComponentStore.component(component[:name])}(_slot,_c#{component[:index]}_attr,params,session,flash,cookies);"
|
77
77
|
code << "_slot=nil;_c#{component[:index]}_swap=nil;_c#{component[:index]}_attr=nil;"
|
78
78
|
|
79
79
|
code
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rblade/compiler/statements/compiles_conditionals"
|
2
|
+
require "rblade/compiler/statements/compiles_form"
|
2
3
|
require "rblade/compiler/statements/compiles_html_attributes"
|
3
4
|
require "rblade/compiler/statements/compiles_inline_ruby"
|
4
5
|
require "rblade/compiler/statements/compiles_loops"
|
@@ -48,7 +49,12 @@ module RBlade
|
|
48
49
|
handler_class, handler_method = @@statement_handlers[name.tr("_", "").downcase]
|
49
50
|
|
50
51
|
if !handler_class&.method_defined?(handler_method)
|
51
|
-
|
52
|
+
if name.start_with? "end"
|
53
|
+
## Fallback to the default end handler
|
54
|
+
handler_class, handler_method = @@statement_handlers["end"]
|
55
|
+
else
|
56
|
+
raise StandardError.new "Unhandled statement: @#{name}"
|
57
|
+
end
|
52
58
|
end
|
53
59
|
|
54
60
|
if handler_class == CompilesStatements
|
@@ -63,47 +69,49 @@ module RBlade
|
|
63
69
|
@@handler_instances = {}
|
64
70
|
|
65
71
|
@@statement_handlers = {
|
72
|
+
"blank?" => [CompilesConditionals, :compileBlank],
|
66
73
|
"break" => [CompilesLoops, :compileBreak],
|
67
74
|
"breakif" => [CompilesLoops, :compileBreakIf],
|
68
75
|
"case" => [CompilesConditionals, :compileCase],
|
69
76
|
"checked" => [CompilesConditionals, :compileChecked],
|
70
77
|
"class" => [CompilesHtmlAttributes, :compileClass],
|
78
|
+
"defined?" => [CompilesConditionals, :compileDefined],
|
79
|
+
"delete" => [CompilesForm, :compileDelete],
|
71
80
|
"disabled" => [CompilesConditionals, :compileDisabled],
|
72
81
|
"else" => [CompilesConditionals, :compileElse],
|
73
82
|
"elsif" => [CompilesConditionals, :compileElsif],
|
74
83
|
"each" => [CompilesLoops, :compileEach],
|
75
84
|
"eachelse" => [CompilesLoops, :compileEachElse],
|
76
85
|
"empty" => [CompilesLoops, :compileEmpty],
|
86
|
+
"empty?" => [CompilesConditionals, :compileEmpty],
|
77
87
|
"end" => [CompilesStatements, :compileEnd],
|
78
|
-
"endcase" => [CompilesStatements, :compileEnd],
|
79
|
-
"endeach" => [CompilesStatements, :compileEnd],
|
80
|
-
"endeachelse" => [CompilesStatements, :compileEnd],
|
81
|
-
"endenv" => [CompilesStatements, :compileEnd],
|
82
|
-
"endfor" => [CompilesStatements, :compileEnd],
|
83
|
-
"endforelse" => [CompilesStatements, :compileEnd],
|
84
|
-
"endif" => [CompilesStatements, :compileEnd],
|
85
|
-
"endonce" => [CompilesStatements, :compileEnd],
|
86
88
|
"endprepend" => [CompilesStacks, :compileEndPrepend],
|
89
|
+
"endprependif" => [CompilesStacks, :compileEndPrependIf],
|
87
90
|
"endprependonce" => [CompilesOnce, :compileEndPrependOnce],
|
88
|
-
"endproduction" => [CompilesStatements, :compileEnd],
|
89
91
|
"endpush" => [CompilesStacks, :compileEndPush],
|
92
|
+
"endpushif" => [CompilesStacks, :compileEndPushIf],
|
90
93
|
"endpushonce" => [CompilesOnce, :compileEndPushOnce],
|
91
|
-
"endunless" => [CompilesStatements, :compileEnd],
|
92
|
-
"enduntil" => [CompilesStatements, :compileEnd],
|
93
|
-
"endwhile" => [CompilesStatements, :compileEnd],
|
94
94
|
"env" => [CompilesConditionals, :compileEnv],
|
95
95
|
"for" => [CompilesLoops, :compileFor],
|
96
96
|
"forelse" => [CompilesLoops, :compileForElse],
|
97
97
|
"if" => [CompilesConditionals, :compileIf],
|
98
|
+
"method" => [CompilesForm, :compileMethod],
|
98
99
|
"next" => [CompilesLoops, :compileNext],
|
99
100
|
"nextif" => [CompilesLoops, :compileNextIf],
|
101
|
+
"nil?" => [CompilesConditionals, :compileNil],
|
102
|
+
"old" => [CompilesForm, :compileOld],
|
100
103
|
"once" => [CompilesOnce, :compileOnce],
|
104
|
+
"patch" => [CompilesForm, :compilePatch],
|
101
105
|
"prepend" => [CompilesStacks, :compilePrepend],
|
106
|
+
"prependif" => [CompilesStacks, :compilePrependIf],
|
102
107
|
"prependonce" => [CompilesOnce, :compilePrependOnce],
|
108
|
+
"present?" => [CompilesConditionals, :compilePresent],
|
103
109
|
"production" => [CompilesConditionals, :compileProduction],
|
104
110
|
"props" => [CompilesProps, :compileProps],
|
105
111
|
"push" => [CompilesStacks, :compilePush],
|
112
|
+
"pushif" => [CompilesStacks, :compilePushIf],
|
106
113
|
"pushonce" => [CompilesOnce, :compilePushOnce],
|
114
|
+
"put" => [CompilesForm, :compilePut],
|
107
115
|
"readonly" => [CompilesConditionals, :compileReadonly],
|
108
116
|
"required" => [CompilesConditionals, :compileRequired],
|
109
117
|
"ruby" => [CompilesInlineRuby, :compile],
|
@@ -9,6 +9,46 @@ module RBlade
|
|
9
9
|
"if #{args[0]};"
|
10
10
|
end
|
11
11
|
|
12
|
+
def compileBlank args
|
13
|
+
if args&.count != 1
|
14
|
+
raise StandardError.new "Blank? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
15
|
+
end
|
16
|
+
|
17
|
+
"if (#{args[0]}).blank?;"
|
18
|
+
end
|
19
|
+
|
20
|
+
def compileDefined args
|
21
|
+
if args&.count != 1
|
22
|
+
raise StandardError.new "Defined? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
23
|
+
end
|
24
|
+
|
25
|
+
"if defined? #{args[0]};"
|
26
|
+
end
|
27
|
+
|
28
|
+
def compileEmpty args
|
29
|
+
if args&.count != 1
|
30
|
+
raise StandardError.new "Empty? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
31
|
+
end
|
32
|
+
|
33
|
+
"if (#{args[0]}).empty?;"
|
34
|
+
end
|
35
|
+
|
36
|
+
def compileNil args
|
37
|
+
if args&.count != 1
|
38
|
+
raise StandardError.new "Nil? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
39
|
+
end
|
40
|
+
|
41
|
+
"if (#{args[0]}).nil?;"
|
42
|
+
end
|
43
|
+
|
44
|
+
def compilePresent args
|
45
|
+
if args&.count != 1
|
46
|
+
raise StandardError.new "Present? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
47
|
+
end
|
48
|
+
|
49
|
+
"if (#{args[0]}).present?;"
|
50
|
+
end
|
51
|
+
|
12
52
|
def compileElsif args
|
13
53
|
if args&.count != 1
|
14
54
|
raise StandardError.new "Elsif statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RBlade
|
2
|
+
class CompilesStatements
|
3
|
+
class CompilesForm
|
4
|
+
def compileMethod args
|
5
|
+
if args&.count != 1
|
6
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
7
|
+
end
|
8
|
+
method = RBlade.h(args[0].tr "\"'", "")
|
9
|
+
|
10
|
+
%[_out<<'<input type="hidden" name="_method" value="#{method}">';]
|
11
|
+
end
|
12
|
+
|
13
|
+
def compileDelete args
|
14
|
+
if !args.nil?
|
15
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
16
|
+
end
|
17
|
+
|
18
|
+
compileMethod(['DELETE'])
|
19
|
+
end
|
20
|
+
|
21
|
+
def compilePatch args
|
22
|
+
if !args.nil?
|
23
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
24
|
+
end
|
25
|
+
|
26
|
+
compileMethod(['PATCH'])
|
27
|
+
end
|
28
|
+
|
29
|
+
def compilePut args
|
30
|
+
if !args.nil?
|
31
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
32
|
+
end
|
33
|
+
|
34
|
+
compileMethod(['PUT'])
|
35
|
+
end
|
36
|
+
|
37
|
+
def compileOld args
|
38
|
+
if args.nil? || args.count > 2
|
39
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
40
|
+
end
|
41
|
+
|
42
|
+
default_value = args[1] || "''"
|
43
|
+
|
44
|
+
"_out<<params.fetch(#{args[0]},#{default_value});"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -14,17 +14,13 @@ module RBlade
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def compilePrepend args
|
17
|
-
if args
|
18
|
-
raise StandardError.new "Prepend statement: wrong number of arguments (given #{args&.count}, expecting 1
|
17
|
+
if args&.count != 1
|
18
|
+
raise StandardError.new "Prepend statement: wrong number of arguments (given #{args&.count}, expecting 1)"
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
"RBlade::StackManager.prepend(#{args[0]}, #{args[1]});"
|
23
|
-
else
|
24
|
-
@push_counter += 1
|
21
|
+
@push_counter += 1
|
25
22
|
|
26
|
-
|
27
|
-
end
|
23
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
28
24
|
end
|
29
25
|
|
30
26
|
def compileEndPrepend args
|
@@ -37,18 +33,38 @@ module RBlade
|
|
37
33
|
"RBlade::StackManager.prepend(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
38
34
|
end
|
39
35
|
|
36
|
+
def compilePrependIf args
|
37
|
+
if args&.count != 2
|
38
|
+
raise StandardError.new "Prepend if statement: wrong number of arguments (given #{args&.count}, expecting 2)"
|
39
|
+
end
|
40
|
+
|
41
|
+
"if #{args[0]};" + compilePrepend([args[1]])
|
42
|
+
end
|
43
|
+
|
44
|
+
def compileEndPrependIf args
|
45
|
+
if !args.nil?
|
46
|
+
raise StandardError.new "End push if statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
47
|
+
end
|
48
|
+
|
49
|
+
"end;" + compileEndPush(nil)
|
50
|
+
end
|
51
|
+
|
40
52
|
def compilePush args
|
41
|
-
if args
|
42
|
-
raise StandardError.new "Push statement: wrong number of arguments (given #{args&.count}, expecting 1
|
53
|
+
if args&.count != 1
|
54
|
+
raise StandardError.new "Push statement: wrong number of arguments (given #{args&.count}, expecting 1)"
|
43
55
|
end
|
44
56
|
|
45
|
-
|
46
|
-
"RBlade::StackManager.push(#{args[0]}, #{args[1]});"
|
47
|
-
else
|
48
|
-
@push_counter += 1
|
57
|
+
@push_counter += 1
|
49
58
|
|
50
|
-
|
59
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
60
|
+
end
|
61
|
+
|
62
|
+
def compilePushIf args
|
63
|
+
if args&.count != 2
|
64
|
+
raise StandardError.new "Push if statement: wrong number of arguments (given #{args&.count}, expecting 2)"
|
51
65
|
end
|
66
|
+
|
67
|
+
"if #{args[0]};" + compilePush([args[1]])
|
52
68
|
end
|
53
69
|
|
54
70
|
def compileEndPush args
|
@@ -60,6 +76,14 @@ module RBlade
|
|
60
76
|
|
61
77
|
"RBlade::StackManager.push(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
62
78
|
end
|
79
|
+
|
80
|
+
def compileEndPushIf args
|
81
|
+
if !args.nil?
|
82
|
+
raise StandardError.new "End push if statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
83
|
+
end
|
84
|
+
|
85
|
+
"end;" + compileEndPush(nil)
|
86
|
+
end
|
63
87
|
end
|
64
88
|
end
|
65
89
|
end
|
@@ -12,12 +12,12 @@ module RBlade
|
|
12
12
|
(?:
|
13
13
|
(?:
|
14
14
|
(@@)
|
15
|
-
(\w+(?!\w))
|
15
|
+
(\w+(?!\w)[!\?]?)
|
16
16
|
)
|
17
17
|
|
|
18
18
|
(?:
|
19
19
|
(@)
|
20
|
-
(\w+(?!\w))
|
20
|
+
(\w+(?!\w)[!\?]?)
|
21
21
|
(?:[ \t]*
|
22
22
|
(\(.*?\))
|
23
23
|
)?
|
@@ -45,6 +45,7 @@ module RBlade
|
|
45
45
|
i += 1
|
46
46
|
elsif segment == "@"
|
47
47
|
tokenizeStatement! segments, i
|
48
|
+
handleSpecialCases! segments, i
|
48
49
|
|
49
50
|
i += 1
|
50
51
|
elsif !segments[i].nil? && segments[i] != ""
|
@@ -74,6 +75,16 @@ module RBlade
|
|
74
75
|
segments[i] = Token.new(type: :statement, value: statement_data)
|
75
76
|
end
|
76
77
|
|
78
|
+
def handleSpecialCases!(segments, i)
|
79
|
+
case segments[i][:value][:name]
|
80
|
+
when "case"
|
81
|
+
# Remove any whitespace before a when statement
|
82
|
+
until segments[i + 1].nil? || segments[i + 1] == '@'
|
83
|
+
segments.delete_at i + 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
77
88
|
def tokenizeArguments!(segments, segment_index)
|
78
89
|
success = expandSegmentToEndParenthesis! segments, segment_index
|
79
90
|
|
@@ -81,7 +81,7 @@ module RBlade
|
|
81
81
|
compiled_component = RBlade::Compiler.compileString(code)
|
82
82
|
|
83
83
|
@@component_definitions \
|
84
|
-
<< "def #{@@component_method_names[name]}(slot,attributes);_out='';" \
|
84
|
+
<< "def #{@@component_method_names[name]}(slot,attributes,params,session,flash,cookies);_out='';" \
|
85
85
|
<< "_stacks=[];" \
|
86
86
|
<< "attributes=RBlade::AttributesManager.new(attributes);" \
|
87
87
|
<< compiled_component \
|
@@ -19,12 +19,16 @@ module RBlade
|
|
19
19
|
!@attributes[key].nil?
|
20
20
|
end
|
21
21
|
|
22
|
-
def method_missing(method,
|
23
|
-
|
22
|
+
def method_missing(method, *, &block)
|
23
|
+
if [:select, :filter, :slice].include? method
|
24
|
+
AttributesManager.new @attributes.send(method, *, &block)
|
25
|
+
else
|
26
|
+
@attributes.send(method, *, &block)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def respond_to_missing?(method_name, *args)
|
27
|
-
@attributes.respond_to?(method_name)
|
31
|
+
@attributes.respond_to?(method_name)
|
28
32
|
end
|
29
33
|
|
30
34
|
def to_s attributes = nil
|
@@ -46,7 +50,7 @@ module RBlade
|
|
46
50
|
[keys.to_sym]
|
47
51
|
end
|
48
52
|
|
49
|
-
|
53
|
+
AttributesManager.new @attributes.slice(*keys)
|
50
54
|
end
|
51
55
|
|
52
56
|
def except(keys)
|
@@ -56,7 +60,15 @@ module RBlade
|
|
56
60
|
[keys.to_sym]
|
57
61
|
end
|
58
62
|
|
59
|
-
|
63
|
+
AttributesManager.new @attributes.except(*keys)
|
64
|
+
end
|
65
|
+
|
66
|
+
def class(new_classes)
|
67
|
+
new_classes = ClassManager.new(new_classes).to_s
|
68
|
+
attributes = @attributes.dup
|
69
|
+
attributes[:class] = mergeClasses attributes[:class], new_classes
|
70
|
+
|
71
|
+
AttributesManager.new attributes
|
60
72
|
end
|
61
73
|
|
62
74
|
def merge(default_attributes)
|
@@ -76,7 +88,19 @@ module RBlade
|
|
76
88
|
new_attributes[key] = value
|
77
89
|
end
|
78
90
|
|
79
|
-
|
91
|
+
AttributesManager.new new_attributes
|
92
|
+
end
|
93
|
+
|
94
|
+
def has?(*keys)
|
95
|
+
keys.map!(&:to_sym)
|
96
|
+
|
97
|
+
keys.all? { |key| @attributes.has_key? key }
|
98
|
+
end
|
99
|
+
|
100
|
+
def has_any?(*keys)
|
101
|
+
keys.map!(&:to_sym)
|
102
|
+
|
103
|
+
keys.any? { |key| @attributes.has_key? key }
|
80
104
|
end
|
81
105
|
|
82
106
|
private
|
data/rblade.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rblade"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.6.1"
|
4
4
|
s.summary = "A component-first templating engine for Rails"
|
5
5
|
s.description = "RBlade is a simple, yet powerful templating engine for Ruby on Rails, inspired by Laravel Blade."
|
6
6
|
s.authors = ["Simon J"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rblade
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon J
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -80,7 +80,6 @@ files:
|
|
80
80
|
- LICENSE.md
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
|
-
- TODO.md
|
84
83
|
- do
|
85
84
|
- docker-compose.yml
|
86
85
|
- lib/rblade.rb
|
@@ -92,6 +91,7 @@ files:
|
|
92
91
|
- lib/rblade/compiler/compiles_statements.rb
|
93
92
|
- lib/rblade/compiler/compiles_verbatim.rb
|
94
93
|
- lib/rblade/compiler/statements/compiles_conditionals.rb
|
94
|
+
- lib/rblade/compiler/statements/compiles_form.rb
|
95
95
|
- lib/rblade/compiler/statements/compiles_html_attributes.rb
|
96
96
|
- lib/rblade/compiler/statements/compiles_inline_ruby.rb
|
97
97
|
- lib/rblade/compiler/statements/compiles_loops.rb
|
@@ -115,7 +115,7 @@ homepage: https://rubygems.org/gems/rblade
|
|
115
115
|
licenses:
|
116
116
|
- MIT
|
117
117
|
metadata: {}
|
118
|
-
post_install_message:
|
118
|
+
post_install_message:
|
119
119
|
rdoc_options: []
|
120
120
|
require_paths:
|
121
121
|
- lib
|
@@ -130,8 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
requirements: []
|
133
|
-
rubygems_version: 3.5
|
134
|
-
signing_key:
|
133
|
+
rubygems_version: 3.3.5
|
134
|
+
signing_key:
|
135
135
|
specification_version: 4
|
136
136
|
summary: A component-first templating engine for Rails
|
137
137
|
test_files: []
|
data/TODO.md
DELETED