lib/webgen/path_handler/page_utils.rb in webgen-1.0.0.beta1 vs lib/webgen/path_handler/page_utils.rb in webgen-1.0.0.beta2
- old
+ new
@@ -1,8 +1,8 @@
# -*- encoding: utf-8 -*-
-require 'webgen/path_handler'
+require 'webgen/path_handler/base'
require 'webgen/page'
require 'webgen/error'
module Webgen
class PathHandler
@@ -12,10 +12,123 @@
# Note that this modules provides an implementation for the #parse_meta_info! method. If you
# also include the Base module, make sure that you include it before this module! Also make sure
# to override this method if you need custom behaviour!
module PageUtils
+ # Custom Node class that provides easy access to the blocks of the parsed page file and
+ # methods for rendering a block.
+ class Node < Webgen::PathHandler::Base::Node
+
+ # Return the blocks (see PageUtils#parse_as_page!) for this node.
+ def blocks
+ node_info[:blocks]
+ end
+
+ # Render the block +name+ of this node using the provided Context object.
+ #
+ # Uses the content processors specified for the block via the +blocks+ meta information key if
+ # the +pipeline+ parameter is not set.
+ #
+ # Returns the given context with the rendered content.
+ def render_block(name, context, pipeline = nil)
+ unless blocks.has_key?(name)
+ raise Webgen::RenderError.new("No block named '#{name}' found", nil, context.dest_node.alcn, alcn)
+ end
+
+ content_processor = context.website.ext.content_processor
+ context.website.ext.item_tracker.add(context.dest_node, :node_content, alcn)
+
+ context.content = blocks[name].dup
+ context[:block_name] = name
+ pipeline ||= ((self['blocks'] || {})[name] || {})['pipeline'] ||
+ ((self['blocks'] || {})['defaults'] || {})['pipeline'] ||
+ []
+ content_processor.normalize_pipeline(pipeline).each do |processor|
+ content_processor.call(processor, context)
+ end
+ context[:block_name] = nil
+ context
+ end
+
+ # Return the template chain for this node.
+ #
+ # When invoked directly, the +lang+ parameter should not be used. This parameter is necessary
+ # for the recursive invocation of the method so that the correct templates are used. Consider
+ # the following path hierarchy:
+ #
+ # /default.en.template
+ # /default.de.template
+ # /custom.template
+ # /index.de.page template: custom.template
+ # /index.en.page template: custom.template
+ #
+ # The template chains for index.en.page and index.de.page are therefore
+ #
+ # /default.en.template → /custom.template
+ # /default.de.template → /custom.template
+ #
+ # This means that the /custom.template needs to reference different templates depending on the
+ # language.
+ def template_chain(lang = @lang)
+ cached_template = (tree.website.cache.volatile[[alcn, :templates]] ||= {})
+ if cached_template.has_key?(lang)
+ template_node = cached_template[lang]
+ elsif self['template'].kind_of?(String)
+ template_node = resolve(self['template'], lang, true)
+ if template_node.nil?
+ tree.website.logger.warn do
+ ["Template '#{self['template']}' for <#{self}> not found, using default template!",
+ 'Fix the value of the meta information \'template\' for <#{self}>']
+ end
+ template_node = default_template(parent, lang)
+ end
+ cached_template[lang] = template_node
+ elsif meta_info.has_key?('template') && self['template'].nil?
+ template_node = cached_template[lang] = nil
+ else
+ tree.website.logger.debug { "Using default template in language '#{lang}' for <#{self}>" }
+ template_node = default_template(parent, lang)
+ if template_node == self && !parent.is_root?
+ template_node = default_template(parent.parent, lang)
+ end
+ cached_template[lang] = template_node
+ end
+
+ if template_node.nil?
+ []
+ else
+ (template_node == self ? [] : template_node.template_chain(lang) + [template_node])
+ end
+ end
+
+ # Return the default template for the directory node +dir+ and language +lang+.
+ #
+ # If the template node is not found, the parent directories are searched.
+ def default_template(dir, lang)
+ default_template_name = tree.website.config['path_handler.default_template']
+ template = dir.resolve(default_template_name, lang)
+ if template.nil?
+ if dir.is_root?
+ tree.website.logger.warn do
+ ["Default template '#{default_template_name}' not found in root directory!",
+ 'Provide a </#{default_template_name}> to fix this warning.']
+ end
+ else
+ template = default_template(dir.parent, lang)
+ end
+ end
+ template
+ end
+ protected :default_template
+
+ end
+
+
+ def create_node(path, node_klass = Node) #:nodoc:
+ super
+ end
+
# Calls #parse_as_page! to update the meta information hash of +path+. Returns the found
# blocks which will be passed as second parameter to the #create_nodes method.
def parse_meta_info!(path)
parse_as_page!(path)
end
@@ -38,41 +151,9 @@
# Set the blocks (see #parse_as_page!) for the node.
def set_blocks(node, blocks)
node.node_info[:blocks] = blocks
end
private :set_blocks
-
- # Return the blocks (see #parse_as_page!) for the node.
- def blocks(node)
- node.node_info[:blocks]
- end
-
- # Render the block +name+ of +node+ using the provided Context object.
- #
- # Uses the content processors specified for the block via the +blocks+ meta information key if
- # the +pipeline+ parameter is not set.
- #
- # Returns the given context with the rendered content.
- def render_block(node, name, context, pipeline = nil)
- unless node.blocks.has_key?(name)
- raise Webgen::RenderError.new("No block named '#{name}' found", self.class.name,
- context.dest_node.alcn, node.alcn)
- end
-
- content_processor = context.website.ext.content_processor
- context.website.ext.item_tracker.add(context.dest_node, :node_content, node.alcn)
-
- context.content = node.blocks[name].dup
- context[:block_name] = name
- pipeline ||= ((node.meta_info['blocks'] || {})[name] || {})['pipeline'] ||
- ((node.meta_info['blocks'] || {})['defaults'] || {})['pipeline'] ||
- []
- content_processor.normalize_pipeline(pipeline).each do |processor|
- content_processor.call(processor, context)
- end
- context[:block_name] = nil
- context
- end
end
end
end