Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Last active December 16, 2020 17:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenharman/a59df31a8ca9e7b099d060a248082c3a to your computer and use it in GitHub Desktop.
Save stevenharman/a59df31a8ca9e7b099d060a248082c3a to your computer and use it in GitHub Desktop.
Render Ruby ERB templates, inline, with variables bound and available local variables in the template. ✨ This technique is useful for rendering test fixtures via ERB, for example.
require "ostruct"
# A wrapper around a single ERB template that will bind the given Hash of values,
# making them available as local variables w/in the template.
class ErbNow < OpenStruct
# Render a given ERB +template+ string, binding the entries in the given +attrs+ Hash
# as local variables in the template, with the key as the variable name.
#
# @example
#
# template = <<~ERB
# <h1>Hello, <%= name %>!</h1>
# <p>The current time is: <time datetime="<%= timestamp %>"><%= timestamp.strftime("%d of %B, %Y")%></time>.</p>
# ERB
#
# ErbNow.render(template, name: "Alice", timestamp: Time.now)
#
# => <h1>Hello, Alice</h1>
# => <p>The current time is: <time datetime="2020-12-16 10:31:36 -0500">16 of December, 2020</time>.</p>
#
# @param [String] template An ERB template, as a String.
# @param [Hash] attrs A Hash of values to be bound to the template, with the key as the local name.
def self.render(template, attrs = {})
new(attrs).render(template)
end
def render(template)
ERB.new(template).result(binding)
end
end
@stevenharman
Copy link
Author

stevenharman commented Dec 16, 2020

This could be made more robust by accepting an IO-object, or a String-ish object as the template param. Something like

def render(template)
  template = template.read if template.respond_to?(:read)
  template = String(template)
  ERB.new(template).result(binding)
end

To date I've not needed this extra machinery, but please let me know if you do! I'm curious to know how others might use this technique.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment