Reblog Plug-ins

$Revision: 1.7 $

Table of Contents

Overview

Reblog provides has an internal plug-in API which allows various aspects of its behavior to be changed or augmented. It is distributed with several plug-ins that demonstrate the possibilities.

Using Plug-ins

Reblog plug-ins are found in the plugins directory. Each plug-in is a PHP class, which must have a static property $activePlugin set to boolean true. Example plugins typically have $activePlugin set to false; change the value in order to use them.

The value of this property is determined using get_class_vars(), so it must be set in the source code, like this:

var $activePlugin = true;

Plugins are found and instantiated in RF_Controller's loadPlugins() method. The plugins directory is checked for files whose names end in .plugin.php, which are then included using include_once().

Example Plug-ins

Example plug-ins are distributed with Reblog, and can be activated by following the directions for use above. Some (Obsessive Logger) are simple demonstrations without much utility. Others (MetaWeblog RPC, Feed Sparkliner) are fully-functional Reblog enhancements.

Obsessive Logger

This example plug-in contains handlers for every overridable event in Reblog. Each handler method appends a note to the webserver error log using PHP's error_log function.

Useful for debugging, not recommended for use in a production environment.

Demonstrates entry-level plug-in functionality.

Update Logger

Logs updates to individual feed items. Logs are stored in items_userdata table, and can be displayed in the item list to show when and how individual items were modified.

Useful for debugging purposes, initially written in response to strange "resurrection" behavior in certain feeds where past archived items were being marked unread. Helped in understanding GUID generation behavior and led to Feed Extinguisher plugin.

Demonstrates modifications to database in response to specific events (savedModifiedItem, savedNewItem, freshenedUserFeedItems) and persistence of plugin class instances. Also shows how to use existing Reblog Javascript functions (populate_item_body() from style/dom.js in itemTabHTML method) and remotely-available methods (updateLogHTML()) to create interactive interface elements.

Feed Extinguisher

Munges incoming information from FeedBurner, removing “Feed Flare” and restoring original item links.

Useful for minimizing specious updates to entries resulting from flare changes in Feed Burner, rather than actual content changes in the original feed.

Demonstrates modification of raw feed data before saving to database, without modifying Reblog interface.

Feed Sparkliner

Generates "sparklines", tiny graphs showing feed activity over time. These are displayed in the feed list. Active only when PHP GD (graphics library) extension is present.

Useful for comparing relative amounts of activity between feeds.

Demonstrates caching of files (each sparkline is a PNG graphic stashed in the cache directory) and additional feed interface tabs (feedTabHTML).

Enclosure Handler

Basic awareness and handling of RSS 2.0 enclosures, used by podcasters to distribute audio and video files. Encountered enclosures are saved to the database, and shown as links in item tabs or collected into playlists and displayed in feeds list.

Useful for subscribing to podcasts within Reblog.

Demonstrates advanced use of the items_userdata table: new data about item enclosures are written to the database, and the getUserItems() and getUserFeeds() argument lists are modified (gotUserItemsQueryArguments, gotUserFeedsQueryArguments) to automatically extract this information when generating item and feed lists. Links are added to the sidebar (menuMessageHTML) that show only those items which contain enclosures, showing that the item list can be generated based on matched metadata criteria.

Each feed in the feed list also gets a new enclosure tab, which uses plugin-provided Javascript methods to generate an instance of the XSPF Flash Player, a lightweight audio player. XSPF playlists are generated at feed-update time and stored in the cache directory.

Also demonstrates that plug-ins may make use of additional code beyond the core class. This one contains and additional helper class and the XSPF player library.

MetaWeblog RPC

Implements the MetaWeblog API, a method for remotely updating blogs. If configured, all published Reblog items are also automatically posted to an external weblog. This API is implemented by the popular blogging tool Wordpress.

Useful for populating an external blog with published RSS entries.

Demonstrates advanced actions in response to specific events (markedItemPublished, markedItemsPublished, markedItemUnpublished, markedItemsUnpublished, postedItem, setItemCommentTags, setItemTitleContentLink, setItemLink) and possibilities for connections between Reblog and external services.

Atom API

Based on MetaWeblog RPC, implements Atom protocol for publishing Reblog items to blogs such as Blogger.

Del.icio.us Post

Based on MetaWeblog RPC, implements Del.icio.us API for posting new social bookmarks.

Similar Entries

Displays a list of similar RSS entries based on full text search.

Useful for finding duplicate information among many feeds, and searching for older related items.

Demonstrates advanced interface modifications, with new item tabs for pulling in chunks of server-generated HTML asynchronously from similarEntriesHTML(), and interactive elements for archiving similar items within and among dynamically-generated content areas.

Writing Plug-ins

Requirements

A valid Reblog plug-in:

  1. Must be a PHP class, included in a file whose name ends in .plugin.php, in the plugins directory.

  2. Must have a static class variable $activePlugin, set to boolean true:

    var $activePlugin = true;
  3. Must have a constructor that accepts a single argument, an instance of RF_Controller. Plug-in classes are instantiated in RF_Controller::loadPlugins(), and the passed instance may be used for database access.

  4. Must statically declare any methods intended for remote access via JSON RPC:

    var $remoteMethods = array("method1", "method2");

