Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Ruby2html 🔮✨

Transform your view logic into elegant, semantic HTML with the power of pure Ruby! 🚀✨

🌟 What is Ruby2html?

Ruby2html is a magical gem that allows you to write your views in pure Ruby and automatically converts them into clean, well-formatted HTML. Say goodbye to messy ERB templates and hello to the full power of Ruby in your views! 🎉

🚀 Installation

Add this line to your application's Gemfile:

gem'ruby2html'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install ruby2html

🎨 Usage

In your views

File: app/views/your_view.html.rb

divclass: 'container'doh1'Welcome to Ruby2html! 🎉',class: 'main-title','data-controller': 'welcome'link_to'Home Sweet Home 🏠',root_path,class: 'btn btn-primary','data-turbo': false@products.eachdo |product|
h2class: 'item-title',id: "product-#{product[:id]}"doproduct.titleendpclass: 'item-description'doproduct.descriptionendendendplain'<div>Inline html</div>'.html_saferenderpartial: 'shared/navbar'

(Optional) Nicely Format the HTML for source inspection

File: config/environments/development.rb or config/environments/test.rb

config.middleware.useRuby2html::HtmlBeautifierMiddleware

Or use your current .erb views

In your ApplicationController

File: app/controllers/application_controller.rb

# frozen_string_literal: trueclassApplicationController < ActionController::BaseincludeRuby2html::RailsHelper# to access the <%= html %> helperend

File: app/views/your_view.html.erb

Replace your ERB with beautiful Ruby code:

<%=
html(self) do
h1 "Welcome to Ruby2html! 🎉", class: 'main-title', 'data-controller': 'welcome'
div id: 'content', class: 'container' do
link_to 'Home Sweet Home 🏠', root_path, class: 'btn btn-primary', 'data-turbo': false
end
@items.each do |item|
h2 class: 'item-title', id: "item-#{item[:id]}" do
item.title
end
p class: 'item-description' do
item.description
end
end
plain "<div>Inline html</div>".html_safe
render partial: 'shared/navbar'
end
%>

Benchmark

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
GET /benchmark/html (ERB)
32.000 i/100ms
GET /benchmark/ruby (Ruby2html templates .html.rb)
17.000 i/100ms
GET /benchmark/ruby (Ruby2html + view components)
12.000 i/100ms
GET /benchmark/slim (Slim)
36.000 i/100ms
GET /benchmark/phlex (Phlex)
28.000 i/100ms
Calculating -------------------------------------
GET /benchmark/html (ERB)
330.530 (± 2.4%) i/s - 19.840k in 60.061301s
GET /benchmark/ruby (Ruby2html templates .html.rb)
180.060 (± 1.7%) i/s - 10.812k in 60.068993s
GET /benchmark/ruby (Ruby2html + view components)
121.379 (± 2.5%) i/s - 7.284k in 60.055909s
GET /benchmark/slim (Slim)
367.488 (± 2.2%) i/s - 22.068k in 60.078459s
GET /benchmark/phlex (Phlex)
284.998 (± 1.8%) i/s - 17.108k in 60.047103s
Comparison:
GET /benchmark/slim (Slim): 367.5 i/s
GET /benchmark/html (ERB): 330.5 i/s - 1.11x slower
GET /benchmark/phlex (Phlex): 285.0 i/s - 1.29x slower
GET /benchmark/ruby (Ruby2html templates .html.rb): 180.1 i/s - 2.04x slower
GET /benchmark/ruby (Ruby2html + view components): 121.4 i/s - 3.03x slower

With ViewComponents

Ruby2html seamlessly integrates with ViewComponents, offering flexibility in how you define your component's HTML structure. You can use the call method with Ruby2html syntax, or stick with traditional .erb template files.

File: app/components/application_component.rb

# frozen_string_literal: trueclassApplicationComponent < ViewComponent::BaseincludeRuby2html::ComponentHelperend

Option 1: Using call method with Ruby2html

File: app/components/greeting_component.rb

# frozen_string_literal: trueclassGreetingComponent < ApplicationComponentdefinitialize(name)@name=nameenddefcallhtmldoh1class: 'greeting','data-user': @namedo"Hello, #{@name}! 👋"endpclass: 'welcome-message'do'Welcome to the wonderful world of Ruby2html!'endendendend

Option 2: Using traditional ERB template

File: app/components/farewell_component.rb

# frozen_string_literal: trueclassFarewellComponent < ApplicationComponentdefinitialize(name)@name=nameendend

File: app/components/farewell_component.html.rb

divclass: 'farewell'doh1class: 'farewell-message'do"Goodbye, #{@name}! 👋"endpclass: 'farewell-text'do'We hope to see you again soon!'endend

This flexibility allows you to:

  • Use Ruby2html syntax for new components or when refactoring existing ones
  • Keep using familiar ERB templates where preferred
  • Mix and match approaches within your application as needed

More Component Examples

File: app/components/first_component.rb

# frozen_string_literal: trueclassFirstComponent < ApplicationComponentdefinitialize@item='Hello, World!'enddefcallhtmldoh1id: 'first-component-title'do'first component'enddivclass: 'content-wrapper'doh2'A subheading'endpclass: 'greeting-text','data-testid': 'greeting'do@itemendendendend

File: app/components/second_component.rb

