Skip to content

Instantly share code, notes, and snippets.

@joshnesbitt
Created August 20, 2015 14:51
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 joshnesbitt/971770c415e6405dadbe to your computer and use it in GitHub Desktop.
Save joshnesbitt/971770c415e6405dadbe to your computer and use it in GitHub Desktop.
Example of a simple templating language written in Ruby.
class VariableLang
def initialize(path)
@path = path
@content = File.read(path)
end
def render(locals = {})
locals.inject(@content.dup) do |buffer, vars|
key = vars.first
value = vars.last
buffer.gsub(/@#{key}/, value)
end
end
end
template = VariableLang.new('template.var')
content = template.render(
to: 'Josh',
service: 'Sassy',
from: 'Sassy Team'
)
puts content
Hello @to,
Thanks for signing up to @service! You'll love it here.
Cheers,
@from
@joshnesbitt
Copy link
Author

And if you wanted to validate all variables have been replaced:

class VariableLang
  MissingVariableError = Class.new(Exception)

  def initialize(path, options = {})
    @path = path
    @content = File.read(path)
    @options = options
  end

  def render(locals = {})
    locals.inject(@content.dup) do |buffer, vars|
      buffer.gsub(/@#{vars[0]}/, vars[1])
    end.tap do |content|
      if @options[:raise_on_missing]
        unless (vars = fetch_missing_variables(content)).empty?
          raise(MissingVariableError, "Variables are present in the template that have not been replaced: #{vars.join(', ')}.")
        end
      end
    end
  end

private

  def fetch_missing_variables(content)
    matches = content.scan(/@\w+/)
    matches ? matches.to_a : []
  end
end

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