Class: Inversion::Template::Tag
- Extended by:
- MethodUtilities, Loggability
- Includes:
- AbstractClass
- Defined in:
- lib/inversion/template/tag.rb
Overview
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.
Direct Known Subclasses
BeginTag, CodeTag, CommentTag, ConfigTag, ElseTag, EndTag, FragmentTag, ImportTag, IncludeTag, PublishTag, RescueTag, SubscribeTag, YieldTag
Constant Summary collapse
- TAG_PLUGIN_PATTERN =
The glob pattern for matching template tag plugins
'inversion/template/*tag.rb'
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
the body of the tag.
Attributes inherited from Node
Class Method Summary collapse
-
.create(tagname, body, linenum = nil, colnum = nil) ⇒ Object
Create a new Inversion::Template::Tag from the specified ‘tagname` and `body`.
-
.inherited(subclass) ⇒ Object
Inheritance hook – keep track of loaded derivatives.
-
.load(tagfile) ⇒ Object
Safely load the specified ‘tagfile`.
-
.load_all ⇒ Object
Load all available template tags and return them as a Hash keyed by their name.
-
.types ⇒ Object
Return a Hash of all loaded tag types, loading them if they haven’t been loaded already.
Instance Method Summary collapse
-
#as_comment_body ⇒ Object
Render the tag as the body of a comment, suitable for template debugging.
-
#derivatives ⇒ Object
The Array of subclasses of this class.
-
#initialize(body, linenum = nil, colnum = nil) ⇒ Tag
constructor
Create a new Inversion::Template::Tag with the specified ‘body`.
-
#tagname ⇒ Object
Return the human-readable name of the tag class.
-
#types ⇒ Object
The hash of loaded tag types, keyed by the tag name as a Symbol.
Methods included from MethodUtilities
singleton_attr_accessor, singleton_attr_reader, singleton_attr_writer
Methods included from AbstractClass
Methods included from AbstractClass::ClassMethods
Methods inherited from Node
#after_appending, #after_rendering, #before_appending, #before_rendering, #is_container?, #location, #render
Constructor Details
#initialize(body, linenum = nil, colnum = nil) ⇒ Tag
Create a new Inversion::Template::Tag with the specified ‘body`.
140 141 142 143 |
# File 'lib/inversion/template/tag.rb', line 140 def initialize( body, linenum=nil, colnum=nil ) super @body = body.to_s.strip end |
Instance Attribute Details
#body ⇒ Object (readonly)
the body of the tag
151 152 153 |
# File 'lib/inversion/template/tag.rb', line 151 def body @body end |
Class Method Details
.create(tagname, body, linenum = nil, colnum = nil) ⇒ Object
Create a new Inversion::Template::Tag from the specified ‘tagname` and `body`.
121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/inversion/template/tag.rb', line 121 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 |
.inherited(subclass) ⇒ Object
Inheritance hook – keep track of loaded derivatives.
48 49 50 51 52 53 |
# File 'lib/inversion/template/tag.rb', line 48 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 |
.load(tagfile) ⇒ Object
Safely load the specified ‘tagfile`.
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/inversion/template/tag.rb', line 108 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. ] Inversion.log.debug " " + err.backtrace.join( "\n " ) return false end |
.load_all ⇒ Object
Load all available template tags and return them as a Hash keyed by their name.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/inversion/template/tag.rb', line 64 def self::load_all = {} 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 ] [ snakecase_name.to_sym ] = tagclass [ snakecase_name.gsub('_', '').to_sym ] = tagclass end @types ||= {} @types.merge!( ) return @types end |
.types ⇒ Object
Return a Hash of all loaded tag types, loading them if they haven’t been loaded already.
57 58 59 60 |
# File 'lib/inversion/template/tag.rb', line 57 def self::types self.load_all unless @types return @types end |
Instance Method Details
#as_comment_body ⇒ Object
Render the tag as the body of a comment, suitable for template debugging.
155 156 157 |
# File 'lib/inversion/template/tag.rb', line 155 def as_comment_body return "%s %s at %s" % [ self.tagname, self.body.to_s.dump, self.location ] end |
#derivatives ⇒ Object
The Array of subclasses of this class
44 |
# File 'lib/inversion/template/tag.rb', line 44 singleton_attr_reader :derivatives |
#tagname ⇒ Object
Return the human-readable name of the tag class
161 162 163 |
# File 'lib/inversion/template/tag.rb', line 161 def tagname return self.class.name.sub(/Tag$/, '').sub( /^.*::/, '' ) end |
#types ⇒ Object
The hash of loaded tag types, keyed by the tag name as a Symbol
40 |
# File 'lib/inversion/template/tag.rb', line 40 singleton_attr_reader :types |