ruby2html 1.1.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acd9834eee45bda437a281566e66300e5e5645dddb45850d571d506c27a94501
4
- data.tar.gz: ebe9a74c98f952e049335357fda1e9268f7126fbb090cbf7bf4e8b4e1fbedc1f
3
+ metadata.gz: 006b9857270b4ad9ebc613ca84e1e00327285e4e52f371417a42d2823e6b3099
4
+ data.tar.gz: f78b3b0d8929174dde445502d0c90051ff6ac95a8b37f7e05e7722ff91d96aaf
5
5
  SHA512:
6
- metadata.gz: 4dc38bb961568de810742b8e8c2a8c9231abcbc0244bf0334350b3949eef3e1d81d2f907ab2565bc1acc6b0b6751ccabdc2c04b9855996e72e0ef0c117eaf8fa
7
- data.tar.gz: 5e200ab5fd3f5a0941c7d7a32e5729e5a9f249d01158b1906a2797d0b0e8309bf403e0aaf5bd5a8416ef9cf42a8d56c0150bc2a9d5f0ca63bfe987ba8c777dca
6
+ metadata.gz: aa9a480274cbe132f1053010d218b5f1e3e56be27dd224fc0d41867ea85e2d0afb763b121fb8179f2426d4bcbb5f17a0c70b0c361aff7b722afada0ea7b7a046
7
+ data.tar.gz: 49c3f7a01bfd9cc058ce68a672b8e2c159a41895a7af6b2352a8d150b192e1da445ea124640807d0d291da8cc53b528e25f9a960bf1e21f0103db7e48463abf0
data/README.md CHANGED
@@ -25,18 +25,6 @@ Or install it yourself as:
25
25
 
26
26
  ## 🎨 Usage
27
27
 
28
- ### In your ApplicationController
29
-
30
- File: `app/controllers/application_controller.rb`
31
-
32
- ```ruby
33
- # frozen_string_literal: true
34
-
35
- class ApplicationController < ActionController::Base
36
- include Ruby2html::RailsHelper
37
- end
38
- ```
39
-
40
28
  ### In your views
41
29
 
42
30
  File: `app/views/your_view.html.rb`
@@ -63,6 +51,18 @@ render partial: 'shared/navbar'
63
51
 
64
52
  #### Or use your current .erb views
65
53
 
54
+ ### In your ApplicationController
55
+
56
+ File: `app/controllers/application_controller.rb`
57
+
58
+ ```ruby
59
+ # frozen_string_literal: true
60
+
61
+ class ApplicationController < ActionController::Base
62
+ include Ruby2html::RailsHelper
63
+ end
64
+ ```
65
+
66
66
  File: `app/views/your_view.html.erb`
67
67
 
68
68
  Replace your ERB with beautiful Ruby code:
@@ -97,18 +97,18 @@ Replace your ERB with beautiful Ruby code:
97
97
  ruby 3.3.3 (2024-06-12 revision f1c7b6f435) +YJIT [x86_64-linux]
98
98
  Warming up --------------------------------------
99
99
  GET /benchmark/html (ERB)
100
- 1.000 i/100ms
100
+ 2.000 i/100ms
101
101
  GET /benchmark/ruby (Ruby2html)
102
102
  1.000 i/100ms
103
103
  Calculating -------------------------------------
104
104
  GET /benchmark/html (ERB)
105
- 20.163 (±19.8%) i/s - 95.000 in 5.062853s
105
+ 20.989 (±19.1%) i/s - 102.000 in 5.077353s
106
106
  GET /benchmark/ruby (Ruby2html)
107
- 19.36215.5%) i/s - 92.000 in 5.006433s
107
+ 20.43819.6%) i/s - 97.000 in 5.010249s
108
108
 
109
109
  Comparison:
