ruby2html 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
- %>