class Sho::Configurator

Main Sho object providing rendering method creation API.

There are three ways to create rendering methods:

@example

class AnyClass
  include Sho

  # `sho` returns an instance of Configurator
  sho.template :rendering_method_name, 'path/to/template.slim', :param1, param2: default_value
end

Attributes

base_folder[RW]

@return [String, nil] folder to look templates at for {#template} method. `nil` by default,

meaning application's current folder (`Dir.pwd`).
host[R]

@private

Public Class Methods

new(host) click to toggle source

@private

# File lib/sho/configurator.rb, line 31
def initialize(host)
  @host = host
end

Public Instance Methods

inline_template(name, *mandatory, _layout: nil, **options)
Alias for: template_inline
template(name, template, *mandatory, _layout: nil, **optional) click to toggle source

Generates instance method named `name` in a host module, which renders template from `template`. Instance of the host class is passed as a template scope on rendering.

Template is looked up relative to application's main folder, or {#base_folder}.

@example

# generates method with signature #profile()
sho.template :profile, 'app/views/users/profile.slim'

# generates method with signature #profile(context:, detailed: false)
# `context` and `detailed` vairables are accessible inside template.
sho.template :profile, 'app/views/users/profile.slim', :context, detailed: false

@param name [Symbol] name of method to generate; @param template [String] path to template to render; @param _layout [Symbol, nil] name of method which provides layout (wraps results of current

method);

@param mandatory [Array<Symbol>] list of mandatory params; @param optional [Hash{Symbol => Object}] list of optional params and their default values

# File lib/sho/configurator.rb, line 55
def template(name, template, *mandatory, _layout: nil, **optional)
  tpl = Tilt.new(File.expand_path(template, base_folder || Dir.pwd))
  define_template_method(name, tpl, mandatory, optional, _layout)
end
template_inline(name, *mandatory, _layout: nil, **options) click to toggle source

Inline rendering method definition, useful in decorators and other contexts with small templates.

@example

sho.inline_template :badge,
  slim: <<~SLIM
    span.badge
      span.name = user.name
      i.role(class: user.role)
  SLIM

@param name [Symbol] name of method to generate; @param _layout [Symbol, nil] name of method which provides layout (wraps results of current

method);

@param mandatory [Array<Symbol>] list of mandatory params; @param options [Hash{Symbol => Object}] list of optional params and their default values +

template to render (passed in a key named `slim:` or `erb:` or `haml:`, and so on).
# File lib/sho/configurator.rb, line 101
def template_inline(name, *mandatory, _layout: nil, **options)
  kind, template = options.detect { |key,| Tilt.registered?(key.to_s) }
  template or fail ArgumentError, "No known templates found in #{options.keys}"
  optional = options.reject { |key,| key == kind }
  tpl = Tilt.default_mapping[kind].new { template }

  define_template_method(name, tpl, mandatory, optional, _layout)
end
Also aliased as: inline_template
template_relative(name, template, *mandatory, _layout: nil, **optional) click to toggle source

Like {#template}, but looks up template relative to host module path. Allows to structure views like:

“` app/ +- view_models/

+- users.rb   # calls sho.template_relative :profile, 'users/profile.slim'
+- users/
   +- profile.slim

“`

@param name [Symbol] name of method to generate; @param template [String] path to template to render; @param _layout [Symbol, nil] name of method which provides layout (wraps results of current

method);

@param mandatory [Array<Symbol>] list of mandatory params; @param optional [Hash{Symbol => Object}] list of optional params and their default values

# File lib/sho/configurator.rb, line 77
def template_relative(name, template, *mandatory, _layout: nil, **optional)
  base = File.dirname(caller(1..1).first.split(':').first)
  tpl = Tilt.new(File.expand_path(template, base))

  define_template_method(name, tpl, mandatory, optional, _layout)
end

Private Instance Methods

define_template_method(name, tilt, mandatory, optional, layout) click to toggle source
# File lib/sho/configurator.rb, line 114
def define_template_method(name, tilt, mandatory, optional, layout)
  arguments = ArgumentValidator.new(*mandatory, **optional)
  @host.__send__(:define_method, name) do |**locals, &block|
    locals = arguments.call(**locals)
    if layout
      __send__(layout) { tilt.render(self, **locals) }
    else
      tilt.render(self, **locals, &block)
    end
  end
end