Tag

class
Superclass
Inversion::Template::Node
Included Modules
Inversion::AbstractClass
Extended With
Loggability
Inversion::MethodUtilities

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

body[R]

the body of the tag

Public Class Methods

anchor
create( tagname, body, linenum=nil, colnum=nil )

Create a new Inversion::Template::Tag from the specified tagname and body.

# File lib/inversion/template/tag.rb, line 122
def self::create( tagname, body, linenum=nil, colnum=nil )
        tagname =~ /^(\w+)$/i 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
anchor
inherited( subclass )

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
anchor
load( tagfile )

Safely load the specified tagfile.

# File lib/inversion/template/tag.rb, line 109
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
anchor
load_all()

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 =~ /\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
anchor
new( body, linenum=nil, colnum=nil )

Create a new Inversion::Template::Tag with the specified body.

# File lib/inversion/template/tag.rb, line 141
def initialize( body, linenum=nil, colnum=nil )
        super
        @body = body.to_s.strip
end
anchor
types()

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

Public Instance Methods

anchor
as_comment_body()

Render the tag as the body of a comment, suitable for template debugging.

# File lib/inversion/template/tag.rb, line 156
def as_comment_body
        return "%s %s at %s" % [ self.tagname, self.body.to_s.dump, self.location ]
end
anchor
derivatives()

The Array of subclasses of this class

# File lib/inversion/template/tag.rb, line 45
singleton_attr_reader :derivatives
anchor
tagname()

Return the human-readable name of the tag class

# File lib/inversion/template/tag.rb, line 162
def tagname
        return self.class.name.sub(/Tag$/, '').sub( /^.*::/, '' )
end
anchor
types()

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