rblade 0.2.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,28 +1,34 @@
1
1
  require "rblade/compiler"
2
2
 
3
3
  module RBlade
4
- FILE_EXTENSIONS = [".blade", ".html.blade"]
4
+ FILE_EXTENSIONS = [".rblade", ".html.rblade"]
5
5
 
6
6
  class ComponentStore
7
- def self.fetchComponent name
8
- namespace = nil
9
- path = name
7
+ # Retrieve the method name for a component, and compile it if it hasn't already been compiled
8
+ def self.component full_name
9
+ # If this is a relative path, prepend with the previous component name's base
10
+ if full_name.start_with? "."
11
+ full_name = @@component_name_stack.last.gsub(/\.[^\.]+$/, "") + full_name
12
+ end
10
13
 
11
- if name.match? "::"
12
- namespace, path = name.split("::")
14
+ # Ensure each component is only compiled once
15
+ unless @@component_method_names[full_name].nil?
16
+ return @@component_method_names[full_name]
13
17
  end
14
18
 
15
- path.tr! ".", "/"
19
+ @@component_name_stack << full_name
16
20
 
17
- @@template_paths[namespace]&.each do |base_path|
18
- FILE_EXTENSIONS.each do |extension|
19
- if File.exist? base_path + path + extension
20
- return RBlade::Compiler.compileString File.read(base_path + path + extension)
21
- end
22
- end
21
+ namespace = nil
22
+ name = full_name
23
+
24
+ if name.match? "::"
25
+ namespace, name = full_name.split("::")
23
26
  end
24
27
 
25
- raise StandardError.new "Unknown component #{name}"
28
+ method_name = compile_component full_name, File.read(find_component_file(namespace, name))
29
+ @@component_name_stack.pop
30
+
31
+ method_name
26
32
  end
27
33
 
28
34
  def self.add_path path, namespace = nil
@@ -35,8 +41,61 @@ module RBlade
35
41
  @@template_paths[namespace] << path
36
42
  end
37
43
 
44
+ def self.view_name view_name
45
+ @@component_name_stack.push view_name
46
+ end
47
+
48
+ def self.get
49
+ @@component_definitions
50
+ end
51
+
52
+ def self.clear
53
+ @@component_definitions = ""
54
+ @@component_method_names = {}
55
+ @@component_name_stack = []
56
+ end
57
+
58
+ def self.find_component_file namespace, name
59
+ file_path = name.tr ".", "/"
60
+
61
+ @@template_paths[namespace]&.each do |base_path|
62
+ FILE_EXTENSIONS.each do |extension|
63
+ if File.exist? base_path + file_path + extension
64
+ return "#{base_path}#{file_path}#{extension}"
65
+ end
66
+ if File.exist? base_path + file_path + "/index" + extension
67
+ # Account for index files for relative components
68
+ @@component_name_stack << @@component_name_stack.pop + ".index"
69
+ return "#{base_path}#{file_path}/index#{extension}"
70
+ end
71
+ end
72
+ end
73
+
74
+ raise StandardError.new "Unknown component #{namespace}::#{name}"
75
+ end
76
+ private_class_method :find_component_file
77
+
78
+ def self.compile_component(name, code)
79
+ @@component_method_names[name] = "_c#{@@component_method_names.count}"
80
+
81
+ compiled_component = RBlade::Compiler.compileString(code)
82
+
83
+ @@component_definitions \
84
+ << "def #{@@component_method_names[name]}(slot,attributes);_out='';" \
85
+ << "_stacks=[];" \
86
+ << "attributes=RBlade::AttributesManager.new(attributes);" \
87
+ << compiled_component \
88
+ << "RBlade::StackManager.get(_stacks) + _out;end;"
89
+
90
+ @@component_method_names[name]
91
+ end
92
+ private_class_method :compile_component
93
+
38
94
  private
39
95
 
96
+ @@component_definitions = ""
97
+ @@component_name_stack = []
98
+ @@component_method_names = {}
40
99
  @@template_paths = {}
41
100
  end
42
101
  end
@@ -3,15 +3,6 @@ module RBlade
3
3
  @attributes = {}
4
4
  def initialize attributes
5
5
  @attributes = attributes
6
-
7
- if !@attributes[:_class].nil?
8
- @attributes[:class] = mergeClasses(@attributes[:class], @attributes.delete(:_class))
9
- end
10
- if !@attributes[:_style].nil?
11
- @attributes[:style] = mergeClasses(@attributes[:style], @attributes.delete(:_style))
12
- end
13
-
14
- @attributes
15
6
  end
16
7
 
17
8
  def default(key, default = nil)
@@ -26,23 +17,19 @@ module RBlade
26
17
  !@attributes[key].nil?
27
18
  end
28
19
 
29
- def to_h
30
- attributes = @attributes.dup
31
- if !attributes[:class].nil?
32
- attributes[:_class] = attributes.delete :class
33
- end
34
- if !attributes[:style].nil?
35
- attributes[:_style] = attributes.delete :style
36
- end
20
+ def method_missing(method, *)
21
+ @attributes.send(method, *)
22
+ end
37
23
 
38
- attributes
24
+ def respond_to_missing?(method_name, *args)
25
+ @attributes.respond_to?(method_name) || super
39
26
  end
40
27
 
41
28
  def to_s attributes = nil
42
29
  attributes ||= @attributes
43
30
 
44
31
  attributes.map do |key, value|