Instantiation and Remote Invokation

See RF_Controller::loadPlugins() for the iteration over get_declared_classes() and get_class_vars() that determines valid plugin classes and instantiates them into a $plugins array.

See RF_Controller::invokePlugin() for the call to method_exists() and comparison to $remoteMethods which verifies a valid remote RPC call. In remote requests, method names can be specified in one of two ways:

  1. Retrieve an array of responses to all plugins with a named method defined: method_name. If only one plugin defines a method with this name, a one-element array will be returned.

  2. Retrieve a single response from an existing named plugin with a named method defined: plugin_classname.method_name.

Methods whose names conflict with those belonging to RF_Userdata_Controller will not work in JSON RPC calls. Most methods of RF_Userdata_Controller make calls to RF_Controller::invokePlugin() after performing their assigned actions. For example, in RF_Userdata_Controller::markItemPublished(), the plug-in method markedItemPublished is invoked. This method should be implented in a plug-in where actions resulting from item publishing are desired.

Arguments

Instances of RF_Item or RF_Feed passed to a method via remote calls typically have only an id defined, and other properties may need to loaded from the database. See the similarEntriesHTML() method in Similar Entries for an example of this pattern:

$item = $this->controller->getUserItem($GLOBALS['REBLOG_USER'], $item);

Caching Data

Plug-ins may write to the cache directory, generally called cache and accessible via the function get_configured_cache_dir(). This directory is world readable and accessible via HTTP, so no sensitive information should be saved there.

Built-in Methods

Reblog has a wide variety of built-in methods. These are generally event hooks called at particular points in the operation of classes such as RF_Controller or RF_Userdata_Controller which allow default behaviors to be modified. These are typically named with past-tense verbs, and are invoked after their associated action.

All built-in plug-in methods have arguments passed by reference and most have no return values.

$item = $this->controller->getUserItem($GLOBALS['REBLOG_USER'], $item);

Getting Lists of Items and Feeds

When retrieving user RF_Items via RF_Controller::getUserItems(), a series of events takes place:

  1. gotUserItemsQueryArguments:
    Arguments to RF_Controller::getUserItems() have been processed and may be modified. For example, the Enclosure Handler plug-in adds metadata arguments so that extra information from the items_userdata table may be included in the listing with no extra SQL queries.

  2. gotUserItemsQueryConditions:
    SQL conditions (based on arguments passed and modified earlier) for use by RF_Controller::getUserItemsQuery() have been compiled into an array of test fragments which may be modified individually.

  3. gotUserItemsQuery:
    An SQL query (based on arguments passed and modified earlier) has been generated, including conditions from the previous step. This query may be edited as a string before being passed to the database.

  4. gotUserItems:
    A list of RF_Items has been retrieved from the database based on the SQL query, and may be modified individually before return from RF_Controller::getUserItems().

This series of methods is identical in the case of RF_Feeds returned by RF_Controller::getUserFeeds(): gotUserFeedsQueryArguments, gotUserFeedsQueryConditions, gotUserFeedsQuery, gotUserFeeds.

Template Methods

Some methods should return simple HTML strings, for use by Smarty templates:

Order of Invokation

All built-in plug-in methods have arguments passed by reference, so that chains of plug-ins can perform operations serially. The order in which plug-ins are invoked is somewhat arbitrary, determined by get_declared_classes().

Method Dictionary

feedDeleted

Deleted a feed completely.

Args:

  1. RF_Feed
feedTabHTML

Retrieve a string of HTML for use in the feed tabs, useful when a plug-in requires per-feed interface or form elements. Return value should be a single HTML anchor ("A") element.

Args:

  1. RF_Feed
flushedObsoleteItems

Flushed obsolete items from a feed for all users.

Args:

  1. RF_Feed
  2. array of RF_Items
flushedObsoleteUserItems

Flushed obsolete items from a feed for a given user.

Args:

  1. RF_User
  2. RF_Feed
  3. array of RF_Items
freshenedUserFeedItems

Freshened items in a feed for a given user. These items may have already been archived, but they were changed in the original RSS feed and thus should be revived.

Args:

  1. RF_User
  2. RF_Feed
  3. array of RF_Items
gotFeedItems

Got a list of items for a given feed.

Args:

  1. RF_Feed
  2. array of RF_Items
gotFeeds

Got a list of all feeds.

Args:

  1. array of RF_Feeds
gotFeedUsers

Got a list of users for a given feed.

Args:

  1. RF_Feed
  2. array of RF_Users
gotUserFeeds

Got a list of feeds resulting from SQL query, for a given user.

Args:

  1. RF_User
  2. array of RF_Feeds
gotUserFeedsQuery

Got a complete SQL query for selecting a list of feeds, for a given user.

