class Luigi::Template

Template class.

Parse a template string into a Luigi::Template instance, and then apply the Luigi::Template via the #run method.

Example:

# load luigi template
require 'luigi-template'

# create template
tmpl = Luigi::Template.new('hello %{name}')

# run template and print result
puts tmpl.run({
  name: 'Paul'
})

# prints "hello Paul"

You can also filter values in templates, using the pipe symbol:

# create template that converts name to upper-case
tmpl = Luigi::Template.new('hello %{name | uc}')

# run template and print result
puts tmpl.run({
  name: 'Paul'
})

# prints "hello PAUL"

Filters can be chained:

# create template that converts name to upper-case and then
# strips leading and trailing whitespace
tmpl = Luigi::Template.new('hello %{name | uc | trim}')

# run template and print result
puts tmpl.run({
  name: '   Paul    '
})

# prints "hello PAUL"

Filters can take arguments:

# create template that converts name to lowercase and then
# calculates the SHA-1 digest of the result
tmpl = Luigi::Template.new('hello %{name | lc | hash sha1}')

# run template and print result
puts tmpl.run({
  name: 'Paul',
})

# prints "hello a027184a55211cd23e3f3094f1fdc728df5e0500"

You can define custom global filters:

# create custom global filter named 'foobarify'
Luigi::FILTERS[:foobarify] = proc { |s| "foo-#{s}-bar" }

# create template which uses custom "foobarify" filter
tmpl = Luigi::Template.new('hello %{name | foobarify}')

# run template and print result
puts tmpl.run({
  name: 'Paul'
})

# prints "hello foo-Paul-bar"

Or define custom filters for a template:

# create template with custom filters rather than global filters
tmpl = Luigi::Template.new('hello %{name | reverse}', {
  reverse: proc { |s| s.reverse }
})

# run template and print result
puts tmpl.run({
  name: 'Paul',
})

# prints "hello luaP"

Your custom filters can accept arguments, too:

# create custom global filter named 'foobarify'
Luigi::FILTERS[:wrap] = proc { |s, args|
  case args.length
  when 2
    '(%s, %s, %s)' % [args[0], s, args[1]]
  when 1
    '(%s in %s)' % [s, args[0]]
  when 0
    s
  else
    raise 'invalid argument count'
  end
}

# create template that uses custom "wrap" filter
tmpl = Luigi::Template.new('sandwich: %{meat | wrap slice heel}, taco: %{meat | wrap shell}')

# run template and print result
puts tmpl.run({
  meat: 'chicken'
})

# prints "sandwich: (slice, chicken, heel), taco: (chicken in shell)"

Attributes

str[R]

Original template string.

Public Class Methods

new(str, filters = FILTERS) click to toggle source

Create a new Template from the given string.

# File lib/luigi-template.rb, line 725
def initialize(str, filters = FILTERS)
  @str, @filters = str.freeze, filters
  @actions = Parser.parse_template(str).freeze
end
run(str, args = {}, filters = FILTERS) click to toggle source

Create a new template, expand it with the given arguments and filters, and print the result.

Parameters:

  • str: Template string.

  • args: Argument key/value map.

  • filters: Hash of filters. Defaults to Luigi::FILTERS if unspecified.

Example:

# create a template object, expand it, and print the result
puts Luigi::Template.run('hello %{name}', {
  name: 'Paul'
})

# prints "hello Paul"
# File lib/luigi-template.rb, line 718
def self.run(str, args = {}, filters = FILTERS)
  Template.new(str, filters).run(args)
end

Public Instance Methods

'%'(args)
Alias for: run
run(args) click to toggle source

Expand template with the given arguments and return the result.

Parameters:

  • args: Argument key/value map.

Example:

# create a template object
tmpl = Luigi::Template.new('hello %{name}')

# apply template, print result
puts tmpl.run({ name: 'Paul'})

# prints "hello Paul"

This method is aliased as “%”, so you can do this:

# create template
tmpl = Luigi::Template.new('hello %{name | uc}')

# run template and print result
puts tmpl % { name: 'Paul' }

# prints "hello PAUL"
# File lib/luigi-template.rb, line 757
def run(args)
  @actions.map { |a|
    # pp a

    case a[:type]
    when :action
      # check key and get value
      val = if args.key?(a[:key])
        args[a[:key]]
      elsif args.key?(a[:key].to_s)
        args[a[:key].to_s]
      else
        # invalid key
        raise UnknownKeyError.new(a[:key])
      end

      # filter value
      a[:filters].inject(val) do |r, f|
        # check filter name
        unless @filters.key?(f[:name])
          raise UnknownFilterError.new(f[:name])
        end

        # call filter, return result
        @filters[f[:name]].call(r, f[:args], args, self)
      end
    when :text
      # literal text
      a[:text]
    else
      # never reached
      raise "unknown action type: #{a[:type]}"
    end
  }.join
end
Also aliased as: '%'
to_s() click to toggle source

Return the input template string.

Example:

# create a template object
tmpl = Luigi::Template.new('hello %{name}')

# create a template object
puts tmpl.to_s

# prints "hello %{name}"
# File lib/luigi-template.rb, line 808
def to_s
  @str
end