I've written an internal standalone gem that generates PDF with Gotenberg rendering an ERB HTML template dynamically. This permits to actually generate a PDF outside a controller context for any possible reason, like reports etc.
This is achieved with inline code. For example:
ERB.new(template).result(binding)
When using render inside a template, i get undefined method 'render', cause of course it's not in the current binding. My goal is to use the existing partial rendering process.
Consider having these three templates:
_header.html.erb
<h1>My Header</h1>
_footer.html.erb
<p>My Footer</p>
layout.html.erb
<body>
  <%= render 'header' %>
  <%= yield %>
  <%= render 'footer' %>
</body>
Is there any way to achieve this?
Not completely sure about how you intend to use it but, this works for similar needs.
Assuming a folder structure like this:
.
├── app.rb
└── views
    ├── _footer.erb
    ├── _header.erb
    ├── _index.erb
    └── layout.erb
...You can build a small templating engine in ERB like this, inside app.rb
require 'erb'
require 'date'
class SimpleTemplate
  attr_reader :views
  
  def initialize(views: 'views')
    @views = views
  end
  def render(template_name, locals = {})
    path = File.join(views, "#{template_name}.erb")
    html = erb(path, locals)
    layout = File.join(views,"layout.erb")
    File.exist?(layout) ? erb(layout, locals.merge(content: html)) : html
  end
  private
  def erb(path, locals)
    return "" unless File.exist?(path)
    b = binding
    locals.transform_keys(&:to_sym).each { |k, v| b.local_variable_set(k, v) }
    ERB.new(File.read(path), trim_mode: '-').result(b)
  end
  def render_partial(name)
    path = "#{views}/#{name}"
    File.exist?(path) ? erb(path, {}) : ""
  end
end
Test it with puts SimpleTemplate.new.render('_index')
The content of views/_index.erb
<main>
  <section>
    <p>Contenuto principale della pagina.</p>
    <p>Oggi è <%= Date.today %>.</p>
  </section>
</main>
... views/layout.erb
<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="UTF-8">
  <title>Il mio sito</title>
</head>
<body>
  <%= render_partial('_header.erb') %>
  <%= content %>
  <%= render_partial('_footer.erb') %>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With