rblade 2.0.2 → 3.0.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
- data/.rubocop.yml +24 -0
- data/CHANGELOG.md +11 -0
- data/README.md +83 -16
- data/REFERENCE.md +4 -2
- data/do +4 -4
- data/docker-compose.yml +4 -1
- data/lib/rblade/compiler/compiles_comments.rb +2 -2
- data/lib/rblade/compiler/compiles_components.rb +26 -5
- data/lib/rblade/compiler/compiles_injections.rb +81 -0
- data/lib/rblade/compiler/compiles_statements.rb +69 -64
- data/lib/rblade/compiler/compiles_verbatim.rb +1 -1
- data/lib/rblade/compiler/statements/compiles_component_helpers.rb +17 -13
- data/lib/rblade/compiler/statements/compiles_conditionals.rb +18 -18
- data/lib/rblade/compiler/statements/compiles_form.rb +8 -8
- data/lib/rblade/compiler/statements/compiles_html_attributes.rb +2 -2
- data/lib/rblade/compiler/statements/compiles_inline_ruby.rb +1 -1
- data/lib/rblade/compiler/statements/compiles_loops.rb +11 -11
- data/lib/rblade/compiler/statements/compiles_once.rb +3 -3
- data/lib/rblade/compiler/statements/compiles_stacks.rb +5 -5
- data/lib/rblade/compiler/tokenizes_components.rb +30 -31
- data/lib/rblade/compiler/tokenizes_statements.rb +29 -30
- data/lib/rblade/compiler.rb +20 -19
- data/lib/rblade/component_store.rb +20 -20
- data/lib/rblade/helpers/attributes_manager.rb +10 -9
- data/lib/rblade/helpers/class_manager.rb +1 -1
- data/lib/rblade/helpers/slot_manager.rb +2 -2
- data/lib/rblade/helpers/stack_manager.rb +3 -3
- data/lib/rblade/helpers/style_manager.rb +1 -1
- data/lib/rblade/helpers/tokenizer.rb +5 -5
- data/lib/rblade/rails_template.rb +9 -2
- data/lib/rblade/railtie.rb +34 -2
- data/rblade.gemspec +4 -1
- metadata +50 -8
- data/lib/rblade/compiler/compiles_prints.rb +0 -83
- data/lib/rblade/compiler/compiles_ruby.rb +0 -59
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module RBlade
|
4
4
|
class Tokenizer
|
5
|
-
def self.
|
6
|
-
unless segment.match?(/,\s
|
5
|
+
def self.extract_comma_separated_values(segment)
|
6
|
+
unless segment.match?(/,\s*+\z/)
|
7
7
|
# Add a comma to the end to delimit the end of the last argument
|
8
8
|
segment += ","
|
9
9
|
end
|
@@ -17,7 +17,7 @@ module RBlade
|
|
17
17
|
bracket_count = {
|
18
18
|
"[]": 0,
|
19
19
|
"{}": 0,
|
20
|
-
"()": 0
|
20
|
+
"()": 0,
|
21
21
|
}
|
22
22
|
tokens.each do |token|
|
23
23
|
case token[1]
|
@@ -48,7 +48,7 @@ module RBlade
|
|
48
48
|
end
|
49
49
|
current_line = token[0][0]
|
50
50
|
end
|
51
|
-
argument
|
51
|
+
argument << segment_lines[current_line - 1].slice(current_index...token[0][1])
|
52
52
|
argument.strip!
|
53
53
|
|
54
54
|
arguments.push argument
|
@@ -57,7 +57,7 @@ module RBlade
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
return nil if arguments.count == 1 && arguments
|
60
|
+
return nil if arguments.count == 1 && arguments[0] == ""
|
61
61
|
|
62
62
|
arguments
|
63
63
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rails"
|
4
3
|
require "rblade/compiler"
|
5
4
|
require "rblade/component_store"
|
6
5
|
require "rblade/helpers/attributes_manager"
|
@@ -25,7 +24,15 @@ module RBlade
|
|
25
24
|
component_store.view_name("view::#{view_name}")
|
26
25
|
end
|
27
26
|
|
28
|
-
|
27
|
+
preamble = +"_stacks=[];@_rblade_once_tokens=[];@_rblade_stack_manager=RBlade::StackManager.new;"
|
28
|
+
if RBlade.direct_component_rendering
|
29
|
+
# If the attributes and slot are already set, we don't need to assign them
|
30
|
+
unless template&.locals&.include?("attributes") && template.locals.include?("slot")
|
31
|
+
preamble << "attributes=RBlade::AttributesManager.new(local_assigns);slot||=yield if block_given?;slot=attributes.delete(:slot) if slot.blank?;"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
-"#{preamble}#{component_store.get}#{RBlade::Compiler.compile_string(source, component_store)}@output_buffer.raw_buffer.prepend(@_rblade_stack_manager.get(_stacks));@output_buffer;"
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
data/lib/rblade/railtie.rb
CHANGED
@@ -2,16 +2,48 @@
|
|
2
2
|
|
3
3
|
require "rails"
|
4
4
|
require "rblade/rails_template"
|
5
|
-
require "rblade/component_store"
|
6
5
|
|
7
6
|
module RBlade
|
7
|
+
# Enables support for rendering RBlade components directly. This should be enabled if you want to use RBlade components within ERB or other templating languages.
|
8
|
+
#
|
9
|
+
# When enabled, attributes is set from local_assigns, the slot variable is set from the given block, and @props statements will look for content using content_for
|
10
|
+
mattr_accessor :direct_component_rendering, default: false
|
11
|
+
|
12
|
+
# The name of the view helper method used for rendering RBlade components in other templates
|
13
|
+
mattr_accessor :component_helper_method_name, default: :component
|
14
|
+
|
8
15
|
class Railtie < ::Rails::Railtie
|
9
|
-
initializer :rblade,
|
16
|
+
initializer :rblade, after: :load_config_initializers do |app|
|
10
17
|
ActionView::Template.register_template_handler(:rblade, RBlade::RailsTemplate.new)
|
18
|
+
setup_component_view_helper(ActionView::Helpers)
|
11
19
|
|
12
20
|
RBlade::ComponentStore.add_path(Rails.root.join("app", "views", "components"))
|
13
21
|
RBlade::ComponentStore.add_path(Rails.root.join("app", "views", "layouts"), "layout")
|
14
22
|
RBlade::ComponentStore.add_path(Rails.root.join("app", "views"), "view")
|
15
23
|
end
|
24
|
+
|
25
|
+
def setup_component_view_helper(mod)
|
26
|
+
mod.send(:define_method, RBlade.component_helper_method_name) do |component_name, current_view = nil, **attributes, &block|
|
27
|
+
# If this is a relative path, prepend with the previous component name's base
|
28
|
+
if !current_view.nil? && component_name.start_with?(".")
|
29
|
+
component_name = current_view.sub(/[^\.]++\z/, "") + component_name.delete_prefix(".")
|
30
|
+
end
|
31
|
+
|
32
|
+
path = RBlade::ComponentStore.find_component_file(component_name)
|
33
|
+
|
34
|
+
# Find the relative template path without the file type
|
35
|
+
view_paths.each do |view_path|
|
36
|
+
break unless path.delete_prefix!(view_path.to_s).nil?
|
37
|
+
end
|
38
|
+
path.sub!(/(?:\.[^.]++)?\.rblade\z/, "")
|
39
|
+
|
40
|
+
locals = {
|
41
|
+
slot: block.nil? ? attributes.delete(:slot) || -"" : capture(&block),
|
42
|
+
attributes: RBlade::AttributesManager.new(attributes),
|
43
|
+
}
|
44
|
+
|
45
|
+
render template: path, locals:
|
46
|
+
end
|
47
|
+
end
|
16
48
|
end
|
17
49
|
end
|
data/rblade.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rblade"
|
3
|
-
s.version = "
|
3
|
+
s.version = "3.0.0"
|
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"]
|
@@ -15,5 +15,8 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_development_dependency "minitest", "~> 5.0"
|
16
16
|
s.add_development_dependency "minitest-reporters", "~> 1.1"
|
17
17
|
s.add_development_dependency "standard", ">= 1.3"
|
18
|
+
s.add_development_dependency "rubocop", ">= 1.73"
|
18
19
|
s.add_development_dependency "rails", ">= 7.0"
|
20
|
+
s.add_development_dependency "benchmark-ips"
|
21
|
+
s.add_development_dependency "kalibera"
|
19
22
|
end
|
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:
|
4
|
+
version: 3.0.0
|
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: 2025-03-
|
11
|
+
date: 2025-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.73'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.73'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rails
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +80,34 @@ dependencies:
|
|
66
80
|
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '7.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: benchmark-ips
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: kalibera
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
description: RBlade is a simple, yet powerful templating engine for Ruby on Rails,
|
70
112
|
inspired by Laravel Blade.
|
71
113
|
email: 2857218+mwnciau@users.noreply.github.com
|
@@ -75,6 +117,7 @@ extra_rdoc_files: []
|
|
75
117
|
files:
|
76
118
|
- ".github/workflows/ruby.yml"
|
77
119
|
- ".gitignore"
|
120
|
+
- ".rubocop.yml"
|
78
121
|
- ".standard.yml"
|
79
122
|
- CHANGELOG.md
|
80
123
|
- Gemfile
|
@@ -95,8 +138,7 @@ files:
|
|
95
138
|
- lib/rblade/compiler.rb
|
96
139
|
- lib/rblade/compiler/compiles_comments.rb
|
97
140
|
- lib/rblade/compiler/compiles_components.rb
|
98
|
-
- lib/rblade/compiler/
|
99
|
-
- lib/rblade/compiler/compiles_ruby.rb
|
141
|
+
- lib/rblade/compiler/compiles_injections.rb
|
100
142
|
- lib/rblade/compiler/compiles_statements.rb
|
101
143
|
- lib/rblade/compiler/compiles_verbatim.rb
|
102
144
|
- lib/rblade/compiler/statements/compiles_component_helpers.rb
|
@@ -124,7 +166,7 @@ licenses:
|
|
124
166
|
- MIT
|
125
167
|
metadata:
|
126
168
|
source_code_uri: https://github.com/mwnciau/rblade
|
127
|
-
post_install_message:
|
169
|
+
post_install_message:
|
128
170
|
rdoc_options: []
|
129
171
|
require_paths:
|
130
172
|
- lib
|
@@ -139,8 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
181
|
- !ruby/object:Gem::Version
|
140
182
|
version: '0'
|
141
183
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
143
|
-
signing_key:
|
184
|
+
rubygems_version: 3.4.20
|
185
|
+
signing_key:
|
144
186
|
specification_version: 4
|
145
187
|
summary: A component-first templating engine for Rails
|
146
188
|
test_files: []
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RBlade
|
4
|
-
class CompilesPrints
|
5
|
-
def compile!(tokens)
|
6
|
-
compile_unsafe_prints!(tokens)
|
7
|
-
compile_regular_prints!(tokens)
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def compile_regular_prints!(tokens)
|
13
|
-
compile_prints! tokens, "{{", "}}", true
|
14
|
-
compile_prints! tokens, "<%=", "%>", true
|
15
|
-
end
|
16
|
-
|
17
|
-
def compile_unsafe_prints!(tokens)
|
18
|
-
compile_prints! tokens, "{!!", "!!}"
|
19
|
-
compile_prints! tokens, "<%==", "%>"
|
20
|
-
end
|
21
|
-
|
22
|
-
def compile_prints!(tokens, start_token, end_token, escape_html = false)
|
23
|
-
tokens.map! do |token|
|
24
|
-
next(token) if token.type != :unprocessed
|
25
|
-
|
26
|
-
start_token_escaped = Regexp.escape start_token
|
27
|
-
end_token_escaped = Regexp.escape end_token
|
28
|
-
segments = token.value.split(/(?:(@)(#{start_token_escaped}.+?#{end_token_escaped})|(#{start_token_escaped})\s*(.+?)\s*(#{end_token_escaped}))/m)
|
29
|
-
|
30
|
-
i = 0
|
31
|
-
while i < segments.count
|
32
|
-
if segments[i] == "@"
|
33
|
-
segments.delete_at i
|
34
|
-
segments[i] = Token.new(type: :raw_text, value: segments[i])
|
35
|
-
|
36
|
-
i += 1
|
37
|
-
elsif segments[i] == start_token
|
38
|
-
segments.delete_at i
|
39
|
-
segments.delete_at i + 1
|
40
|
-
|
41
|
-
segments[i] = create_token(segments[i], escape_html)
|
42
|
-
|
43
|
-
i += 1
|
44
|
-
elsif !segments[i].nil? && segments[i] != ""
|
45
|
-
segments[i] = Token.new(type: :unprocessed, value: segments[i])
|
46
|
-
|
47
|
-
i += 1
|
48
|
-
else
|
49
|
-
segments.delete_at i
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
segments
|
54
|
-
end.flatten!
|
55
|
-
end
|
56
|
-
|
57
|
-
def create_token(expression, escape_html)
|
58
|
-
# Don't try to print ends
|
59
|
-
if expression.match?(/\A\s*(?:}|end(?![[:alnum:]_]|[^\0-\177]))/i)
|
60
|
-
return Token.new(:print, "#{expression};")
|
61
|
-
end
|
62
|
-
|
63
|
-
segment_value = if escape_html
|
64
|
-
"@output_buffer.append=#{expression};"
|
65
|
-
# If this is a block, don't wrap in parentheses
|
66
|
-
elsif expression.match?(/
|
67
|
-
(?:\{|do)\s*
|
68
|
-
(
|
69
|
-
\|\s*
|
70
|
-
[a-zA-Z0-9_]+\s*
|
71
|
-
(,\s*[a-zA-Z0-9_]+)?\s*
|
72
|
-
\|\s*
|
73
|
-
)?
|
74
|
-
\Z/x)
|
75
|
-
"@output_buffer.safe_expr_append=#{expression};"
|
76
|
-
else
|
77
|
-
"@output_buffer.raw_buffer<<(#{expression}).to_s;"
|
78
|
-
end
|
79
|
-
|
80
|
-
Token.new(:print, segment_value)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RBlade
|
4
|
-
class CompilesRuby
|
5
|
-
def compile!(tokens)
|
6
|
-
tokens.map! do |token|
|
7
|
-
next(token) if token.type != :unprocessed
|
8
|
-
|
9
|
-
segments = token.value.split(/
|
10
|
-
# @ escapes blade style tags
|
11
|
-
(@)(@ruby.+?@end_?ruby)
|
12
|
-
|
|
13
|
-
# <%% and %%> are escape ERB style tags
|
14
|
-
(<%%)(.+?)(%%>)
|
15
|
-
|
|
16
|
-
\s?(?<!\w)(@ruby)\s+(.+?)[\s;]*(@end_?ruby)(?!\w)\s?
|
17
|
-
|
|
18
|
-
(<%)(?!=)\s*(.+?)[\s;]*(%>)
|
19
|
-
/xmi)
|
20
|
-
|
21
|
-
i = 0
|
22
|
-
while i < segments.count
|
23
|
-
if segments[i] == "@"
|
24
|
-
segments.delete_at i
|
25
|
-
segments[i] = Token.new(type: :raw_text, value: segments[i])
|
26
|
-
|
27
|
-
i += 1
|
28
|
-
elsif segments[i] == "<%%"
|
29
|
-
segments.delete_at i
|
30
|
-
segments.delete_at i + 1
|
31
|
-
segments[i] = Token.new(type: :raw_text, value: "<%#{segments[i]}%>")
|
32
|
-
|
33
|
-
i += 1
|
34
|
-
elsif segments[i].downcase == "@ruby" || segments[i] == "<%"
|
35
|
-
segments.delete_at i
|
36
|
-
segments.delete_at i + 1
|
37
|
-
|
38
|
-
segments[i].strip!
|
39
|
-
if segments[i][-1] != ";"
|
40
|
-
segments[i] << ";"
|
41
|
-
end
|
42
|
-
|
43
|
-
segments[i] = Token.new(type: :ruby, value: segments[i])
|
44
|
-
|
45
|
-
i += 1
|
46
|
-
elsif !segments[i].nil? && segments[i] != ""
|
47
|
-
segments[i] = Token.new(type: :unprocessed, value: segments[i])
|
48
|
-
|
49
|
-
i += 1
|
50
|
-
else
|
51
|
-
segments.delete_at i
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
segments
|
56
|
-
end.flatten!
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|