rblade 0.5.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -38,7 +38,7 @@ module RBlade
38
38
  segments[i] << ";"
39
39
  end
40
40
 
41
- segments[i] = Token.new(type: :php, value: segments[i])
41
+ segments[i] = Token.new(type: :ruby, value: segments[i])
42
42
 
43
43
  i += 1
44
44
  elsif !segments[i].nil? && segments[i] != ""
@@ -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
- raise StandardError.new "Unhandled statement: @#{name}"
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.nil? || args.count > 2
18
- raise StandardError.new "Prepend statement: wrong number of arguments (given #{args&.count}, expecting 1 or 2)"
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
- if args.count == 2
22
- "RBlade::StackManager.prepend(#{args[0]}, #{args[1]});"
23
- else
24
- @push_counter += 1
21
+ @push_counter += 1
25
22
 
26
- "_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
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.nil? || args.count > 2
42
- raise StandardError.new "Push statement: wrong number of arguments (given #{args&.count}, expecting 1 or 2)"
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
- if args.count == 2
46
- "RBlade::StackManager.push(#{args[0]}, #{args[1]});"
47
- else
48
- @push_counter += 1
57
+ @push_counter += 1
49
58
 
50
- "_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
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
- @attributes.send(method, *)
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) || super
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
- self.class.new @attributes.slice(*keys)
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
- self.class.new @attributes.except(*keys)
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
- self.class.new new_attributes
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
@@ -16,6 +16,14 @@ module RBlade
16
16
  to_s
17
17
  end
18
18
 
19
+ def method_missing(method, *)
20
+ @content.send(method, *)
21
+ end
22
+
23
+ def respond_to_missing?(method_name, *args)
24
+ @content.respond_to?(method_name)
25
+ end
26
+
19
27
  def attributes
20
28
  @attributes
21
29
  end
data/rblade.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rblade"
3
- s.version = "0.5.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.5.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-07-30 00:00:00.000000000 Z
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.11
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
@@ -1,2 +0,0 @@
1
- Add @shouldRender? Or say you can use return (return _out) to exit early? @return? @exitComponent?
2
-