module Webgen::ContentProcessor::Blocks
Replaces special XML tags with the rendered content of a node block.
The module provides a ::call
method so that it can be used by the content processor extension. However, it also provides the ::render_block
method that contains the actual logic for rendering a block of a node given a render context.
Public Class Methods
Replace the webgen:block xml tags with the rendered content of the specified node.
# File lib/webgen/content_processor/blocks.rb 19 def self.call(context) 20 context.content.gsub!(BLOCK_RE) do |match| 21 attr = {} 22 match_object = $~ 23 attr[:line_nr_proc] = lambda { match_object.pre_match.scan("\n").size + 1 } 24 match.scan(BLOCK_ATTR_RE) {|name, sep, content| attr[name.to_sym] = content} 25 render_block(context, attr) 26 end 27 context 28 end
Render a block of a page node and return the result.
The Webgen::Context
object context
is used as the render context and the options
hash needs to hold all relevant information, that is:
- :name (mandatory)
-
The name of the block that should be used.
- :chain
-
The node chain used for rendering. If this is not specified, the node chain from the context is used. It needs to be a String in the format '(A)LCN;(A)LCN;…' or an array of nodes.
- :node
-
Defines which node in the node chain should be used. Valid values are
next
(= default value; the next node in the node chain),first
(the first node in the node chain with a block calledname
) orcurrent
(the currently rendered node, ignores thechain
option). - :notfound
-
If this property is set to
ignore
, a missing block will not raise an error. It is unset by default, so missing blocks will raise errors.
# File lib/webgen/content_processor/blocks.rb 52 def self.render_block(context, options) 53 if options[:chain].nil? 54 used_chain = (context[:chain].length > 1 ? context[:chain][1..-1] : context[:chain].dup) 55 elsif options[:chain].kind_of?(Array) 56 used_chain = options[:chain] 57 else 58 paths = options[:chain].split(';') 59 used_chain = paths.collect do |path| 60 context.ref_node.resolve(path.strip, context.dest_node.lang, true) 61 end.compact 62 return '' if used_chain.length != paths.length 63 end 64 dest_node = context.dest_node 65 66 if options[:node] == 'first' 67 used_chain.shift while used_chain.length > 0 && !used_chain.first.blocks.has_key?(options[:name]) 68 elsif options[:node] == 'current' 69 used_chain = context[:chain].dup 70 end 71 block_node = used_chain.first 72 73 if !block_node || !block_node.blocks.has_key?(options[:name]) 74 if options[:notfound] == 'ignore' 75 return '' 76 elsif block_node 77 raise Webgen::RenderError.new("No block named '#{options[:name]}' found in <#{block_node}>", 78 'content_processor.blocks', context.dest_node, 79 context.ref_node, (options[:line_nr_proc].call if options[:line_nr_proc])) 80 else 81 raise Webgen::RenderError.new("No node in the render chain has a block named '#{options[:name]}'", 82 'content_processor.blocks', context.dest_node, 83 context.ref_node, (options[:line_nr_proc].call if options[:line_nr_proc])) 84 end 85 end 86 87 tmp_context = block_node.render_block(options[:name], context.clone(:chain => used_chain, :dest_node => dest_node)) 88 tmp_context.content 89 end