module YARD::Templates::Template
Attributes
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
Public Class Methods
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 37 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
@!parse extend ClassMethods @private
# File lib/yard/templates/template.rb, line 28 def included(klass) klass.extend(ClassMethods) end
# File lib/yard/templates/template.rb, line 178 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
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 194 def T(*path) path.unshift(options.template) if options.template path.push(options.format) if options.format self.class.T(*path) end
@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 275 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
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 YARD::Templates::Template::ClassMethods#find_file @see YARD::Templates::Template::ClassMethods#find_nth_file
# File lib/yard/templates/template.rb, line 302 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
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 229 def init end
# File lib/yard/templates/template.rb, line 332 def inspect "Template(#{self.class.path}) [section=#{section.name}]" end
# File lib/yard/templates/template.rb, line 327 def options=(value) @options = value set_ivars end
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 242 def run(opts = nil, sects = sections, start_at = 0, break_first = false, &block) out = "" 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
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 216 def sections(*args) @sections = Section.new(nil, *args) if args.size > 0 @sections end
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 320 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
Yields all subsections with any extra options
@param [Hash] opts extra options to be applied to subsections
# File lib/yard/templates/template.rb, line 268 def yieldall(opts = nil, &block) with_section { run(opts, section, &block) } end
Protected Instance Methods
# File lib/yard/templates/template.rb, line 338 def erb_file_for(section) "#{section}.erb" end
# File lib/yard/templates/template.rb, line 342 def erb_with(content, filename = nil) erb = ERB.new(content, nil, options.format == :text ? '<>' : nil) erb.filename = filename if filename erb end
Private Instance Methods
# File lib/yard/templates/template.rb, line 385 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
# File lib/yard/templates/template.rb, line 364 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
# File lib/yard/templates/template.rb, line 374 def cache_filename(section) @cache_filename[section.to_sym] ||= self.class.find_file(erb_file_for(section)) end
# File lib/yard/templates/template.rb, line 350 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
# File lib/yard/templates/template.rb, line 379 def set_ivars options.each do |k, v| instance_variable_set("@#{k}", v) end end
# File lib/yard/templates/template.rb, line 398 def with_section(&block) sect = section value = yield self.section = sect value end