class Inversion::Template::Tag
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.
Constants
- TAG_PLUGIN_PATTERN
The glob pattern for matching template tag plugins
Attributes
the body of the tag
Public Class Methods
Create a new Inversion::Template::Tag
from the specified ‘tagname` and `body`.
# File lib/inversion/template/tag.rb, line 120 def self::create( tagname, body, linenum=nil, colnum=nil ) tagname =~ /^(\w+)$/i or raise ArgumentError, "invalid tag name %p" % [ tagname ] tagtype = $1.downcase 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 47 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 107 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 63 def self::load_all tags = {} Gem.find_files( TAG_PLUGIN_PATTERN ).each do |tagfile| tagname = tagfile[ %r{/(\w+?)_?tag\.rb$}, 1 ] 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 =~ /\b#{tagname.gsub('_', '')}tag$/ end end unless tagclass Inversion.log.debug " no class found for %p tag" % [ tagname ] next end Inversion.log.debug " found: %p" % [ tagclass ] snakecase_name = tagclass.name.sub( /^.*\b(\w+)Tag$/i, '\1' ) snakecase_name = snakecase_name.gsub( /([a-z])([A-Z])/, '\1_\2' ).downcase Inversion.log.debug " mapping %p to names: %p" % [ tagclass, snakecase_name ] tags[ snakecase_name.to_sym ] = tagclass tags[ snakecase_name.gsub('_', '').to_sym ] = tagclass end @types ||= {} @types.merge!( tags ) return @types end
Create a new Inversion::Template::Tag
with the specified ‘body`.
Inversion::Template::Node::new
# File lib/inversion/template/tag.rb, line 139 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 56 def self::types self.load_all unless @types return @types end
Public Instance Methods
Render the tag as the body of a comment, suitable for template debugging.
# File lib/inversion/template/tag.rb, line 154 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 43 singleton_attr_reader :derivatives
Return the human-readable name of the tag class
# File lib/inversion/template/tag.rb, line 160 def tagname return self.class.name.sub(/Tag$/, '').sub( /^.*::/, '' ) end
The hash of loaded tag types, keyed by the tag name as a Symbol
# File lib/inversion/template/tag.rb, line 39 singleton_attr_reader :types