Inversion template tag node base class. Represents a directive in a template that defines behavior and/or state.
This class supports the RubyGems plugin API: to provide one or more Inversion tags in a gem of your own, put
them into a directory named ‘inversion/template’ and name the files
<tagname>tag.rb and the classes
<tagname.capitalize>Tag.
The glob pattern for matching template tag plugins
the body of the tag
Create a new Inversion::Template::Tag from the
specified tagname and body.
# File lib/inversion/template/tag.rb, line 117
def self::create( tagname, body, linenum=nil, colnum=nil )
tagname =~ %r^(\w+)$/ or raise ArgumentError, "invalid tag name %p" % [ tagname ]
tagtype = $1.downcase.untaint
unless tagclass = self.types[ tagtype.to_sym ]
Inversion.log.warn "Unknown tag type %p; registered: %p" %
[ tagtype, self.types.keys ]
return nil
end
return tagclass.new( body, linenum, colnum )
end
Inheritance hook – keep track of loaded derivatives.
# File lib/inversion/template/tag.rb, line 49
def self::inherited( subclass )
# Inversion.log.debug "%p inherited from %p" % [ subclass, self ]
Inversion::Template::Tag.derivatives << subclass
Inversion.log.debug "Loaded tag type %p" % [ subclass ]
super
end
Safely load the specified tagfile.
# File lib/inversion/template/tag.rb, line 104
def self::load( tagfile )
tagrequire = tagfile[ %r{inversion/template/\w+tag} ] or
raise "tag file %p doesn't look like a tag plugin" % [ tagfile ]
require( tagrequire )
rescue => err
Inversion.log.error "%s while loading tag plugin %p: %s" %
[ err.class.name, tagfile, err.message ]
Inversion.log.debug " " + err.backtrace.join( "\n " )
return false
end
Load all available template tags and return them as a Hash keyed by their name.
# File lib/inversion/template/tag.rb, line 65
def self::load_all
tags = {}
Gem.find_files( TAG_PLUGIN_PATTERN ).each do |tagfile|
tagname = tagfile[ %r{/(\w+)tag\.rb$}, 1 ].untaint
next unless tagname
self.load( tagfile )
# Inversion.log.debug "Looking for class for %p tag" % [ tagname ]
tagclass = self.derivatives.find do |derivclass|
if derivclass.name.nil? || derivclass.name.empty?
# Inversion.log.debug " skipping anonymous class %p" % [ derivclass ]
nil
elsif !derivclass.respond_to?( :new )
# Inversion.log.debug " skipping abstract class %p" % [ derivclass ]
nil
else
derivclass.name.downcase =~ %r\b#{tagname}tag$/
end
end
unless tagclass
Inversion.log.debug " no class found for %p tag" % [ tagname ]
next
end
Inversion.log.debug " found: %p" % [ tagclass ]
tags[ tagname.to_sym ] = tagclass
end
@types ||= {}
@types.merge!( tags )
return @types
end
Create a new Inversion::Template::Tag with the
specified body.
# File lib/inversion/template/tag.rb, line 136
def initialize( body, linenum=nil, colnum=nil )
super
@body = body.to_s.strip
end
Return a Hash of all loaded tag types, loading them if they haven’t been loaded already.
# File lib/inversion/template/tag.rb, line 58
def self::types
self.load_all unless @types
return @types
end
Render the tag as the body of a comment, suitable for template debugging.
# File lib/inversion/template/tag.rb, line 151
def as_comment_body
return "%s %s at %s" % [ self.tagname, self.body.to_s.dump, self.location ]
end
The Array of subclasses of this class
# File lib/inversion/template/tag.rb, line 45
singleton_attr_reader :derivatives
Return the human-readable name of the tag class
# File lib/inversion/template/tag.rb, line 157
def tagname
return self.class.name.sub(%rTag$/, '').sub( %r^.*::/, '' )
end
The hash of loaded tag types, keyed by the tag name as a Symbol
# File lib/inversion/template/tag.rb, line 41
singleton_attr_reader :types