ruby2html 1.4.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +7 -7
- data/app/views/home/form.html.rb +14 -0
- data/app/views/home/index.html.erb +6 -3
- data/app/views/home/rb_files.html.rb +5 -0
- data/app/views/layouts/application.html.erb +0 -1
- data/config/routes.rb +1 -0
- data/lib/gem/ruby2html/html_beautifier_middleware.rb +26 -0
- data/lib/gem/ruby2html/rails_components/base_component.rb +19 -0
- data/lib/gem/ruby2html/rails_components/button_to.rb +11 -0
- data/lib/gem/ruby2html/rails_components/form_with.rb +93 -0
- data/lib/gem/ruby2html/rails_components/image_tag.rb +11 -0
- data/lib/gem/ruby2html/rails_components/link_to.rb +11 -0
- data/lib/gem/ruby2html/railtie.rb +1 -1
- data/lib/gem/ruby2html/render.rb +11 -10
- data/lib/gem/ruby2html/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f23a95af48405360717b40b2da95c55592066f6ac054e95bc07974d90fefd205
|
4
|
+
data.tar.gz: a2ee6ccafaeb77d085ee8227b51315ebed73a5a1a46eef7eb885f8b1a1b88ed6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a09d5f0288ca174e8348620f62b1ac11331fb53f34ea9790f16b81c27fae218aa4c22076512c5716b41b1c4ddc3376f77d5f593ac8359f65be71c9a002fcd280
|
7
|
+
data.tar.gz: 64e555a4b2cb1f4470f00a967b310cd7a23cdc79bdf2b2650af5ee044aef1049bd37677e771e6d65f84f6e15234c9cd39fadf45af3086481e30a83c9d3b7b8a4
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -34,12 +34,12 @@ div class: 'container' do
|
|
34
34
|
h1 'Welcome to Ruby2html! 🎉', class: 'main-title', 'data-controller': 'welcome'
|
35
35
|
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
|
36
36
|
|
37
|
-
@
|
38
|
-
h2 class: 'item-title', id: "
|
39
|
-
|
37
|
+
@products.each do |product|
|
38
|
+
h2 class: 'item-title', id: "product-#{product[:id]}" do
|
39
|
+
product.title
|
40
40
|
end
|
41
41
|
p class: 'item-description' do
|
42
|
-
|
42
|
+
product.description
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -49,7 +49,7 @@ plain '<div>Inline html</div>'.html_safe
|
|
49
49
|
render partial: 'shared/navbar'
|
50
50
|
```
|
51
51
|
|
52
|
-
### (Optional) Nicely Format the HTML
|
52
|
+
### (Optional) Nicely Format the HTML for source inspection
|
53
53
|
|
54
54
|
File: `config/environments/development.rb` or `config/environments/test.rb`
|
55
55
|
```ruby
|
@@ -84,10 +84,10 @@ Replace your ERB with beautiful Ruby code:
|
|
84
84
|
|
85
85
|
@items.each do |item|
|
86
86
|
h2 class: 'item-title', id: "item-#{item[:id]}" do
|
87
|
-
item
|
87
|
+
item.title
|
88
88
|
end
|
89
89
|
p class: 'item-description' do
|
90
|
-
item
|
90
|
+
item.description
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -14,10 +14,13 @@
|
|
14
14
|
h1 "ok"
|
15
15
|
h1 "ok"
|
16
16
|
div do
|
17
|
-
link_to 'home', root_path
|
17
|
+
link_to 'home 1', root_path
|
18
|
+
end
|
19
|
+
link_to 'home 2', root_path
|
20
|
+
|
21
|
+
div do
|
22
|
+
link_to 'home 3', root_path
|
18
23
|
end
|
19
|
-
link_to 'home', root_path
|
20
|
-
link_to 'home', root_path
|
21
24
|
|
22
25
|
render partial: 'shared/navbar'
|
23
26
|
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'htmlbeautifier'
|
4
|
+
|
5
|
+
module Ruby2html
|
6
|
+
class HtmlBeautifierMiddleware
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
status, headers, body = @app.call(env)
|
13
|
+
|
14
|
+
if headers['Content-Type']&.include?('text/html')
|
15
|
+
new_body = []
|
16
|
+
body.each do |chunk|
|
17
|
+
new_body << HtmlBeautifier.beautify(chunk)
|
18
|
+
end
|
19
|
+
headers['Content-Length'] = new_body.map(&:bytesize).sum.to_s
|
20
|
+
body = new_body
|
21
|
+
end
|
22
|
+
|
23
|
+
[status, headers, body]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruby2html
|
4
|
+
module RailsComponents
|
5
|
+
class BaseComponent
|
6
|
+
def initialize(render, context, method, *args, **options)
|
7
|
+
@render = render
|
8
|
+
@context = context
|
9
|
+
@method = method
|
10
|
+
@args = args
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def render(&block)
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruby2html
|
4
|
+
module RailsComponents
|
5
|
+
class FormWith < BaseComponent
|
6
|
+
include ActionView::Helpers::FormHelper
|
7
|
+
def render(&block)
|
8
|
+
model = @options[:model]
|
9
|
+
scope = @options[:scope]
|
10
|
+
url = @options[:url]
|
11
|
+
method = @options[:method]
|
12
|
+
local = @options[:local]
|
13
|
+
|
14
|
+
form_options = @options.except(:model, :scope, :url, :method, :local)
|
15
|
+
form_options[:action] = determine_url(model, url)
|
16
|
+
form_options[:method] = determine_method(model, method)
|
17
|
+
form_options['data-remote'] = 'true' unless local
|
18
|
+
@model = model
|
19
|
+
@scope = determine_scope(model, scope)
|
20
|
+
|
21
|
+
@render.form(**form_options) do
|
22
|
+
authenticity_token_tag
|
23
|
+
utf8_enforcer_tag
|
24
|
+
block.call(self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def label(method, text = nil, options = {})
|
29
|
+
@render.label(**options.merge(for: field_id(method))) do
|
30
|
+
text || method.to_s.humanize
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def text_field(method, options = {})
|
35
|
+
@render.input(**options.merge(type: 'text', name: field_name(method), id: field_id(method), value: object_value_for(method)))
|
36
|
+
end
|
37
|
+
|
38
|
+
def hidden_field(method, options = {})
|
39
|
+
@render.input(**options.merge(type: 'hidden', name: field_name(method), id: field_id(method), value: object_value_for(method)))
|
40
|
+
end
|
41
|
+
|
42
|
+
def password_field(method, options = {})
|
43
|
+
@render.input(**options.merge(type: 'password', name: field_name(method), id: field_id(method)))
|
44
|
+
end
|
45
|
+
|
46
|
+
def file_field(method, options = {})
|
47
|
+
@render.input(**options.merge(type: 'file', name: field_name(method), id: field_id(method)))
|
48
|
+
end
|
49
|
+
|
50
|
+
def submit(value = nil, options = {})
|
51
|
+
@render.input(**options.merge(type: 'submit', value: value || submit_default_value))
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def determine_url(model, url)
|
56
|
+
return url if url
|
57
|
+
return polymorphic_path(model) if model && model.respond_to?(:persisted?)
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def determine_method(model, method)
|
62
|
+
return method if method
|
63
|
+
return 'post' unless model
|
64
|
+
model.respond_to?(:persisted?) && model.persisted? ? 'patch' : 'post'
|
65
|
+
end
|
66
|
+
|
67
|
+
def determine_scope(model, scope)
|
68
|
+
return scope if scope
|
69
|
+
model.model_name.param_key if model.respond_to?(:model_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def authenticity_token_tag
|
73
|
+
@render.input(type: 'hidden', name: 'authenticity_token', value: @context.session[:_csrf_token])
|
74
|
+
end
|
75
|
+
|
76
|
+
def utf8_enforcer_tag
|
77
|
+
@render.input(type: 'hidden', name: 'utf8', value: '✓')
|
78
|
+
end
|
79
|
+
|
80
|
+
def field_name(method)
|
81
|
+
@scope ? "#{@scope}[#{method}]" : method.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
def field_id(method)
|
85
|
+
@scope ? "#{@scope}_#{method}" : method.to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def object_value_for(method)
|
89
|
+
@model&.public_send(method) if @model
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -17,7 +17,7 @@ module Ruby2html
|
|
17
17
|
#{source}
|
18
18
|
end
|
19
19
|
Thread.current[:__ruby2html_renderer__] = renderer
|
20
|
-
renderer.
|
20
|
+
renderer.__render_from_rails(#{template.identifier.inspect})
|
21
21
|
ensure
|
22
22
|
Thread.current[:__ruby2html_renderer__] = previous_renderer
|
23
23
|
end
|
data/lib/gem/ruby2html/render.rb
CHANGED
@@ -17,9 +17,10 @@ module Ruby2html
|
|
17
17
|
|
18
18
|
VOID_ELEMENTS = %w[area base br col embed hr img input link meta param source track wbr].freeze
|
19
19
|
|
20
|
-
COMMON_RAILS_METHOD_HELPERS = %w[
|
20
|
+
COMMON_RAILS_METHOD_HELPERS = %w[link_to image_tag form_with button_to].freeze
|
21
21
|
|
22
22
|
attr_reader :output
|
23
|
+
attr_accessor :current_output
|
23
24
|
|
24
25
|
def initialize(context, &root)
|
25
26
|
@context = context
|
@@ -28,14 +29,14 @@ module Ruby2html
|
|
28
29
|
@current_output = @output
|
29
30
|
end
|
30
31
|
|
31
|
-
def
|
32
|
+
def __render_from_rails(template_path)
|
32
33
|
result = render
|
33
34
|
return result unless annotate_rendered_view_with_filenames?
|
34
35
|
|
35
36
|
template_path = template_path.sub("#{Rails.root}/", '')
|
36
37
|
|
37
38
|
"<!-- BEGIN #{template_path} -->#{result}<!-- END #{template_path} -->".html_safe
|
38
|
-
end
|
39
|
+
end if defined?(ActionView)
|
39
40
|
|
40
41
|
def render(*args, **options, &block)
|
41
42
|
set_instance_variables
|
@@ -45,9 +46,8 @@ module Ruby2html
|
|
45
46
|
end
|
46
47
|
instance_exec(&@root)
|
47
48
|
result = @output.string
|
48
|
-
|
49
|
-
|
50
|
-
end
|
49
|
+
|
50
|
+
result = ActiveSupport::SafeBuffer.new(result) if defined?(ActiveSupport)
|
51
51
|
|
52
52
|
result
|
53
53
|
end
|
@@ -62,7 +62,7 @@ module Ruby2html
|
|
62
62
|
HTML5_TAGS.include?(method_name) || super
|
63
63
|
end
|
64
64
|
|
65
|
-
def html!(name, *args, **options
|
65
|
+
def html!(name, *args, **options)
|
66
66
|
content = args.first.is_a?(String) ? args.shift : nil
|
67
67
|
attributes = options
|
68
68
|
|
@@ -121,8 +121,9 @@ module Ruby2html
|
|
121
121
|
end
|
122
122
|
|
123
123
|
COMMON_RAILS_METHOD_HELPERS.each do |method|
|
124
|
-
define_method(method) do |*args, &block|
|
125
|
-
|
124
|
+
define_method(method) do |*args, **options, &block|
|
125
|
+
constant = "Ruby2html::RailsComponents::#{method.to_s.camelize}".constantize
|
126
|
+
constant.new(self, @context, method, *args, **options).render(&block)
|
126
127
|
end
|
127
128
|
end if defined?(ActionView)
|
128
129
|
|
@@ -130,7 +131,7 @@ module Ruby2html
|
|
130
131
|
return '' if attributes.empty?
|
131
132
|
|
132
133
|
result = StringIO.new
|
133
|
-
attributes.each do |k, v|
|
134
|
+
attributes.compact.each do |k, v|
|
134
135
|
result << ' '
|
135
136
|
result << k.to_s
|
136
137
|
result << '="'
|
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.
|
4
|
+
version: 1.5.1
|
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-
|
11
|
+
date: 2024-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: htmlbeautifier
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- app/models/concerns/.keep
|
64
64
|
- app/views/benchmark/normal_html.html.erb
|
65
65
|
- app/views/benchmark/ruby_2html.html.rb
|
66
|
+
- app/views/home/form.html.rb
|
66
67
|
- app/views/home/index.html.erb
|
67
68
|
- app/views/home/rb_files.html.rb
|
68
69
|
- app/views/layouts/application.html.erb
|
@@ -96,6 +97,12 @@ files:
|
|
96
97
|
- lib/assets/.keep
|
97
98
|
- lib/gem/ruby2html.rb
|
98
99
|
- lib/gem/ruby2html/component_helper.rb
|
100
|
+
- lib/gem/ruby2html/html_beautifier_middleware.rb
|
101
|
+
- lib/gem/ruby2html/rails_components/base_component.rb
|
102
|
+
- lib/gem/ruby2html/rails_components/button_to.rb
|
103
|
+
- lib/gem/ruby2html/rails_components/form_with.rb
|
104
|
+
- lib/gem/ruby2html/rails_components/image_tag.rb
|
105
|
+
- lib/gem/ruby2html/rails_components/link_to.rb
|
99
106
|
- lib/gem/ruby2html/rails_helper.rb
|
100
107
|
- lib/gem/ruby2html/railtie.rb
|
101
108
|
- lib/gem/ruby2html/render.rb
|