Changeset 975

Show
Ignore:
Timestamp:
08/20/08 17:18:34 (3 months ago)
Author:
mpaschal
Message:

Wrap all these lines so the doc is mostly readable directly in subversion

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ActionStreams/plugins/ActionStreams/doc/recipe-guide.txt

    r903 r975  
    11# Action Streams Recipe Developer Guide # 
    22 
    3 The Action Streams plugin collects authors' actions performed in remote services. Plugin developers can add support to Action Streams for new web services, often with no Perl code required at all. 
     3The Action Streams plugin collects authors' actions performed in remote 
     4services. Plugin developers can add support to Action Streams for new web 
     5services, often with no Perl code required at all. 
    46 
    57## Making a plugin with the registry ## 
    68 
    7 In Movable Type 4, plugins are defined using a file called `config.yaml` instead of Perl code. When Movable Type loads the plugin, the settings the plugin defines in `config.yaml` are integrated into what's called *the registry*. The registry is a tree of settings that informs Movable Type what settings, pages, and objects are available. 
    8  
    9 To define your plugin, make a new directory in the `plugins` directory. Inside it, create a file called `config.yaml`, and enter all the basic plugin settings. For example: 
     9In Movable Type 4, plugins are defined using a file called `config.yaml` 
     10instead of Perl code. When Movable Type loads the plugin, the settings the 
     11plugin defines in `config.yaml` are integrated into what's called *the 
     12registry*. The registry is a tree of settings that informs Movable Type what 
     13settings, pages, and objects are available. 
     14 
     15To define your plugin, make a new directory in the `plugins` directory. Inside 
     16it, create a file called `config.yaml`, and enter all the basic plugin 
     17settings. For example: 
    1018 
    1119    id:   ExampleService 
     
    1826    plugin_link: http://www.example.com/plugins/example-service/ 
    1927 
    20 These settings define a plugin called "Example Service" with all the specified settings. Consult the Movable Type developer documentation for further help on creating plugins. 
     28These settings define a plugin called "Example Service" with all the specified 
     29settings. Consult the Movable Type developer documentation for further help on 
     30creating plugins. 
    2131 
    2232## Defining a profile service ## 
    2333 
    24 Every action and stream belongs to a **service**, so unless you're adding a stream for a service that already exists in Action Streams, you need to define one of those first. Usually a service is a web site at which an author has an account. Authors can use the Action Streams plugin to make a sidebar list of their accounts on all the services for which they enter their accounts. 
    25  
    26 Profile services are defined in the `profile_services` section of the registry. Because Movable Type merges your `config.yaml` into the registry, you specify additional services by adding your own `profile_services` section to your plugin's `config.yaml`. For example: 
     34Every action and stream belongs to a **service**, so unless you're adding a 
     35stream for a service that already exists in Action Streams, you need to define 
     36one of those first. Usually a service is a web site at which an author has an 
     37account. Authors can use the Action Streams plugin to make a sidebar list of 
     38their accounts on all the services for which they enter their accounts. 
     39 
     40Profile services are defined in the `profile_services` section of the 
     41registry. Because Movable Type merges your `config.yaml` into the registry, 
     42you specify additional services by adding your own `profile_services` section 
     43to your plugin's `config.yaml`. For example: 
    2744 
    2845    profile_services: 
     
    3956            icon: example.png 
    4057 
    41 This defines two services. Each service has its own key by which it's known in the registry. These services' keys are `example` and `complex`. The data you can set for a service are: 
     58This defines two services. Each service has its own key by which it's known in 
     59the registry. These services' keys are `example` and `complex`. The data you 
     60can set for a service are: 
    4261 
    4362### `name` (required) ### 
    4463 
    45 The human-readable name of the service. This name is used for display and for ordering the list of services. 
     64The human-readable name of the service. This name is used for display and for 
     65ordering the list of services. 
    4666 
    4767### `url` (required) ### 
    4868 
    49 The URL to a user's profile on the service. This is the URL used in the author's list of services. 
    50  
    51 The string `{{ident}}` will be replaced by the author's identifier for this service. Only one identifier per service is currently supported. 
     69The URL to a user's profile on the service. This is the URL used in the 
     70author's list of services. 
     71 
     72The string `{{ident}}` will be replaced by the author's identifier for this 
     73service. Only one identifier per service is currently supported. 
    5274 
    5375### `ident_label` ### 
    5476 
    55 A label to describe what the author's identifier on the service is. If not given, the label `Username` is used. For example, if the user identifier on the service is a number, you might specify `User ID` here to indicate the author should enter a number. For the AIM service, the label is `Screen name`. 
     77A label to describe what the author's identifier on the service is. If not 
     78given, the label `Username` is used. For example, if the user identifier on 
     79the service is a number, you might specify `User ID` here to indicate the 
     80author should enter a number. For the AIM service, the label is `Screen name`. 
    5681 
    5782### `ident_example` ### 
    5883 
    59 A label to show what the identifiers for the service generally look like. For example, if the user identifier is a number, you might specify `12345`. For the Flickr service, the example identifier is `36381329@N00`. 
     84A label to show what the identifiers for the service generally look like. For 
     85example, if the user identifier is a number, you might specify `12345`. For 
     86the Flickr service, the example identifier is `36381329@N00`. 
    6087 
    6188### `ident_suffix` ### 
    6289 
    63 A label to show after the field in which the identifier is entered. Typically this is used to further suggest that the one's subdomain on a service is one's identifier. For example, the Vox service's suffix is `.vox.com`. 
     90A label to show after the field in which the identifier is entered. Typically 
     91this is used to further suggest that the one's subdomain on a service is one's 
     92identifier. For example, the Vox service's suffix is `.vox.com`. 
    6493 
    6594### `service_type` ### 
    6695 
    67 The kind of web service this profile is about. Authors can list their accounts for a certain type of services using the `type` attribute of the `OtherProfiles` tag. Any value is allowed here, but the established service types are: 
     96The kind of web service this profile is about. Authors can list their accounts 
     97for a certain type of services using the `type` attribute of the 
     98`OtherProfiles` tag. Any value is allowed here, but the established service 
     99types are: 
    68100 
    69101* `contact` (AIM, Yahoo! Messenger, etc) 
     
    77109### `icon` ### 
    78110 
    79 The location of the service's icon. This can be a complete URL to the image. If not a URL, `icon` should be a path to the image relative to your plugin's `mt-static` directory. For example, if you install your `example.png` at `mt-static/plugins/ExampleService/example.png`, your `icon` setting should be `example.png`. 
     111The location of the service's icon. This can be a complete URL to the image. 
     112If not a URL, `icon` should be a path to the image relative to your plugin's 
     113`mt-static` directory. For example, if you install your `example.png` at 
     114`mt-static/plugins/ExampleService/example.png`, your `icon` setting should be 
     115`example.png`. 
    80116 
    81117## Defining stream recipes for a service ## 
    82118 
    83 Once a service is defined in `profile_services`, you can make recipes for collecting its action streams. These recipes go in the `action_streams` section of the registry. For example: 
     119Once a service is defined in `profile_services`, you can make recipes for 
     120collecting its action streams. These recipes go in the `action_streams` 
     121section of the registry. For example: 
    84122 
    85123    action_streams: 
     
    96134                    thumbnail: media:thumbnail/child::text() 
    97135 
    98 Each service has its own section, labelled with the same key as in the `profile_services` section. Inside that, you can define one or more recipes for how to collect actions. As you can see, recipes have three parts: 
     136Each service has its own section, labelled with the same key as in the 
     137`profile_services` section. Inside that, you can define one or more recipes 
     138for how to collect actions. As you can see, recipes have three parts: 
    99139 
    100140* **URLs** that indicate where to find action content. 
    101 * **Collectors** that specify how to turn the resource at the stream's URL into action data. Action data is primarily a title, a link, and a unique identifier for each action, but you can specify additional data fields in your recipe. 
    102 * **Forms** that describe how to turn the action data back into HTML. Authors can display however they like with template code, but in the application and by default, actions in this stream will display as you specify in the recipe. 
     141* **Collectors** that specify how to turn the resource at the stream's URL 
     142  into action data. Action data is primarily a title, a link, and a unique 
     143  identifier for each action, but you can specify additional data fields in 
     144  your recipe. 
     145* **Forms** that describe how to turn the action data back into HTML. Authors 
     146  can display however they like with template code, but in the application and 
     147  by default, actions in this stream will display as you specify in the 
     148  recipe. 
    103149 
    104150Together, these parts define the recipe. 
     
    106152### Picking a stream ID ### 
    107153 
    108 The word you use as the registry key when defining a stream is its ID. While you can use any term here, if the stream you're defining is analogous to a stream available from another service, use the same ID as the other service's stream does. 
    109  
    110 Template authors can list similar actions across services by using the `stream` attribute on the `ActionStreams` tag in absence of the `service` attribute. The value template authors will use with `stream` will be this ID, so in order for your (say) photos stream to be included when a user lists all posted photos across all services, use `photos` for your stream ID. 
     154The word you use as the registry key when defining a stream is its ID. While 
     155you can use any term here, if the stream you're defining is analogous to a 
     156stream available from another service, use the same ID as the other service's 
     157stream does. 
     158 
     159Template authors can list similar actions across services by using the 
     160`stream` attribute on the `ActionStreams` tag in absence of the `service` 
     161attribute. The value template authors will use with `stream` will be this ID, 
     162so in order for your (say) photos stream to be included when a user lists all 
     163posted photos across all services, use `photos` for your stream ID. 
    111164 
    112165Some of the standard stream IDs used in the standard provided streams are: 
    113166 
    114 * `links`, web pages or resources that have been bookmarked (as in del.icio.us, Digg, Magnolia) 
    115 * `photos`, photos posted by the author (as in Flickr, Picasa on the Web, Smugmug) 
    116 * `favorites`, assets and objects of others' that the author saved as a favorite (as in Vox, Twitter, YouTube) 
     167* `links`, web pages or resources that have been bookmarked (as in 
     168  del.icio.us, Digg, Magnolia) 
     169* `photos`, photos posted by the author (as in Flickr, Picasa on the Web, 
     170  Smugmug) 
     171* `favorites`, assets and objects of others' that the author saved as a 
     172  favorite (as in Vox, Twitter, YouTube) 
    117173* `achievements`, awards won by the author (as in Steam or Kongregate) 
    118174* `videos`, videos posted by the author (as in Viddler, Vimeo, YouTube) 
     
    120176### Picking the stream resource ### 
    121177 
    122 Typically, modern web services will provide a web feed or XML resource for their members that rolls up their recent activity on the site. Sometimes a service only provides an HTML page, but Action Streams can work with them too. This is the resource you will specify as your stream's `url`. 
    123  
    124 The URL for the resource needs to include the user's identifier in the URL. In some extreme cases, you may even have to change what identifier your profile service uses in order to get the stream resource. Normally the same user name or ID is in the URL, though. 
     178Typically, modern web services will provide a web feed or XML resource for 
     179their members that rolls up their recent activity on the site. Sometimes a 
     180service only provides an HTML page, but Action Streams can work with them too. 
     181This is the resource you will specify as your stream's `url`. 
     182 
     183The URL for the resource needs to include the user's identifier in the URL. In 
     184some extreme cases, you may even have to change what identifier your profile 
     185service uses in order to get the stream resource. Normally the same user name 
     186or ID is in the URL, though. 
    125187 
    126188### Three schools of collection ### 
    127189 
    128 Most services don't yet publish their members' actions as such, so even if you can collect from a nice standard web feed, the feed content will need some massaging. There are three main kinds of collectors at your disposal: XML feeds, HTML scrapers, and custom collectors. 
     190Most services don't yet publish their members' actions as such, so even if you 
     191can collect from a nice standard web feed, the feed content will need some 
     192massaging. There are three main kinds of collectors at your disposal: XML 
     193feeds, HTML scrapers, and custom collectors. 
    129194 
    130195#### XML feeds #### 
    131196 
    132 It's easy to collect data from XML feeds. Action Streams accepts recipes using XPath syntax. For example, you might collect data from del.icio.us' RSS feeds with an `xpath` recipe: 
     197It's easy to collect data from XML feeds. Action Streams accepts recipes using 
     198XPath syntax. For example, you might collect data from del.icio.us' RSS feeds 
     199with an `xpath` recipe: 
    133200 
    134201    delicious: 
     
    146213                    url: link/child::text() 
    147214 
    148 This specifies that each item in the feed is an XPath `//item`, meaning an `item` tag anywhere in the document. Within each `item`, you can find values for the `created_on`, `title`, and `url` fields using the given XPath selectors. The `identifier: url` statement indicates to use the `url` value as the action's unique identifier. 
    149  
    150 As many services provide as standard web feeds, it's actually even easier to collect from those. Instead of `xpath`, specify your recipe as `rss` or `atom`, with any additional or special fields as additional XPath selectors: 
     215This specifies that each item in the feed is an XPath `//item`, meaning an 
     216`item` tag anywhere in the document. Within each `item`, you can find values 
     217for the `created_on`, `title`, and `url` fields using the given XPath 
     218selectors. The `identifier: url` statement indicates to use the `url` value as 
     219the action's unique identifier. 
     220 
     221As many services provide as standard web feeds, it's actually even easier to 
     222collect from those. Instead of `xpath`, specify your recipe as `rss` or 
     223`atom`, with any additional or special fields as additional XPath selectors: 
    151224 
    152225    delicious: 
     
    160233                created_on: dc:date/child::text() 
    161234 
    162 If there are no special fields to collect, you can also specify the recipe as simply `1`, as in this recipe for Jaiku: 
     235If there are no special fields to collect, you can also specify the recipe as 
     236simply `1`, as in this recipe for Jaiku: 
    163237 
    164238    jaiku: 
     
    170244            atom: 1 
    171245 
    172 The values of each entry's ID field (`guid` in RSS and `id` in Atom) are then used for actions' identifiers. 
     246The values of each entry's ID field (`guid` in RSS and `id` in Atom) are then 
     247used for actions' identifiers. 
    173248 
    174249#### HTML pages #### 
    175250 
    176 When feeds aren't available, HTML will do. Action Streams reads HTML pages using Web::Scraper, an HTML scraping library inspired by the Ruby scrapi library. For example, the Iwtst plugin reads your iwanttoseethat.com profile page with this definition: 
     251When feeds aren't available, HTML will do. Action Streams reads HTML pages 
     252using Web::Scraper, an HTML scraping library inspired by the Ruby scrapi 
     253library. For example, the Iwtst plugin reads your iwanttoseethat.com profile 
     254page with this definition: 
    177255 
    178256    iwtst: 
     
    193271                      - TEXT 
    194272 
    195 Instead of XPath, here we can use CSS selector syntax. (For more complex constructions, you can use XPath selectors as well.) This recipe says each action is a `div` with class `seethat_yes` inside a `seethat` `div`. The action's `url` field is then the value of the `href` attribute of the `a` tag inside, while the `title` field is the text linked inside that `a` tag. 
     273Instead of XPath, here we can use CSS selector syntax. (For more complex 
     274constructions, you can use XPath selectors as well.) This recipe says each 
     275action is a `div` with class `seethat_yes` inside a `seethat` `div`. The 
     276action's `url` field is then the value of the `href` attribute of the `a` tag 
     277inside, while the `title` field is the text linked inside that `a` tag. 
    196278 
    197279#### Custom collectors #### 
    198280 
    199 If you aren't pulling web data, or you can't quite articulate as a set of selectors, you can implement your own action collector as a Perl class. You then tell what class implements your stream: 
     281If you aren't pulling web data, or you can't quite articulate as a set of 
     282selectors, you can implement your own action collector as a Perl class. You 
     283then tell what class implements your stream: 
    200284 
    201285    complex: 
     
    206290            class: Example::Event::ComplexPosts 
    207291 
    208 Your class then subclasses the plugin's `ActionStreams::Event` class, and implements your particular content-finding behavior. As the XML and HTML recipes are really the default behavior of an `ActionStreams::Event` object, the above techniques are easily accessible from your class too. See some of the `ActionStreams::Event` subclasses included with the Action Streams plugin for examples. 
     292Your class then subclasses the plugin's `ActionStreams::Event` class, and 
     293implements your particular content-finding behavior. As the XML and HTML 
     294recipes are really the default behavior of an `ActionStreams::Event` object, 
     295the above techniques are easily accessible from your class too. See some of 
     296the `ActionStreams::Event` subclasses included with the Action Streams plugin 
     297for examples. 
    209298 
    210299### Formatting actions for display ### 
    211300 
    212 While bloggers can customize how actions are published to the blog however they wish with the provided template tags, the recipe defines how actions are displayed when using the `mt:StreamAction` tag and when displayed in the application. This display is governed by the `html_form` and `html_params` options, as in the del.icio.us recipe: 
     301While bloggers can customize how actions are published to the blog however 
     302they wish with the provided template tags, the recipe defines how actions are 
     303displayed when using the `mt:StreamAction` tag and when displayed in the 
     304application. This display is governed by the `html_form` and `html_params` 
     305options, as in the del.icio.us recipe: 
    213306 
    214307    delicious: 
     
    222315            # ... 
    223316 
    224 The `html_form` setting is a pattern in maketext format, making it easy to . Each replacement token is numbered. The first replacement token, `[_1]`, is always the name of the MT user whose action is being displayed. The next tokens represent the fields you specify in (in this case, `url` and `title`). 
    225  
    226 Note that the result of formatting an action is, in fact, HTML. This markup will be returned verbatim when used with the `mt:StreamAction` tag. For display in the Movable Type application, the HTML is removed; del.icio.us links are the text "*Author name* saved the link *title*" without the hyperlink, for example. 
     317The `html_form` setting is a pattern in maketext format, making it easy to . 
     318Each replacement token is numbered. The first replacement token, `[_1]`, is 
     319always the name of the MT user whose action is being displayed. The next 
     320tokens represent the fields you specify in (in this case, `url` and `title`). 
     321 
     322Note that the result of formatting an action is, in fact, HTML. This markup 
     323will be returned verbatim when used with the `mt:StreamAction` tag. For 
     324display in the Movable Type application, the HTML is removed; del.icio.us 
     325links are the text "*Author name* saved the link *title*" without the 
     326hyperlink, for example. 
    227327 
    228328### Cleaning up after your stream ### 
    229329 
    230 Some streams may not leave in the correct displayable format. For example, the regular Twitter tweet feeds include the authors' usernames with the tweets. The Twitter stream needs to remove to correctly collect only the tweet text. How can it remove the usernames from the collected actions? 
    231  
    232 Movable Type provides a system for defining *callbacks*, or code hooks that are run at certain points of a process. The Action Streams plugin provides several callbacks at various stages of stream event collection. You will have to use Perl code to write these callbacks, but as you're doing very small things, the code is usually simple. 
    233  
    234 For example, the Twitter stream uses the `pre_build_action_streams_event` callback to modify the actions after they're collected by the normal feed collector, but before they are saved. The callback is defined in the registry thus: 
     330Some streams may not leave in the correct displayable format. For example, the 
     331regular Twitter tweet feeds include the authors' usernames with the tweets. 
     332The Twitter stream needs to remove to correctly collect only the tweet text. 
     333How can it remove the usernames from the collected actions? 
     334 
     335Movable Type provides a system for defining *callbacks*, or code hooks that 
     336are run at certain points of a process. The Action Streams plugin provides 
     337several callbacks at various stages of stream event collection. You will have 
     338to use Perl code to write these callbacks, but as you're doing very small 
     339things, the code is usually simple. 
     340 
     341For example, the Twitter stream uses the `pre_build_action_streams_event` 
     342callback to modify the actions after they're collected by the normal feed 
     343collector, but before they are saved. The callback is defined in the registry 
     344thus: 
    235345 
    236346    callbacks: 
     
    252362        } 
    253363 
    254 The Action Streams callbacks available to you are documented later. See the Movable Type developer documentation for more about defining callbacks. 
     364The Action Streams callbacks available to you are documented later. See the 
     365Movable Type developer documentation for more about defining callbacks. 
    255366 
    256367## Stream recipe option reference ## 
    257368 
    258 Recipes describe how to collect and display users' actions on profile services. They are found in the `action_streams` section of the registry, in sections named the same as the related service in the  `profile_services` section. 
     369Recipes describe how to collect and display users' actions on profile 
     370services. They are found in the `action_streams` section of the registry, in 
     371sections named the same as the related service in the  `profile_services` 
     372section. 
    259373 
    260374The options you can set for action streams are: 
     
    262376### `name` (required) ### 
    263377 
    264 The name of the action stream. This is displayed to authors when they enter their profile service identifier, where they are given the option of collecting the stream. 
     378The name of the action stream. This is displayed to authors when they enter 
     379their profile service identifier, where they are given the option of 
     380collecting the stream. 
    265381 
    266382### `description` (required) ### 
    267383 
    268 The description of the action stream. This is displayed to authors with the stream's name when they enter profile identifiers. 
     384The description of the action stream. This is displayed to authors with the 
     385stream's name when they enter profile identifiers. 
    269386 
    270387### `fields` ### 
     
    272389The list of additional fields supported by actions of this stream. 
    273390 
    274 Every stream already has a set of standard fields. You need only specify additional fields beyond these. The standard fields are: 
     391Every stream already has a set of standard fields. You need only specify 
     392additional fields beyond these. The standard fields are: 
    275393 
    276394#### `title` #### 
     
    284402#### `thumbnail` #### 
    285403 
    286 The web address (URL) of a thumbnail image of the page/asset/resource the action is about. 
     404The web address (URL) of a thumbnail image of the page/asset/resource the 
     405action is about. 
    287406 
    288407#### `identifier` #### 
     
    292411#### `created_on` #### 
    293412 
    294 When the action was taken. This is *not* necessarily when the page/asset/resource the action is about was created; when a link is saved or a video is favorited, for example. 
     413When the action was taken. This is *not* necessarily when the 
     414page/asset/resource the action is about was created; when a link is saved or a 
     415video is favorited, for example. 
    295416 
    296417#### `modified_on` #### 
    297418 
    298 When the action was last altered. Many actions occur only once and will never change, but some may (such as if the author changes the rating or tags for a saved link). Action Streams will update this timestamp automatically when the action object is changed. 
     419When the action was last altered. Many actions occur only once and will never 
     420change, but some may (such as if the author changes the rating or tags for a 
     421saved link). Action Streams will update this timestamp automatically when the 
     422action object is changed. 
    299423 
    300424### `html_form` ### 
    301425 
    302 The formatting string for formatting an action for display. Numbered replacement tokens are replaced with the author's name and the values of the fields named in `html_params`. 
     426The formatting string for formatting an action for display. Numbered 
     427replacement tokens are replaced with the author's name and the values of the 
     428fields named in `html_params`. 
    303429 
    304430### `html_params` ### 
    305431 
    306 The list of additional fields to replace into `html_form` when displaying an action. 
     432The list of additional fields to replace into `html_form` when displaying an 
     433action. 
    307434 
    308435### `url` ### 
    309436 
    310 The URL from which to collect action data. The token `{{ident}}` will be replaced with the author's identifier on that service. 
     437The URL from which to collect action data. The token `{{ident}}` will be 
     438replaced with the author's identifier on that service. 
    311439 
    312440### `identifier` ### 
    313441 
    314 The name of the field to use as the unique identifier. Multiple fields can be specified by separating their names with commas (for example: `title,created_on`). 
    315  
    316 If not given, the collection recipe should collect an `identifier` field from the action source. If an `identifier` field is not collected, each action will be considered unique, regardless of the content of the other fields. 
     442The name of the field to use as the unique identifier. Multiple fields can be 
     443specified by separating their names with commas (for example: 
     444`title,created_on`). 
     445 
     446If not given, the collection recipe should collect an `identifier` field from 
     447the action source. If an `identifier` field is not collected, each action will 
     448be considered unique, regardless of the content of the other fields. 
    317449 
    318450### `xpath` ### 
    319451 
    320 The XPath recipe with which to collect action data. The recipe options for an XPath recipe are: 
     452The XPath recipe with which to collect action data. The recipe options for an 
     453XPath recipe are: 
    321454 
    322455#### `foreach` (required) #### 
    323456 
    324 The XPath selector that selects the nodes of the resource document that represent actions. All the `get` selectors are then applied to each node to find the action data. 
     457The XPath selector that selects the nodes of the resource document that 
     458represent actions. All the `get` selectors are then applied to each node to 
     459find the action data. 
    325460 
    326461#### `get` (required) #### 
    327462 
    328 A set of XPath selectors, keyed on the names of the action fields they describe. To find the value of each field, the indicated selector is applied to each node as determined by the `foreach` selector. 
     463A set of XPath selectors, keyed on the names of the action fields they 
     464describe. To find the value of each field, the indicated selector is applied 
     465to each node as determined by the `foreach` selector. 
    329466 
    330467### `rss` ### 
    331468 
    332 The RSS recipe with which to collect action data. RSS recipes collect data from the standard RSS entry content. If child options are specified, each is used as an XPath selector (as in an `xpath` recipe's `get` option) to collect a field from the RSS `item` nodes. 
     469The RSS recipe with which to collect action data. RSS recipes collect data 
     470from the standard RSS entry content. If child options are specified, each is 
     471used as an XPath selector (as in an `xpath` recipe's `get` option) to collect 
     472a field from the RSS `item` nodes. 
    333473 
    334474### `atom` ### 
    335475 
    336 The Atom recipe with which to collect action data. Atom recipes collect data from the standard Atom feed content. If child options are specified, each is used as an XPath selector (as in an `xpath` recipe's `get` option) to collect a field from the Atom `entry` nodes. 
     476The Atom recipe with which to collect action data. Atom recipes collect data 
     477from the standard Atom feed content. If child options are specified, each is 
     478used as an XPath selector (as in an `xpath` recipe's `get` option) to collect 
     479a field from the Atom `entry` nodes. 
    337480 
    338481### `scraper` ### 
    339482 
    340 The Web::Scraper recipe with which to collect action data. The options for a Web::Scraper recipe are: 
     483The Web::Scraper recipe with which to collect action data. The options for a 
     484Web::Scraper recipe are: 
    341485 
    342486#### `foreach` (required) #### 
    343487 
    344 The CSS or XPath selector that selects the nodes of the resource document that represent the actions. All the `get` selectors are then applied to each node to find the action data. 
     488The CSS or XPath selector that selects the nodes of the resource document that 
     489represent the actions. All the `get` selectors are then applied to each node 
     490to find the action data. 
    345491 
    346492#### `get` (required) #### 
    347493 
    348 A set of Web::Scraper selectors, keyed on the names of the action fields they describe. Each selector is applied to each action node, as determined by the `foreach` selector, to find the action data. 
     494A set of Web::Scraper selectors, keyed on the names of the action fields they 
     495describe. Each selector is applied to each action node, as determined by the 
     496`foreach` selector, to find the action data. 
    349497 
    350498Each Web::Scraper selector is a two-element list: 
    351499 
    352500* The CSS or XPath selector to use to find a child node. 
    353 * `@`*`attribute`* or `TEXT` to select an attribute value or the text content of the node. 
     501* `@`*`attribute`* or `TEXT` to select an attribute value or the text content 
     502  of the node. 
    354503 
    355504### `class` ### 
    356505 
    357 The name of the Perl package to use to represent actions in this stream. The Perl package should be a subclass of `ActionStreams::Event`. See the `ActionStreams::Event` perldoc for information on defining an action stream in Perl code. 
     506The name of the Perl package to use to represent actions in this stream. The 
     507Perl package should be a subclass of `ActionStreams::Event`. See the 
     508`ActionStreams::Event` perldoc for information on defining an action stream in 
     509Perl code. 
    358510 
    359511## Stream recipe callback reference ## 
    360512 
    361 Action Streams specifies several callbacks for you to customize the creation of your action streams and the collection of their events. 
    362  
    363 Note that Movable Type's standard object callbacks are also available for the `ActionStreams::Event` objects representing actions. 
     513Action Streams specifies several callbacks for you to customize the creation 
     514of your action streams and the collection of their events. 
     515 
     516Note that Movable Type's standard object callbacks are also available for the 
     517`ActionStreams::Event` objects representing actions. 
    364518 
    365519### `pre_add_profile.`*`type`* ### 
    366520 
    367 Fires before an author's new profile is added. `type` is the ID (registry key) of the service being added. The parameters passed to your callback routine are: 
     521Fires before an author's new profile is added. `type` is the ID (registry key) 
     522of the service being added. The parameters passed to your callback routine 
     523are: 
    368524 
    369525* `$app`, the current MT::App through which the profile is being added 
    370526* `$user`, the MT::Author whose profile is being added 
    371 * `$profile`, a hashref containing the information about the profile being added: 
     527* `$profile`, a hashref containing the information about the profile being 
     528  added: 
    372529  * `type`, the ID of the profile service 
    373530  * `ident`, the user ID on the remote service 
    374531  * `label`, a user-facing description of the profile 
    375532  * `uri`, the URL of the profile page 
    376   * `streams`, a hashref with keys that are the stream IDs of the streams the author has selected to collect; all values are set to `1` 
     533  * `streams`, a hashref with keys that are the stream IDs of the streams the 
     534    author has selected to collect; all values are set to `1` 
    377535 
    378536### `post_add_profile.`*`type`* ### 
    379537 
    380 Fires after an author's new profile is added. The same parameters are passed to your callback routine as to a `pre_add_profile` routine. 
     538Fires after an author's new profile is added. The same parameters are passed 
     539to your callback routine as to a `pre_add_profile` routine. 
    381540 
    382541### `pre_remove_profile.`*`type`* ### 
    383542 
    384 Fires before a profile is removed. The parameters passed to your callback routine are: 
     543Fires before a profile is removed. The parameters passed to your callback 
     544routine are: 
    385545 
    386546* `$app`, the current MT::App through which the profile is being removed 
     
    391551### `post_remove_profile.`*`type`* ### 
    392552 
    393 Fires after a profile is removed. The parameters passed to your callback are the same as to a `pre_remove_profile` callback. 
     553Fires after a profile is removed. The parameters passed to your callback are 
     554the same as to a `pre_remove_profile` callback. 
    394555 
    395556### `pre_action_streams_task` ### 
    396557 
    397 Fires before the scheduled task to collect stream events is performed. The parameters to your callback routine are: 
    398  
    399 * `$mt`, the current MT instance through which the stream events will be collected 
     558Fires before the scheduled task to collect stream events is performed. The 
     559parameters to your callback routine are: 
     560 
     561* `$mt`, the current MT instance through which the stream events will be 
     562  collected 
    400563 
    401564### `post_action_streams_task` ### 
    402565 
    403 Fires after the scheduled task to collect stream events is completed. The parameters to your callback are the same as for `pre_action_streams_task`. 
     566Fires after the scheduled task to collect stream events is completed. The 
     567parameters to your callback are the same as for `pre_action_streams_task`. 
    404568 
    405569### `pre_update_action_streams_profile.`*`type`* ### 
    406570 
    407 Fires before the streams for a particular author's profile are collected. For example, this callback fires once before an author's Twitter streams (both the tweets and favorites streams) are collected. The parameters passed to your callback routine are: 
    408  
    409 * `$mt`, the current MT instance through which the stream events will be collected 
     571Fires before the streams for a particular author's profile are collected. For 
     572example, this callback fires once before an author's Twitter streams (both the 
     573tweets and favorites streams) are collected. The parameters passed to your 
     574callback routine are: 
     575 
     576* `$mt`, the current MT instance through which the stream events will be 
     577  collected 
    410578* `$author`, the MT::Author whose streams are being collected 
    411 * `$profile`, a hashref containing all the information about the profile; this is the same as the `$profile` argument to the `pre_add_profile` callback 
     579* `$profile`, a hashref containing all the information about the profile; this 
     580  is the same as the `$profile` argument to the `pre_add_profile` callback 
    412581 
    413582### `post_update_action_streams_profile.`*`type`* ### 
    414583 
    415 Fires after the streams for a particular author's profile are collected. The parameters passed to your callback routine are the same as to `pre_update_action_streams_profile`. 
     584Fires after the streams for a particular author's profile are collected. The 
     585parameters passed to your callback routine are the same as to 
     586`pre_update_action_streams_profile`. 
    416587 
    417588### `pre_build_action_streams_event.`*`type`* ### 
    418589 
    419 Fires after a stream event is collected, but before it's put into the `ActionStreams::Event` object. The parameters given to your callback routine are: 
     590Fires after a stream event is collected, but before it's put into the 
     591`ActionStreams::Event` object. The parameters given to your callback routine 
     592are: 
    420593 
    421594* `$mt`, the current MT instance through which the stream event was collected 
    422595* `$item`, a hashref containing the data collected for this event 
    423 * `$event`, the `ActionStreams::Event` into which the event data will put; this is either a new empty `ActionStreams::Event`, or the previously version of this event as determined by the value of the stream recipe's identifier field 
     596* `$event`, the `ActionStreams::Event` into which the event data will put; 
     597  this is either a new empty `ActionStreams::Event`, or the previously version 
     598  of this event as determined by the value of the stream recipe's identifier 
     599  field 
    424600* `$author`, the MT::Author whose stream is being collected 
    425 * `$profile`, a hashref containing all the information about the profile; this is the same as the `$profile` argument to the `pre_add_profile` callback 
     601* `$profile`, a hashref containing all the information about the profile; this 
     602  is the same as the `$profile` argument to the `pre_add_profile` callback 
    426603 
    427604### `post_build_action_streams_event.`*`type`* ### 
    428605 
    429 Fires after a stream event is composed, but before it is saved. The parameters passed to your callback routine are the same as to `pre_build_action_streams_event`. 
     606Fires after a stream event is composed, but before it is saved. The parameters 
     607passed to your callback routine are the same as to 
     608`pre_build_action_streams_event`. 
     609