45
- "#{key}=\"#{h(value)}\""
32
+ "#{key}=\"#{(value == true) ? key : h(value)}\""
46
33
  end.join " "
47
34
  end
48
35
 
@@ -19,5 +19,9 @@ module RBlade
19
19
  def to_s
20
20
  @classes
21
21
  end
22
+
23
+ def to_str
24
+ to_s
25
+ end
22
26
  end
23
27
  end
@@ -33,5 +33,9 @@ module RBlade
33
33
  def to_s
34
34
  @styles
35
35
  end
36
+
37
+ def to_str
38
+ to_s
39
+ end
36
40
  end
37
41
  end
@@ -1,5 +1,6 @@
1
1
  require "rails"
2
2
  require "rblade/compiler"
3
+ require "rblade/component_store"
3
4
  require "rblade/helpers/attributes_manager"
4
5
  require "rblade/helpers/class_manager"
5
6
  require "rblade/helpers/stack_manager"
@@ -8,10 +9,25 @@ require "rblade/helpers/style_manager"
8
9
  module RBlade
9
10
  class RailsTemplate
10
11
  def call(template, source = nil)
12
+ RBlade::ComponentStore.clear
11
13
  RBlade::StackManager.clear
12
- setup = "_out='';_stacks=[];"
14
+
15
+ unless template.nil?
16
+ view_name = template.short_identifier
17
+ .delete_prefix("app/views/")
18
+ .delete_suffix(".rblade")
19
+ .delete_suffix(".html")
20
+ .tr("/", ".")
21
+
22
+ # Let the component store know about the current view for relative components
23
+ RBlade::ComponentStore.view_name(
24
+ "view::#{view_name}"
25
+ )
26
+ end
27
+ setup = "_out='';_stacks=[];$_once_tokens=[];"
28
+ code = RBlade::Compiler.compileString(source || template.source)
13
29
  setdown = "RBlade::StackManager.get(_stacks) + _out"
14
- setup + RBlade::Compiler.compileString(source || template.source) + setdown
30
+ setup + ComponentStore.get + code + setdown
15
31
  end
16
32
  end
17
33
  end
@@ -5,10 +5,11 @@ require "rblade/component_store"
5
5
  module RBlade
6
6
  class Railtie < ::Rails::Railtie
7
7
  initializer :rblade, before: :load_config_initializers do |app|
8
- ActionView::Template.register_template_handler(:blade, RBlade::RailsTemplate.new)
8
+ ActionView::Template.register_template_handler(:rblade, RBlade::RailsTemplate.new)
9
9
 
10
10
  RBlade::ComponentStore.add_path(Rails.root.join("app", "views", "components"))
11
11
  RBlade::ComponentStore.add_path(Rails.root.join("app", "views", "layouts"), "layout")
12
+ RBlade::ComponentStore.add_path(Rails.root.join("app", "views"), "view")
12
13
  end
13
14
  end
14
15
  end
data/rblade.gemspec CHANGED
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rblade"
3
- s.version = "0.2.5"
4
- s.summary = "Blade templates for ruby"
5
- s.description = "A port of the Laravel blade templating engine to ruby"
3
+ s.version = "0.4.0"
4
+ s.summary = "A component-first templating engine for Rails"
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"]
7
7
  s.email = "2857218+mwnciau@users.noreply.github.com"
8
8
  s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|storage)/}) }
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.2.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon J
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-23 00:00:00.000000000 Z
11
+ date: 2024-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -66,7 +66,8 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '7.0'
69
- description: A port of the Laravel blade templating engine to ruby
69
+ description: RBlade is a simple, yet powerful templating engine for Ruby on Rails,
70
+ inspired by Laravel Blade.
70
71
  email: 2857218+mwnciau@users.noreply.github.com
71
72
  executables: []
72
73
  extensions: []
@@ -76,7 +77,10 @@ files:
76
77
  - ".standard.yml"
77
78
  - CHANGELOG.md
78
79
  - Gemfile
80
+ - LICENSE.md
81
+ - README.md
79
82
  - Rakefile
83
+ - TODO.md
80
84
  - do
81
85
  - docker-compose.yml
82
86
  - lib/rblade.rb
@@ -86,9 +90,12 @@ files:
86
90
  - lib/rblade/compiler/compiles_echos.rb
87
91
  - lib/rblade/compiler/compiles_ruby.rb
88
92
  - lib/rblade/compiler/compiles_statements.rb
93
+ - lib/rblade/compiler/compiles_verbatim.rb
89
94
  - lib/rblade/compiler/statements/compiles_conditionals.rb
95
+ - lib/rblade/compiler/statements/compiles_html_attributes.rb
90
96
  - lib/rblade/compiler/statements/compiles_inline_ruby.rb
91
97
  - lib/rblade/compiler/statements/compiles_loops.rb
98
+ - lib/rblade/compiler/statements/compiles_once.rb
92
99
  - lib/rblade/compiler/statements/compiles_props.rb
93
100
  - lib/rblade/compiler/statements/compiles_stacks.rb
94
101
  - lib/rblade/compiler/tokenizes_components.rb
@@ -124,5 +131,5 @@ requirements: []
124
131
  rubygems_version: 3.5.11
125
132
  signing_key:
126
133
  specification_version: 4
127
- summary: Blade templates for ruby
134
+ summary: A component-first templating engine for Rails
128
135
  test_files: []