110
- GET /benchmark/html (ERB): 20.2 i/s
111
- GET /benchmark/ruby (Ruby2html): 19.4 i/s - same-ish: difference falls within error
110
+ GET /benchmark/html (ERB): 21.0 i/s
111
+ GET /benchmark/ruby (Ruby2html): 20.4 i/s - same-ish: difference falls within error
112
112
  ```
113
113
 
114
114
  ### With ViewComponents
@@ -138,7 +138,7 @@ class GreetingComponent < ApplicationComponent
138
138
  end
139
139
 
140
140
  def call
141
- html(self) do
141
+ html do
142
142
  h1 class: 'greeting', 'data-user': @name do
143
143
  "Hello, #{@name}! 👋"
144
144
  end
@@ -164,19 +164,17 @@ class FarewellComponent < ApplicationComponent
164
164
  end
165
165
  ```
166
166
 
167
- File: `app/components/farewell_component.html.erb`
167
+ File: `app/components/farewell_component.html.rb`
168
168
 
169
- ```erb
170
- <div class="farewell">
171
- <h2>Goodbye, <%= @name %>! 👋</h2>
172
- <p>We hope you enjoyed using Ruby2html!</p>
173
-
174
- <%=
175
- html do
176
- link_to 'Home', root_path, class: 'btn btn-primary', 'data-turbo': false
177
- end
178
- %>
179
- </div>
169
+ ```rb
170
+ div class: 'farewell' do
171
+ h1 class: 'farewell-message' do
172
+ "Goodbye, #{@name}! 👋"
173
+ end
174
+ p class: 'farewell-text' do
175
+ 'We hope to see you again soon!'
176
+ end
177
+ end
180
178
  ```
181
179
 
182
180
  This flexibility allows you to:
@@ -197,7 +195,7 @@ class FirstComponent < ApplicationComponent
197
195
  end
198
196
 
199
197
  def call
200
- html(self) do
198
+ html do
201
199
  h1 id: 'first-component-title' do
202
200
  'first component'
203
201
  end
@@ -219,7 +217,7 @@ File: `app/components/second_component.rb`
219
217
 
220
218
  class SecondComponent < ApplicationComponent
221
219
  def call
222
- html(self) do
220
+ html do
223
221
  h1 class: 'my-class', id: 'second-component-title', 'data-controller': 'second' do
224
222
  'second component'
225
223
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ h1 'first component'
4
+
5
+ div do
6
+ h2 'A subheading'
7
+ end
8
+
9
+ another_div
10
+
11
+ p @item
@@ -4,4 +4,12 @@ class FirstComponent < ApplicationComponent
4
4
  def initialize
5
5
  @item = 'Hello, World!'
6
6
  end
7
+
8
+ def another_div
9
+ div do
10
+ h2 'Another subheading from component'
11
+ end
12
+
13
+ h1 'Yet Another heading from component'
14
+ end
7
15
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class SecondComponent < ApplicationComponent
4
4
  def call
5
- html(self) do
5
+ html do
6
6
  h1 class: 'my-class' do
7
7
  plain 'Second Component'
8
8
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ h1 'Third component'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThirdComponent < ApplicationComponent
4
+ def initialize
5
+ @item = 'Hello, World!'
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ h1 'Benchmark: Ruby2html'
4
+
5
+ h2 'User Statistics'
6
+ ul do
7
+ li { plain "Total Users: #{@complex_data[:stats][:total_users]}" }
8
+ li { plain "Average Orders per User: #{@complex_data[:stats][:average_orders_per_user]}" }
9
+ li { plain "Most Expensive Item: #{@complex_data[:stats][:most_expensive_item]}" }
10
+ li { plain "Most Popular Country: #{@complex_data[:stats][:most_popular_country]}" }
11
+ end
12
+
13
+ h2 'User List'
14
+ @complex_data[:users].each do |user|
15
+ div class: 'user-card' do
16
+ h3 user[:name]
17
+ p { plain "Email: #{user[:email]}" }
18
+ p { plain "Address: #{user[:address][:street]}, #{user[:address][:city]}, #{user[:address][:country]}" }
19
+
20
+ h4 'Orders'
21
+ user[:orders].each do |order|
22
+ div class: 'order' do
23
+ p { plain "Order ID: #{order[:id]}" }
24
+ p { plain "Total: $#{order[:total]}" }
25
+ ul do
26
+ order[:items].each do |item|
27
+ li { plain "#{item[:name]} - $#{item[:price]} (Quantity: #{item[:quantity]})" }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  <%= render FirstComponent.new %>
4
4
  <%= render SecondComponent.new %>
5
+ <%= render ThirdComponent.new %>
5
6
 
6
7
  <%=
7
8
  html(self) do
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ h1 'RbFiles'
4
+ h1 'ok'
5
+ h1 'ok'
6
+
7
+ div @value
8
+
9
+ link_to 'Home', root_url
10
+ render partial: 'shared/navbar'
@@ -2,8 +2,26 @@
2
2
 
3
3
  module Ruby2html
4
4
  module ComponentHelper
5
- def html(context, &block)
6
- Ruby2html::Render.new(context, &block).render.html_safe
5
+ def html(&block)
6
+ previous_renderer = __ruby2html_renderer__
7
+ Ruby2html::Render.new(self, &block).yield_self do |component_renderer|
8
+ Thread.current[:__ruby2html_renderer__] = component_renderer
9
+ component_renderer.render.html_safe
10
+ end
11
+ ensure
12
+ Thread.current[:__ruby2html_renderer__] = previous_renderer
13
+ end
14
+
15
+ def method_missing(method, *args, &block)
16
+ if __ruby2html_renderer__.respond_to?(method)
17
+ __ruby2html_renderer__.send(method, *args, &block)
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def __ruby2html_renderer__
24
+ Thread.current[:__ruby2html_renderer__]
7
25
  end
8
26
  end
9
27
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruby2html
4
+ class TemplateHandler
5
+ class_attribute :default_format
6
+ self.default_format = :html
7
+
8
+ def self.call(template, source)
9
+ new.call(template, source)
10
+ end
11
+
12
+ def call(_template, source)
13
+ <<-RUBY
14
+ begin
15
+ previous_renderer = Thread.current[:__ruby2html_renderer__]
16
+ renderer = Ruby2html::Render.new(self) do
17
+ #{source}
18
+ end
19
+ Thread.current[:__ruby2html_renderer__] = renderer
20
+ renderer.render
21
+ ensure
22
+ Thread.current[:__ruby2html_renderer__] = previous_renderer
23
+ end
24
+ RUBY
25
+ end
26
+ end
27
+
28
+ class Railtie < Rails::Railtie
29
+ initializer 'ruby2html.initializer' do
30
+ Rails.autoloaders.main.ignore(
31
+ Rails.root.join('app/views/**/*.html.rb'),
32
+ Rails.root.join('app/components/**/*.html.rb')
33
+ )
34
+ end
35
+ end
36
+ end
37
+
38
+ ActionView::Template.register_template_handler :rb, Ruby2html::TemplateHandler if defined? ActionView::Template
@@ -6,14 +6,14 @@ require 'stringio'
6
6
  module Ruby2html
7
7
  class Render
8
8
  HTML5_TAGS = %w[
9
- a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption
10
- cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset
11
- figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hr html i iframe img input ins
12
- kbd label legend li link main map mark meta meter nav noscript object ol optgroup option
13
- output p param picture pre progress q rp rt ruby s samp script section select small source
14
- span strong style sub summary sup table tbody td template textarea tfoot th thead time title
15
- tr track u ul var video wbr
16
- ].freeze
9
+ a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption
10
+ cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset
11
+ figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hr html i iframe img input ins
12
+ kbd label legend li link main map mark meta meter nav noscript object ol optgroup option
13
+ output p param picture pre progress q rp rt ruby s samp script section select small source
14
+ span strong style sub summary sup table tbody td template textarea tfoot th thead time title
15
+ tr track u ul var video wbr
16
+ ].freeze
17
17
 
18
18
  VOID_ELEMENTS = %w[area base br col embed hr img input link meta param source track wbr].freeze
19
19
 
@@ -35,7 +35,12 @@ module Ruby2html
35
35
  return plain @context.render(*args, **options, &block)
36
36
  end
37
37
  instance_exec(&@root)
38
- @output.string
38
+ result = @output.string
39
+ if defined?(ActiveSupport)
40
+ result = ActiveSupport::SafeBuffer.new(result)
41
+ end
42
+
43
+ result
39
44
  end
40
45
 
41
46
  HTML5_TAGS.each do |tag|
@@ -44,6 +49,10 @@ module Ruby2html
44
49
  end
45
50
  end
46
51
 
52
+ def respond_to?(method_name, include_private = false)
53
+ HTML5_TAGS.include?(method_name) || super
54
+ end
55
+
47
56
  def html!(name, *args, **options, &block)
48
57
  content = args.first.is_a?(String) ? args.shift : nil
49
58
  attributes = options
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruby2html
4
- VERSION = '1.1.0'
4
+ VERSION = '1.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2html
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sebi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-08 00:00:00.000000000 Z
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby2HTML empowers developers to write view logic in pure Ruby, seamlessly
14
14
  converting it into clean, well-formatted HTML. Enhance your templating workflow,
@@ -33,9 +33,11 @@ files:
33
33
  - app/channels/application_cable/channel.rb
34
34
  - app/channels/application_cable/connection.rb
35
35
  - app/components/application_component.rb
36
- - app/components/first_component.html.erb
36
+ - app/components/first_component.html.rb
37
37
  - app/components/first_component.rb
38
38
  - app/components/second_component.rb
39
+ - app/components/third_component.rb
40
+ - app/components/third_component/third_component.html.rb
39
41
  - app/controllers/application_controller.rb
40
42
  - app/controllers/benchmark_controller.rb
41
43
  - app/controllers/concerns/.keep
@@ -46,8 +48,9 @@ files:
46
48
  - app/models/application_record.rb
47
49
  - app/models/concerns/.keep
48
50
  - app/views/benchmark/normal_html.html.erb
49
- - app/views/benchmark/ruby_2html.html.erb
51
+ - app/views/benchmark/ruby_2html.html.rb
50
52
  - app/views/home/index.html.erb
53
+ - app/views/home/rb_files.html.rb
51
54
  - app/views/layouts/application.html.erb
52
55
  - app/views/layouts/mailer.html.erb
53
56
  - app/views/layouts/mailer.text.erb
@@ -79,6 +82,7 @@ files:
79
82
  - lib/gem/ruby2html.rb
80
83
  - lib/gem/ruby2html/component_helper.rb
81
84
  - lib/gem/ruby2html/rails_helper.rb
85
+ - lib/gem/ruby2html/railtie.rb
82
86
  - lib/gem/ruby2html/render.rb
83
87
  - lib/gem/ruby2html/version.rb
84
88
  - lib/tasks/.keep
@@ -1,9 +0,0 @@
1
- <%= html(self) do
2
- h1 "first component"
3
-
4
- div do
5
- h2 "A subheading"
6
- end
7
-
8
- p @item
9
- end %>
@@ -1,35 +0,0 @@
1
- <%=
2
- html(self) do
3
- h1 'Benchmark: Ruby2html'
4
-
5
- h2 'User Statistics'
6
- ul do
7
- li { plain "Total Users: #{@complex_data[:stats][:total_users]}" }
8
- li { plain "Average Orders per User: #{@complex_data[:stats][:average_orders_per_user]}" }
9
- li { plain "Most Expensive Item: #{@complex_data[:stats][:most_expensive_item]}" }
10
- li { plain "Most Popular Country: #{@complex_data[:stats][:most_popular_country]}" }
11
- end
12
-
13
- h2 'User List'
14
- @complex_data[:users].each do |user|
15
- div class: 'user-card' do
16
- h3 user[:name]
17
- p { plain "Email: #{user[:email]}" }
18
- p { plain "Address: #{user[:address][:street]}, #{user[:address][:city]}, #{user[:address][:country]}" }
19
-
20
- h4 'Orders'
21
- user[:orders].each do |order|
22
- div class: 'order' do
23
- p { plain "Order ID: #{order[:id]}" }
24
- p { plain "Total: $#{order[:total]}" }
25
- ul do
26
- order[:items].each do |item|
27
- li { plain "#{item[:name]} - $#{item[:price]} (Quantity: #{item[:quantity]})" }
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
35
- %>