# frozen_string_literal: trueclassSecondComponent < ApplicationComponentdefcallhtmldoh1class: 'my-class',id: 'second-component-title','data-controller': 'second'do'second component'endlink_to'Home',root_path,class: 'nav-link','data-turbo-frame': falseendendend

Without Rails

renderer=Ruby2html::Render.new(nil)do# context by default is nil, you can use self or any other objecthtmldoheaddotitle'Ruby2html Example'endbodydoh1'Hello, World!'endendendputsrenderer.render# => "<html><head><title>Ruby2html Example</title></head><body><h1>Hello, World!</h1></body></html>"

🐢 Gradual Adoption

One of the best features of Ruby2html is that you don't need to rewrite all your views at once! You can adopt it gradually, mixing Ruby2html with your existing ERB templates. This allows for a smooth transition at your own pace.

Mixed usage example

File: app/views/your_mixed_view.html.erb

<h1>Welcome to our gradually evolving page!</h1><%=renderpartial: 'legacy_erb_partial'%><%=html(self)dodivclass: 'ruby2html-section'doh2"This section is powered by Ruby2html!"p"Isn't it beautiful? 😍"endend%><%=renderModernComponent.new%><footer><!-- More legacy ERB code --></footer>

In this example, you can see how Ruby2html seamlessly integrates with existing ERB code. This approach allows you to:

  • Keep your existing ERB templates and partials
  • Gradually introduce Ruby2html in specific sections
  • Use Ruby2html in new components while maintaining older ones
  • Refactor your views at your own pace

Remember, there's no rush! You can keep your .erb files and Ruby2html code side by side until you're ready to fully transition. This flexibility ensures that adopting Ruby2html won't disrupt your existing workflow or require a massive rewrite of your application. 🌈

⚡ Performance

Ruby2html features extensive C extension optimizations for high-performance HTML generation:

Benchmark Results (50 users × 1-5 orders × 1-10 items)

Ruby 3.4.7 +YJIT (After Optimizations)

Slim: 367.5 i/s - fastest
ERB: 330.5 i/s - 1.11x slower
Phlex: 285.0 i/s - 1.29x slower
Ruby2html templates: 180.1 i/s - 2.04x slower
Ruby2html components:121.4 i/s - 3.03x slower

Improvement on Ruby 3.3.4 baseline: 125.0 → 180.1 i/s = 44% faster!Gap to Phlex narrowed: From 2.63x slower to only 1.58x slower (180.1 vs 285.0 i/s)

Performance varies by Ruby version. The results above are on Ruby 3.4.7.

C Extension + Phlex-Inspired Optimizations

  1. SIMD HTML Escaping (SSE4.2)

    • Vectorized character scanning (16 bytes at once)
    • 3-10x faster for clean strings
    • Early exit fast path for content without special characters
  2. Optimized Tag Generation

    • Complete tag rendering in C
    • Pre-allocated buffers with size estimation
    • 2-3x faster than pure Ruby
  3. Attribute Caching (Phlex-inspired)

    • Global cache by options.hash
    • Frozen strings for zero-copy cache hits
    • 32% faster on attribute-heavy rendering
    • Eliminates regenerating identical attribute combinations
  4. Specialized Code Paths (Phlex-inspired)

    • Separate fast paths for ±attributes, ±block
    • Early returns for common cases
    • Direct buffer operations with chained <<
    • 17% faster on complex nested structures
  5. Direct Hash Iteration

    • Uses rb_hash_foreach instead of array allocation
    • 30% fewer allocations for attributes
  6. Lookup Table Escaping

    • Branch-free character lookups
    • Zero branch mispredictions
    • 4-5% faster than switch statements
  7. Type & Compiler Optimizations

    • Proper size_t usage for lengths/indices
    • restrict keyword for non-aliasing pointers
    • __attribute__((always_inline)) for hot paths
    • Loop unrolling by 4
  8. Optimized Template Usage

    • Direct string arguments instead of plain method
    • Eliminates unnecessary method call overhead
    • 78% improvement in template rendering speed

Performance vs Phlex

While Ruby2html is slower than Phlex in benchmarks, the difference is architectural rather than optimization-related:

  • Phlex advantage: Direct instantiation, no Rails template overhead
  • Ruby2html focus: Rails integration, automatic escaping, template-based architecture

See PERFORMANCE_ANALYSIS.md for detailed analysis.

When to Choose Ruby2html

  • ✅ Need .html.rb template files (Rails conventions)
  • ✅ Want automatic HTML escaping (security-first)
  • ✅ Prefer template-based architecture
  • ✅ Working with existing Rails views/controllers

🛠 Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

🤝 Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/ruby2html. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

📜 License

The gem is available as open source under the terms of the MIT License.

🌈 Code of Conduct

Everyone interacting in the Ruby2html project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

🌟 Features

  • Write views in pure Ruby 💎
  • Seamless Rails integration 🛤️
  • ViewComponent support with flexible template options 🧩
  • Automatic HTML beautification 💅
  • Easy addition of custom attributes and data attributes 🏷️
  • Gradual adoption - mix with existing ERB templates 🐢
  • Improved readability and maintainability 📚
  • Full access to Ruby's power in your views 💪

Start writing your views in Ruby today and experience the magic of Ruby2html! ✨🔮

About

Rails views with ruby

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages