Parent

Class Index [+]

Quicksearch

Webgen::ContentProcessor::Tags

Processes special webgen tags to provide dynamic content.

webgen tags are an easy way to add dynamically generated content to websites, for example menus or breadcrumb trails.

Constants

BRACKETS_RE
ProcessingStruct

Public Instance Methods

call(context) click to toggle source

Replace all webgen tags in the content of context with the rendered content.

    # File lib/webgen/contentprocessor/tags.rb, line 24
24:     def call(context)
25:       replace_tags(context) do |tag, param_string, body|
26:         log(:debug) { "Replacing tag #{tag} with data '#{param_string}' and body '#{body}' in <#{context.ref_node}>" }
27:         process_tag(tag, param_string, body, context)
28:       end
29:       context
30:     end
process_tag(tag, params, body, context) click to toggle source

Process the tag and return the result. The parameter params needs to be a Hash holding all needed and optional parameters for the tag or a parameter String in YAML format and body is the optional body for the tag. context needs to be a valid Webgen::Context object.

    # File lib/webgen/contentprocessor/tags.rb, line 35
35:     def process_tag(tag, params, body, context)
36:       result = ''
37:       processor = processor_for_tag(tag)
38:       if !processor.nil?
39:         params = if params.kind_of?(String)
40:                    processor.create_tag_params(params, context.ref_node)
41:                  else
42:                    processor.create_params_hash(params, context.ref_node)
43:                  end
44: 
45:         processor.set_params(params)
46:         result, process_output = processor.call(tag, body, context)
47:         processor.set_params(nil)
48:         result = call(context.clone(:content => result)).content if process_output
49:       else
50:         raise Webgen::RenderError.new("No tag processor for '#{tag}' found", self.class.name,
51:                                       context.dest_node, context.ref_node)
52:       end
53:       result
54:     end

Private Instance Methods

processor_for_tag(tag) click to toggle source

Return the tag processor for tag or nil if tag is unknown.

     # File lib/webgen/contentprocessor/tags.rb, line 156
156:     def processor_for_tag(tag)
157:       map = website.config['contentprocessor.tags.map']
158:       klass = if map.has_key?(tag)
159:                 map[tag]
160:               elsif map.has_key?(:default)
161:                 map[:default]
162:               else
163:                 nil
164:               end
165:       klass.nil? ? nil : website.cache.instance(klass)
166:     end
replace_tags(context) click to toggle source

Return the context.content provided by context.ref_node with all webgen tags replaced. When a webgen tag is encountered by the parser, the method yields all found information and substitutes the returned string for the tag.

     # File lib/webgen/contentprocessor/tags.rb, line 68
 68:     def replace_tags(context) #:yields: tag_name, param_string, body
 69:       scanner = StringScanner.new(context.content)
 70:       data = ProcessingStruct.new(:before_tag)
 71:       while true
 72:         case data.state
 73:         when :before_tag
 74:           if scanner.skip_until(@start_re)
 75:             data.state = :in_start_tag
 76:             data.backslashes = scanner[1].length
 77:             data.brackets = 1
 78:             data.tag = scanner[2]
 79:             data.simple_tag = (scanner[3] == ':')
 80:             data.params_start_pos = scanner.pos
 81:             data.start_pos = scanner.pos - scanner.matched.length
 82:           else
 83:             data.state = :done
 84:           end
 85: 
 86:         when :in_start_tag
 87:           data.brackets += (scanner[1] == '{' ? 1 : 1) while data.brackets != 0 && scanner.skip_until(BRACKETS_RE)
 88:           if data.brackets != 0
 89:             raise Webgen::RenderError.new("Unbalanced curly brackets for tag '#{data.tag}'", self.class.name,
 90:                                           context.dest_node, context.ref_node)
 91:           else
 92:             data.params_end_pos = data.body_end_pos = data.end_pos = scanner.pos - 1
 93:             data.state = (data.simple_tag ? :process : :in_body)
 94:           end
 95: 
 96:         when :process
 97:           if RUBY_VERSION >= '1.9'
 98:             begin
 99:               enc = scanner.string.encoding
100:               scanner.string.force_encoding('ASCII-8BIT')
101:               if data.backslashes % 2 == 0
102:                 result = yield(data.tag, scanner.string[data.params_start_pos...data.params_end_pos].force_encoding(enc),
103:                                scanner.string[(data.params_end_pos+1)...data.body_end_pos].to_s.force_encoding(enc)).to_s
104:                 scanner.string[data.start_pos..data.end_pos] = "\\" * (data.backslashes / 2) + result.force_encoding('ASCII-8BIT')
105:                 scanner.pos = data.start_pos + result.length
106:               else
107:                 scanner.string[data.start_pos, 1 + data.backslashes / 2] = ''
108:                 scanner.pos -= 1 + data.backslashes / 2
109:               end
110:             ensure
111:               scanner.string.force_encoding(enc) if RUBY_VERSION >= '1.9'
112:             end
113:           else
114:             if data.backslashes % 2 == 0
115:               result = yield(data.tag, scanner.string[data.params_start_pos...data.params_end_pos],
116:                              scanner.string[(data.params_end_pos+1)...data.body_end_pos]).to_s
117:               scanner.string[data.start_pos..data.end_pos] = "\\" * (data.backslashes / 2) + result
118:               scanner.pos = data.start_pos + result.length
119:             else
120:               scanner.string[data.start_pos, 1 + data.backslashes / 2] = ''
121:               scanner.pos -= 1 + data.backslashes / 2
122:             end
123:           end
124:           data.state = :before_tag
125: 
126:         when :in_body
127:           while (result = scanner.skip_until(@end_re))
128:             next unless scanner[2] == data.tag
129:             if scanner[1].length % 2 == 1
130:               scanner.string[(scanner.pos - scanner.matched.length), 1 + scanner[1].length / 2] = ''
131:               scanner.pos -= 1 + scanner[1].length / 2
132:             else
133:               break
134:             end
135:           end
136:           if result
137:             data.state = :process
138:             data.end_pos = scanner.pos - 1
139:             data.body_end_pos = scanner.pos - scanner.matched.length + scanner[1].length / 2
140:           else
141:             raise Webgen::RenderError.new("Invalid body part - no end tag found for '#{data.tag}'", self.class.name,
142:                                           context.dest_node, context.ref_node)
143:           end
144: 
145:         when :done
146:           break
147:         end
148:       end
149:       scanner.string
150:     rescue Webgen::RenderError => e
151:       e.line = scanner.string[0...scanner.pos].scan("\n").size + 1 unless e.line
152:       raise
153:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.