module Toys::Template

A template definition. Template classes should include this module.

A template is a configurable set of DSL code that can be run in a toys configuration to automate tool defintion. For example, toys provides a “minitest” template that generates a “test” tool that invokes minitest. Templates will often support configuration; for example the minitest template lets you configure the paths to the test files.

### Usage

To create a template, define a class and include this module. The class defines the “configuration” of the template. If your template has options/parameters, you should provide a constructor, and methods appropriate to edit those options. The arguments given to the {Toys::DSL::Tool#expand} method are passed to your constructor, and your template object is passed to any block given to {Toys::DSL::Tool#expand}.

Next, in your template class, call the `on_expand` method, which is defined in {Toys::Template::ClassMethods#on_expand}. Pass this a block which defines the implementation of the template. Effectively, the contents of this block are “inserted” into the user's configuration. The template object is passed to the block so you have access to the template options.

### Example

This is a simple template that generates a “hello” tool. The tool simply prints a `“Hello, #{name}!”` greeting. The name is set as a template option; it is defined when the template is expanded in a toys configuration.

# Define a template by creating a class that includes Toys::Template.
class MyHelloTemplate
  include Toys::Template

  # A user of the template may pass an optional name as a parameter to
  # `expand`, or leave it as the default of "world".
  def initialize(name: "world")
    @name = name
  end

  # The template is passed to the expand block, so a user of the
  # template may also call this method to set the name.
  attr_accessor :name

  # The following block is inserted when the template is expanded.
  on_expand do |template|
    desc "Prints a greeting to #{template.name}"
    tool "templated-greeting" do
      to_run do
        puts "Hello, #{template.name}!"
      end
    end
  end
end

Now you can use the template in your `.toys.rb` file like this:

expand(MyHelloTemplate, name: "rubyists")

or alternately:

expand(MyHelloTemplate) do |template|
  template.name = "rubyists"
end

And it will create a tool called “templated-greeting”.

Public Class Methods

create(&block) click to toggle source

Create a template class with the given block.

@param block [Proc] Defines the template class. @return [Class]

# File lib/toys/template.rb, line 79
def self.create(&block)
  template_class = ::Class.new do
    include ::Toys::Template
  end
  template_class.class_eval(&block) if block
  template_class
end
included(mod) click to toggle source

@private

# File lib/toys/template.rb, line 88
def self.included(mod)
  return if mod.respond_to?(:on_expand)
  mod.extend(ClassMethods)
  mod.include(Context::Key)
end