DEV Community

sebyx07
sebyx07

Posted on

Ruby2html: Streamline Your Rails Views with Pure Ruby

https://github.com/sebyx07/ruby2html

As a Rails developer, I've often found myself wrestling with the limitations of ERB templates. The constant context switching between Ruby and HTML can be jarring, and complex logic in views can quickly become unwieldy. That's why I was excited to discover Ruby2html, a gem that allows you to write your entire view logic in pure Ruby.

The Power of Ruby in Your Views

Ruby2html isn't just another templating engine – it's a different approach to writing views. Instead of mixing Ruby and HTML, you write your entire view in Ruby, which is then transformed into clean, semantic HTML. This approach brings several benefits:

  1. Consistent syntax: No more switching between Ruby and HTML syntax.
  2. Full access to Ruby's features: Use all of Ruby's powerful methods and constructs in your views.
  3. Improved readability: Your views become as clear and expressive as your Ruby code.

Here's an example of what a view looks like with Ruby2html:

div class: 'container' do
  h1 'Welcome to Ruby2html', class: 'main-title', 'data-controller': 'welcome'

  @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
end
Enter fullscreen mode Exit fullscreen mode

Notice how we're using object methods (item.title) instead of hash syntax. This aligns better with Ruby conventions and provides better IDE support.

Gradual Adoption and Seamless Integration

One of Ruby2html's strengths is its ability to coexist with your current ERB templates. You don't need to rewrite your entire application at once. Instead, you can adopt Ruby2html gradually, allowing for a smooth transition:

<h1>Welcome to our evolving page</h1>

<%= render partial: 'legacy_erb_partial' %>

<%=
  html(self) do
    div class: 'ruby2html-section' do
      h2 "This section uses Ruby2html"
      p "It integrates seamlessly with existing ERB"
    end
  end
%>

<%= render ModernComponent.new %>
Enter fullscreen mode Exit fullscreen mode

This flexibility means you can start benefiting from Ruby2html immediately in new views or components, while gradually refactoring existing ones as time allows.

ViewComponent Compatibility

If you're using ViewComponents (which I highly recommend), Ruby2html integrates smoothly. You can use Ruby2html syntax in your call method or stick with traditional .erb template files:

class GreetingComponent < ApplicationComponent
  def initialize(name)
    @name = name
  end

  def call
    html do
      h1 class: 'greeting', 'data-user': @name do
        "Hello, #{@name}!"
      end
      p class: 'welcome-message' do
        'Welcome to Ruby2html'
      end
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

This compatibility allows you to leverage Ruby2html where it makes the most sense in your application architecture.

Performance Considerations

When adopting a new view rendering approach, performance is always a concern. In my testing, I've found that Ruby2html performs comparably to traditional ERB templates:

Comparison:
GET /benchmark/html (ERB):       21.0 i/s
GET /benchmark/ruby (Ruby2html): 20.4 i/s - difference falls within error margin
Enter fullscreen mode Exit fullscreen mode

These benchmarks suggest that you can adopt Ruby2html without significant performance impact.

Getting Started

To start using Ruby2html in your Rails project, add this line to your Gemfile:

gem 'ruby2html'
Enter fullscreen mode Exit fullscreen mode

Then, you can start writing your views in Ruby. I recommend starting with a small, isolated component to get a feel for the syntax and workflow.

Real-world Experience

In my recent project, a complex dashboard application, I used Ruby2html for all new views. The transition was smooth, and I noticed several benefits:

  1. Reduced cognitive load: Writing views in pure Ruby eliminated the mental context switching between Ruby and HTML.
  2. Improved maintainability: Views became easier to refactor and test, as they're now just Ruby code.
  3. Enhanced reusability: It became simpler to extract common patterns into helper methods or components.

However, it's worth noting that there was a learning curve for the team. Developers needed time to adjust to thinking about HTML structure in terms of Ruby methods. We found that pair programming sessions were particularly helpful during this transition.

Conclusion

Ruby2html offers a compelling alternative to traditional ERB templates in Rails. By allowing you to write your views in pure Ruby, it brings consistency, power, and improved maintainability to your frontend code.

While it may not be the right choice for every project, I've found it particularly beneficial in applications with complex view logic or those heavily utilizing ViewComponents.

I encourage you to give Ruby2html a try in your next Rails project. Start small, perhaps with a single component, and see how it fits into your workflow. You might find, as I did, that it significantly improves your view-writing experience.

Check out the Ruby2html GitHub repo to get started, and feel free to share your experiences or ask questions in the comments. Happy coding!

Top comments (1)

Collapse
 
andyobtiva profile image
Andy Maleh

Thank you! This is awesome! I have been a proponent of the Markaby-like approach for a while now. Glimmer DSL for Web (open-source gem) also supports a Ruby DSL for HTML, but on the Frontend side of a Rails application as a replacement for Frontend JS libraries like React, Vue, Svelte, Ember, and Angular. It provides full support for components, element listeners, and unidirectional/bidirectional data-binding as part of the HTML DSL.
Check it out here:
github.com/AndyObtiva/glimmer-dsl-web
I think Ruby2html and Glimmer DSL for Web could be used side-by-side in a Rails web app whereby Ruby2html handles Backend rendering of full webpages and Glimmer DSL for Web handles Frontend rendering of interactive parts of webpages.
The possibilities are endless!