module YARD::Templates::Template

Attributes

extra_includes[RW]

Extra includes are mixins that are included after a template is created. These mixins can be registered by plugins to operate on templates and override behaviour.

Note that this array can be filled with modules or proc objects. If a proc object is given, the proc will be called with the {Template#options} hash containing relevant template information like the object, format, and more. The proc should return a module or nil if there is none.

@example Adding in extra mixins to include on a template

Template.extra_includes << MyHelper

@example Conditionally including a mixin if the format is html

Template.extra_includes << proc {|opts| MyHelper if opts.format == :html }

@return [Array<Module, Proc>] a list of modules to be automatically included

into any new template module
class[RW]
options[R]
section[RW]

Public Class Methods

include_extra(template, options) click to toggle source

Includes the {extra_includes} modules into the template object.

@param [Template] template the template object to mixin the extra includes. @param [SymbolHash] options the options hash containing all template information @return [void]

# File lib/yard/templates/template.rb, line 38
def include_extra(template, options)
  extra_includes.each do |mod|
    mod = mod.call(options) if mod.is_a?(Proc)
    next unless mod.is_a?(Module)
    template.extend(mod)
  end
end
included(klass) click to toggle source

@!parse extend ClassMethods @private

# File lib/yard/templates/template.rb, line 29
def included(klass)
  klass.extend(ClassMethods)
end
new(opts = TemplateOptions.new) click to toggle source
# File lib/yard/templates/template.rb, line 186
def initialize(opts = TemplateOptions.new)
  opts_class = opts.class
  opts_class = TemplateOptions if opts_class == Hash
  @cache = {}
  @cache_filename = {}
  @sections = []
  @options = opts_class.new
  add_options(opts)
  Template.include_extra(self, options)
  init
end

Public Instance Methods

T(*path) click to toggle source

Loads a template specified by path. If :template or :format is specified in the {#options} hash, they are prepended and appended to the path respectively.

@param [Array<String, Symbol>] path the path of the template @return [Template] the loaded template module

# File lib/yard/templates/template.rb, line 204
def T(*path) # rubocop:disable Style/MethodName
  path.unshift(options.template) if options.template
  path.push(options.format) if options.format
  self.class.T(*path)
end
erb(section, &block) click to toggle source

@param [String, Symbol] section the section name @yield calls subsections to be rendered @return [String] the contents of the ERB rendered section

# File lib/yard/templates/template.rb, line 285
def erb(section, &block)
  method_name = ErbCache.method_for(cache_filename(section)) do
    erb_with(cache(section), cache_filename(section))
  end
  send(method_name, &block)
end
file(basename, allow_inherited = false) click to toggle source

Returns the contents of a file. If allow_inherited is set to true, use +{{{__super__}}}+ inside the file contents to insert the contents of the file from an inherited template. For instance, if templates/b inherits from templates/a and file “test.css” exists in both directories, both file contents can be retrieved by having templates/b/test.css look like:

{{{__super__}}}
...
body { css styles here }
p.class { other styles }

@param [String] basename the name of the file @param [Boolean] allow_inherited whether inherited templates can

be inserted with +{{{__super__}}}+

@return [String] the contents of a file identified by basename. All

template paths (including any mixed in templates) are searched for
the file

@see ClassMethods#find_file @see ClassMethods#find_nth_file

# File lib/yard/templates/template.rb, line 312
def file(basename, allow_inherited = false)
  file = self.class.find_file(basename)
  raise ArgumentError, "no file for '#{basename}' in #{self.class.path}" unless file

  data = IO.read(file)
  if allow_inherited
    superfile = self.class.find_nth_file(basename, 2)
    data.gsub!('{{{__super__}}}', superfile ? IO.read(superfile) : "")
  end

  data
end
init() click to toggle source

Initialization called on the template. Override this in a ‘setup.rb’ file in the template’s path to implement a template

@example A default set of sections

def init
  sections :section1, :section2, [:subsection1, :etc]
end

@see sections

# File lib/yard/templates/template.rb, line 239
def init
end
inspect() click to toggle source
# File lib/yard/templates/template.rb, line 342
def inspect
  "Template(#{self.class.path}) [section=#{section.name}]"
end
options=(value) click to toggle source
# File lib/yard/templates/template.rb, line 337
def options=(value)
  @options = value
  set_ivars
end
run(opts = nil, sects = sections, start_at = 0, break_first = false, &block) click to toggle source

Runs a template on sects using extra options. This method should not be called directly. Instead, call the class method {ClassMethods#run}

@param [Hash, nil] opts any extra options to apply to sections @param [Section, Array] sects a section list of sections to render @param [Fixnum] start_at the index in the section list to start from @param [Boolean] break_first if true, renders only the first section @yield [opts] calls for the subsections to be rendered @yieldparam [Hash] opts any extra options to yield @return [String] the rendered sections joined together

# File lib/yard/templates/template.rb, line 252
def run(opts = nil, sects = sections, start_at = 0, break_first = false, &block)
  out = String.new("")
  return out if sects.nil?
  sects = sects[start_at..-1] if start_at > 0
  sects = Section.new(nil, sects) unless sects.is_a?(Section)
  add_options(opts) do
    sects.each do |s|
      self.section = s
      subsection_index = 0
      value = render_section(section) do |*args|
        value = with_section do
          run(args.first, section, subsection_index, true, &block)
        end
        subsection_index += 1
        value
      end
      out << (value || "")
      break if break_first
    end
  end
  out
end
sections(*args) click to toggle source

Sets the sections (and subsections) to be rendered for the template

@example Sets a set of erb sections

sections :a, :b, :c # searches for a.erb, b.erb, c.erb

@example Sets a set of method and erb sections

sections :a, :b, :c # a is a method, the rest are erb files

@example Sections with subsections

sections :header, [:name, :children]
# the above will call header.erb and only renders the subsections
# if they are yielded by the template (see #yieldall)

@param [Array<Symbol, String, Template, Array>] args the sections

to use to render the template. For symbols and strings, the
section will be executed as a method (if one exists), or rendered
from the file "name.erb" where name is the section name. For
templates, they will have {Template::ClassMethods#run} called on them.
Any subsections can be yielded to using yield or {#yieldall}
# File lib/yard/templates/template.rb, line 226
def sections(*args)
  @sections = Section.new(nil, *args) unless args.empty?
  @sections
end
superb(sect = section, &block) click to toggle source

Calls the ERB file from the last inherited template with {#section}.erb

@param [Symbol, String] sect if provided, uses a specific section name @return [String] the rendered ERB file in any of the inherited template

paths.
# File lib/yard/templates/template.rb, line 330
def superb(sect = section, &block)
  filename = self.class.find_nth_file(erb_file_for(sect), 2)
  return "" unless filename
  method_name = ErbCache.method_for(filename) { erb_with(IO.read(filename), filename) }
  send(method_name, &block)
end
yieldall(opts = nil, &block) click to toggle source

Yields all subsections with any extra options

@param [Hash] opts extra options to be applied to subsections

# File lib/yard/templates/template.rb, line 278
def yieldall(opts = nil, &block)
  with_section { run(opts, section, &block) }
end

Protected Instance Methods

erb_file_for(section) click to toggle source
# File lib/yard/templates/template.rb, line 348
def erb_file_for(section)
  "#{section}.erb"
end
erb_with(content, filename = nil) click to toggle source
# File lib/yard/templates/template.rb, line 352
def erb_with(content, filename = nil)
  erb = if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
          ERB.new(content, :trim_mode => options.format == :text ? '<>' : nil)
        else
          ERB.new(content, nil, options.format == :text ? '<>' : nil)
        end
  erb.filename = filename if filename
  erb
end

Private Instance Methods

add_options(opts = nil) { || ... } click to toggle source
# File lib/yard/templates/template.rb, line 399
def add_options(opts = nil)
  return(yield) if opts.nil? && block_given?
  cur_opts = options if block_given?

  self.options = options.merge(opts)

  if block_given?
    value = yield
    self.options = cur_opts
    value
  end
end
cache(section) click to toggle source
# File lib/yard/templates/template.rb, line 378
def cache(section)
  content = @cache[section.to_sym]
  return content if content

  file = cache_filename(section)
  @cache_filename[section.to_sym] = file
  raise ArgumentError, "no template for section '#{section}' in #{self.class.path}" unless file
  @cache[section.to_sym] = IO.read(file)
end
cache_filename(section) click to toggle source
# File lib/yard/templates/template.rb, line 388
def cache_filename(section)
  @cache_filename[section.to_sym] ||=
    self.class.find_file(erb_file_for(section))
end
render_section(section, &block) click to toggle source
# File lib/yard/templates/template.rb, line 364
def render_section(section, &block)
  section = section.name if section.is_a?(Section)
  case section
  when Section, String, Symbol
    if respond_to?(section)
      send(section, &block)
    else
      erb(section, &block)
    end
  when Module, Template
    section.run(options, &block) if section.is_a?(Template)
  end || ""
end
set_ivars() click to toggle source
# File lib/yard/templates/template.rb, line 393
def set_ivars
  options.each do |k, v|
    instance_variable_set("@#{k}", v)
  end
end
with_section() { || ... } click to toggle source
# File lib/yard/templates/template.rb, line 412
def with_section
  sect = section
  value = yield
  self.section = sect
  value
end