class Webgen::ItemTracker

Namespace for all item trackers.

About

This extension manager class is used to track various “items”. Such items can be added as a dependency to a node and later be checked if they have changed. This allows webgen to conditionally render a node.

An item can basically be anything, there only has to be an item tracker extension that knows how to handle it. Each item tracker extension is uniquely identified by its name (e.g. :node_content, :node_meta_info, …).

Implementing an item tracker.

An item tracker extension class must respond to the following methods:

initialize(website)

Initializes the extension and provides the website object which can be used to resolve the item ID to the referenced item or item data itself.

item_id(*item)

Return the unique ID for the given item. The returned ID has to be unique for this item tracker extension

item_data(*item)

Return the data for the item so that it can be correctly checked later if it has changed. If data for the given item cannot be computer anymore because the item got invalid, raise an exception.

item_changed?(item_id, old_data)

Return true if the item identified by its unique ID has changed. The parameter old_data contains the last known data of the item.

node_referenced?(item_id, old_data, node_alcn)

Return true if the node identified by node_alcn is referenced in the old data identified by the unique ID.

item_description(item_id, data)

Return a string or an array of strings which describe the item (identified by its unique ID) and the given item data. This is used for display purposes and should therefore include a nice, human readable interpretation of the item.

The parameter item for the methods item_id and item_data contains the information needed to identify the item and is depdendent on the specific item tracker extension class. Therefore you need to look at the documentation for an item tracker extension to see what it expects as the item.

Since these methods are invoked multiple times for different items, these methods should have no side effects.

Sample item tracker

The following sample item tracker tracks changes in configuration values. It needs the configuration option name as item.

class ConfigTracker

  def initialize(website)
    @website = website
  end

  def item_id(config_key)
    config_key
  end

  def item_data(config_key)
    @website.config[config_key]
  end

  def item_changed?(config_key, old_val)
    @website.config[config_key] != old_val
  end

  def node_referenced?(config_key, config_value, node_alcn)
    false
  end

  def item_description(config_key, old_val)
    "The website configuration option '#{config_key}'"
  end

end

website.ext.item_tracker.register ConfigTracker, name: :config

Public Class Methods

new(website)

Create a new item tracker for the given website.

Calls superclass method Webgen::ExtensionManager::new

Public Instance Methods

add(node, name, *item)

Add the given item that is handled by the item tracker extension name as a dependency to the node.

cached_items(include_default=true)

Return a hash with mappings from node ALCNs to their used items (items are converted to a human readable representation by using the item_description method).

If the parameter include_default is set to false, the default items added to each node so that it is possible to correctly detect changes, are not included.

The cached data, not the current data, is used. So this information is only useful after a website has been generated.

item_changed?(name, *item)

Return true if the given item that is handled by the item tracker extension name has changed.

node_changed?(node)

Return true if the given node has changed.

node_referenced?(node)

Return true if the given node has been referenced by any item tracker extension.

register(klass, options={}, &block)

Register an item tracker.

The parameter klass has to contain the name of the item tracker class or the class object itself. If the class is located under this namespace, only the class name without the hierarchy part is needed, otherwise the full class name including parent module/class names is needed.

Options:

:name

The name for the item tracker class. If not set, it defaults to the snake-case version (i.e. FileSystem → file_system) of the class name (without the hierarchy part). It should only contain letters.

Examples:

item_tracker.register('Node')   # registers Webgen::ItemTracker::Node

item_tracker.register('::Node') # registers Node !!!

item_tracker.register('MyModule::Doit', name: 'infos')