Args:

  1. RF_User
  2. string: query
gotUserFeedsQueryArguments

Got a list arguments, which are subsequently used to generate an SQL query for a given user. These may include qualifiers to select a range of feeds, or perform joins to retrieve feed metadata.

Args:

  1. associative array of arguments
gotUserFeedsQueryConditions

Got a list of SQL conditions, used in generated SQL query for a given user. These are mostly conditionals used directly in WHERE clauses.

Args:

  1. RF_User
  2. associative array of conditions
  3. associative array of arguments, from which conditions were generated
gotUserItems

Got a list of items resulting from SQL query, for a given user.

Args:

  1. RF_User
  2. array of RF_Items
gotUserItemsQuery

Got a complete SQL query for selecting a list of items, for a given user.

Args:

  1. RF_User
  2. string: query
gotUserItemsQueryArguments

Got a list arguments, which are subsequently used to generate an SQL query for a given user. These may include qualifiers to select a range of items, or perform joins to retrieve item metadata.

Args:

  1. associative array of arguments
gotUserItemsQueryConditions

Got a list of SQL conditions, used in generated SQL query for a given user. These are mostly conditionals used directly in WHERE clauses.

Args:

  1. RF_User
  2. associative array of conditions
  3. associative array of arguments, from which conditions were generated
gotUserTags

Got a list of tags for a given user.

Args:

  1. RF_User
  2. string: "item" or "feed", depending on which tags were retreived.
  3. array of strings: tags
itemTabHTML

Retrieve a string of HTML for use in the item tabs, useful when a plug-in requires per-item interface or form elements. Return value should be a single HTML anchor ("A") element.

Args:

  1. RF_Item
loadedPlugins

Finished loading plug-ins.

markedFeedPublished

Marked a user's feed published.

Args:

  1. RF_User
  2. RF_Feed
markedFeedUnpublished

Marked a user's feed unpublished.

Args:

  1. RF_User
  2. RF_Feed
markedItemPublished

Marked a user's items published.

Args:

  1. RF_User
  2. RF_Item
markedItemRead

Marked a user's item read.

Args:

  1. RF_User
  2. RF_Item
markedItemsPublished

Marked a user's items published.

Args:

  1. RF_User
  2. array of RF_Items
markedItemsRead

Marked a user's items read.

Args:

  1. RF_User
  2. array of RF_Items
markedItemsUnread

Marked a user's items unread.

Args:

  1. RF_User
  2. array of RF_Items
markedItemUnpublished

Marked a user's items unpublished.

Args:

  1. RF_User
  2. RF_Item
markedItemUnread

Marked a user's item unread.

Args:

  1. RF_User
  2. RF_Item
menuMessageHTML

Retrieve a string of HTML for use in the page menu, useful when a plug-in requires page-wide interface or form elements.

pageHeadHTML

Retrieve a string of HTML for use in the page head, useful when a plug-in requires additional javascript or style sheets.

postedItem

Posted a new item to a user's own feed.

Args:

  1. RF_User
  2. RF_Item
preparedItemArguments

Prepared item arguments, after parsing RSS but before saving to database. This is the last chance to munge item data before it's saved.

Args:

  1. RF_Feed
  2. associative array: names and values of arguments ready for RF_Item constructor
  3. associative array: names and values of item data direct from RSS parser
savedExistingFeed

Saved an existing feed.

Args:

  1. RF_Feed
savedModifiedItem

Saved an item to the database, after it has been fetched from an RSS source and determined to have been modified since it was last seen.

Args:

  1. RF_Item
savedNewFeed

Saved a new feed.

Args:

  1. RF_Feed
savedNewItem

Saved an item to the database, after it has been fetched from an RSS source and determined to be new.

Args:

  1. RF_Item
setFeedTags

Modified feed tags for a given user.

Args:

  1. RF_User
  2. RF_feed
  3. array of strings: tags
setItemCommentTags

Modified item comment and tags for a given user.

Args:

  1. RF_User
  2. RF_Item
  3. string: comment
  4. array of strings: tags
setItemLink

Modified item link for a given user.

Args:

  1. RF_User
  2. RF_Item
  3. string: new link
setItemTags

Modified item tags for a given user.

Args:

  1. RF_User
  2. RF_Item
  3. array of strings: tags
setItemTitleContentLink

Modified item title, content and link for a given user.

Args:

  1. RF_User
  2. RF_Item
  3. string: title
  4. string: content
  5. string: link
setKeyboardUse

Keyboard use has been set to on or off.

Args:

  1. RF_User
  2. boolean: keyboard status
subscribedUserToFeed

Subscribed a user to a feed.

Args:

  1. RF_User
  2. RF_Feed
unsubscribedUserFromFeed

Unsubscribed a user from a feed.

Args:

  1. RF_User
  2. RF_Feed
updatedFeed

Updated a feed from source URL.

Args:

  1. RF_Feed

License

Reblog is distributed under the GPL (see the LICENSE file in this directory), though some of its included libraries (in./library/) are not.