This chapter discusses how to:
Analyze requirements for new feed data types.
Create the feed data source application class.
Define the feed data type.
Update the property maintenance component.
Update the view content component or pagelet.
Note. The last section in this chapter provides examples of specific feed types.
When developing a new feed data type, you should consider these issues:
Decide how to distinguish feeds of the same data type, which you will implement as data source settings for the feed. For example, the data source setting for a discussion forum is the forum ID; the data source settings for a content management folder are the portal name and folder ID.
Decide how you will configure the feeds and what the default value is for each data source parameter. For example, the data source parameter for a discussion forum is the maximum number of entries with a default of 10. The data source parameters for a content management folder are the maximum number of entries with a default of 10 and an include subfolder flag with a default of yes.
Decide what data will be published as feed entries. For example, a discussion forum publishes the complete post, author, tags, attachment, and timestamp in each feed entry; a content management folder publishes the content summary, author, tags, attachment, and timestamp in each feed entry.
Decide whether you want the feed to be generated as a scheduled feed or as a real-time feed.
Decide who will have the authority to create and manage feed definitions.
Decide where you will locate the Publish as Feed link.
Decide where you will locate the related feeds hover menu.
Decide how you want to handle real-time feed security and GETFEED viewer permission requests.
The feed data source application class manages all aspects of data collection and data security.
To create a feed data source application class for your new feed data type:
Extend the PTFP_FEED:DataSource:DataSource base class.
Implement the DataSource methods.
Set read-only flags by using protected methods.
Implement a new class that extends the PTFP_FEED:DataSource:DataSource base class.
See Creating Application Packages and Classes.
When implementing the methods of the DataSource class, consider these method types:
Required methods
Recommended methods
Optional methods
This table describes the DataSource methods that you must implement:
Method |
Purpose |
|
Clone the data source object. |
|
Return the feed content URL. |
|
Return the allowed list of viewer roles, permission lists, or both. |
|
Validate whether the current user has permission to view the feed. |
|
Initialize the data source setting collection and other class properties. |
|
Validate data source setting values and generate a data source parameter list accordingly. |
|
Collect data based on user permissions and fill in the feed document. |
This table describes the DataSource methods that you should consider implementing:
Method |
Purpose |
|
Validate whether the current user has permission to administer the feed. |
|
The clone method uses protected methods for copying class properties. |
This table describes the DataSource methods that you might consider implementing:
Method |
Purpose |
|
Perform tasks after saving the feed definition. |
|
Perform tasks before deleting the feed definition. |
|
Return data source setting details as HTML. |
|
Return data source parameter details as HTML. |
You should use these protected methods to set read-only flags:
setDataSourceType
setSettingsCompleted
setAllowRealTimeFeedSecurity
This section lists the steps for defining a new feed data type and discusses how to:
Define a new feed data type.
Determine whether additional advanced options are available.
Page Name |
Definition Name |
Navigation |
Usage |
Define Feed Data Types |
PTFP_DATATYPE |
PeopleTools, Feeds, Define Feed Data Types |
Define feed data types. |
You complete these steps to define a new feed data type:
Select PeopleTools, Feed, Define Data Types.
Specify the data source application class.
Select the service operations to be used by feeds of this data type and specify the default service operation.
Specify the default feed head level attributes for feeds of this data type.
(Optional) Click the Publish as Feed link to create a list of feeds feed, which lists all feeds of this data type that the user can access.
Determine whether additional advanced options are available.
Access the Define Feed Data Types page (PeopleTools, Feeds, Define Feed Data Types).
PeopleTools delivers the following feed data types: FEED, GENERICFEED, PSQUERY, PTSF_SES_FEED_DT, and WORKLIST. To create a new feed data type, use the Add New Value field on the search page.
Data Type |
Displays the type of feed that you are creating or editing. This field is display-only. |
Description |
Enter a short description of the type of feed. You may enter up to 30 characters. |
Long Description |
Enter a long description of the type of feed to clearly describe its purpose. You may enter up to 255 characters. |
Active |
Select to activate the feed definition. |
Not all readers display all properties. This table describes the default feed properties that some feed readers process and display.
Note. These properties are the defaults. You can change any of these default properties at the individual feed level.
Copyright |
Enter copyright information to be included in the XML. |
Logo |
Enter a URL to the logo to be included in the XML, for example, http://myserver.com/img/logo.gif. |
Icon |
Enter a URL to an icon to be included in the XML, for example, http://myserver.com/img/icon.gif. |
Author Name |
Enter an author name to be included in the XML. |
Author Email |
Enter an author's email address to be included in the XML. |
Contributor Name |
Enter a contributor's name to be included in the XML. |
Contributor Email |
Enter a contributor's email address to be included in the XML. |
Package Name |
Enter the application class package name that you want to use for the data type. Each Feed Data Type application class should be associated with one Feed Data Type service operation. |
Path |
Enter the application class path that you want to use for the data type. |
Application Class ID |
Enter the name of the application class that you want to use for the data type. The class must exist in the application package name that you specify. |
Service Operation |
Enter the name of the service operations associated with the feed definition that are used to retrieve data. |
Type |
Displays whether the service operation is real-time or scheduled. This field is display-only. |
Default |
Select this check box to make this service operation the default. |
The standard advanced option page, PTFP_PUB_AS_ADVOPT, has one advanced option: Max Number of Entries. If your new feed data type has additional data source parameters (such as a paged feed, an incremental feed, or other parameters), then you must create a custom advanced options page. Otherwise, you can use the standard advanced options page shown in this example:
See Also
Creating an Advanced Options Page
To update property maintenance components, you complete the tasks described in this section.
This section discusses how to:
Add the four standard Publish as Feed pages.
Add the Publish as Feed link to a page in the component.
Create an advanced options page.
Add record PeopleCode.
You must add these four standard, hidden Publish as Feed pages to the component:
Publish Feed Definition (PTFP_PUB_AS_FEED)
Advanced Feed Options (PTFP_PUB_AS_ADVOPT)
Publish as Feed (PTFP_PUB_AS_LIST)
Publish Feed Definition to Sites (PTFP_PUB_AS_SITES)
Note. You can clone and then modify all four pages to suit the unique requirements of the new feed data type.
Access the component, add the pages, and configure the pages as hidden, as shown in this example:
See Adding Pages to Components.
To publish the new feed data type, the feed administrator must have access to the Publish as Feed pages. To access these pages, you must add the Publish as Feed link to a page in the component.
In the following example, notice the Publish As Feed link in the lower left corner of the PTFP_DATATYPE page:
See Using Push Buttons and Links.
The advanced options page is used to set data source parameters for each feed definition. The standard advanced option page, PTFP_PUB_AS_ADVOPT, has one advanced option: Max Number of Entries. If your new feed data type has additional data source parameters (such as a paged feed, an incremental feed, or other parameters), then you must create a custom advanced options page. Otherwise, you can use the standard advanced options page shown in this example:
To create a custom advanced options page:
Clone the PTFP_PUB_AS_ADVOPT page as a feed data type-specific advanced options page.
Add the feed data type-specific data source parameters to the page.
In the page Activate event, create a PeopleCode program to read the data source parameter values from the feed definition.
Create an additional PeopleCode program to set the data source parameter values to the feed definition when the page is closed.
Example
This is the Query Advanced Options page. Notice how this page differs from the standard page.
See Also
Add the following code to the FieldChange event for the “Publish as Feed” component record field:
import PTFP_FEED:UTILITY:PublishAsRequest; Declare Function initialize PeopleCode PTFP_PA_WORKREC.FUNCLIB FieldFormula; Local PTFP_FEED:UTILITY:PublishAsRequest &request; Local array of string &thisDSS; /* Create and fill in the request object */ &request = create PTFP_FEED:Utility:PublishAsRequest("<unique ID>"); &request.TransactionPageName = Page.<Page Name>; &request.TransactionTitle = "<Page Title>"; &request.ContentTitle = "<Default Feed Title>"; &request.ContentDescription = "<Default Feed Description>"; &request.AdvancedOptionsPageName = Page.<Page Name>; &request.DataTypeID = "yourDataTypeID"; /* Fill in the data source setting values */ &thisDSS = CreateArray("<Data Source Setting Name>", "<Data Source ⇒ Setting Value>"); &request.DataSourceSettings.Push(&thisDSS); /* Start the process */ initialize(&request);
Example
Notice the component record field PeopleCode on the PTFP_PUB_AS_PB field in this example:
Note. Where you add the record PeopleCode depends on which record field is used for the Publish as Feed page. If you use the standard page, DERIVED_PTFP.PTFP_PUB_AS_PB, then you should only add code in the component record field FieldChange event. If the field is in your own work record, you can use the record FieldChange event directly.
See Also
Accessing Record Field PeopleCode
Accessing Component Record Field PeopleCode
This section discusses how to:
Add the related feeds hover menu to pages.
Add component or page PeopleCode.
Add the related feeds hover menu to Pagelet Wizard pagelets.
Add an HTML area to the page for hosting the related feeds hover menu.
Example
Notice the HTML area in the upper right of the PTFP_DATATYPE page:
See Also
Add the following PeopleCode to the Activate event for the page:
import PTFP_FEED:FeedFactory; import PTFP_FEED:UTILITY:HoverMenu; import PTFP_FEED:UTILITY:RelatedFeedsRequest; Local PTFP_FEED:FeedFactory &PTFP_FEED_FACTORY; Local PTFP_FEED:UTILITY:RelatedFeedsRequest &request; Local array of PTFP_FEED:UTILITY:RelatedFeedsRequest &requests; Local PTFP_FEED:UTILITY:HoverMenu &resultMenu; &PTFP_FEED_FACTORY = create PTFP_FEED:FeedFactory(); /* Fill in the search criteria */ &request = create PTFP_FEED:UTILITY:RelatedFeedsRequest("<Unique ID>"); &request.DataTypeID = "<yourDataTypeID>"; &request.DataSourceSettings.Push(CreateArray("<Data Source Setting Name>", ⇒ "<Data Source Setting Value>")); &requests.Push(&request); try /* Generate the menu */ &resultMenu = &PTFP_FEED_FACTORY.getRelatedFeedsHoverMenu(&requests); DERIVED_PTFP.PTFP_HTMLAREA.Value = &resultMenu.getHtml(); catch Exception &e WinMessage(&e.ToString(), %MsgStyle_OK); end-try;
See Accessing Page PeopleCode.
Example
In this example, you see the Page PeopleCode on the Activate event:
When adding the hover menu, consider these points:
Only homepage pagelets and embeddable pagelets on application pages support the related feeds hover menu.
Transformer output must be XML or XHTML.
Multi-group feed menu is supported.
Example: Related Feeds Hover Menu XSL
This is sample XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="NumRows"> <xsl:value-of select="count(/queryresult/queryrows/row)" /> </xsl:variable> <xsl:template match="/"> <table border="0" cellpadding="1" cellspacing="1" width="100%" summary=""> <xsl:if test="$NumRows=0"> <tr><td class="PSTEXT">no data available</td></tr> </xsl:if> <xsl:if test="$NumRows>0"> <tr><td> <PSRELATEDFEEDSLINK> <feed id="ADMN_LIST_OF_FEEDS" /> <feeds> <label>PSQUERY Feed List Feeds</label> <description>List of all PSQUERY feed list feeds</description> <feedDataType id="FEED" /> <dataSourceSetting id="PTFP_DATATYPE_ID" value="PSQUERY" /> </feeds> </PSRELATEDFEEDSLINK> </td></tr> </xsl:if> </table> </xsl:template> </xsl:stylesheet>
This section provides examples of specific steps required when developing these feed types:
Up-front scheduled feeds
Real-time incremental feeds
Paged feeds
Creating up-front scheduled feeds requires additional steps. You must complete the following tasks when creating up-front scheduled feeds:
Ensure that the service operation you use to publish the up-front feed messages to the Integration Broker queues satisfies these conditions:
It must be an asynchronous, one-way service operation.
It must have PT_FEED_REQUEST.VERSION_1 as the message.
It must be secured appropriately. This security is enforced by the scheduled feed GetFeed service operation handler at run time.
The queue used in the service operation must have the Archive option enabled if the up-front feeds are to be archived. If this option is not enabled, then the Archival Feeds will delete the feed messages in the Integration Broker queue.
List the service operation used to publish the up-front feed messages in the Define Feed Data Types page. The system uses this information to archive feeds.
Set the feed format and language as message attributes before publishing the message:
/* Set the feed format of the message (i.e. Atom 1.0). */ &succeeded = &responseMsg.IBInfo.AddAttribute(&feedFactory.Utility.⇒ QUERYPARAMETER_FEEDFORMAT, &feedDoc.FeedFormat); /* Set the language of the message. */ &succeeded = &responseMsg.IBInfo.AddAttribute(&feedFactory.Utility.⇒ QUERYPARAMETER_LANGUAGE, %Language);
Define the DSPARAMETER_MAXROW, DSPARAMETER_SF_PAGING, DSPARAMETER_INCREMENTAL, and DSPARAMETER_SF_MAXMINUTES data source parameters found in the PTFP_FEED:UTILITY:Utility application class and set them to appropriate values in your implementation of the processSettingsChange method for your data source. The system requires DSPARAMETER_MAXROW and DSPARAMETER_SF_MAXMINUTES for archiving feeds and it uses DSPARAMETER_SF_PAGING for paged feeds and DSPARAMETER_INCREMENTAL for incremental feeds.
For example:
&thisDSP = %This.addParameter(&utility.DSPARAMETER_MAXROW, ⇒ String(&utility.SF_MAXROWOPTION_LATESTMSG)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3005, "Message Not Found - ⇒ Max Entries"); &thisDSP.FieldType = &utility.FIELDTYPE_NUMBER; &thisDSP.DefaultValue = String(&utility.SF_MAXROWOPTION_LATESTMSG); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True; &thisDSP = %This.addParameter(&utility.DSPARAMETER_SF_PAGING, ⇒ String(&utility.SF_PAGINGOPTION_NOPAGING)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3006, "Message Not Found - Paging"); &thisDSP.FieldType = &utility.FIELDTYPE_SIGNEDNUMBER; &thisDSP.DefaultValue = String(&utility.SF_PAGINGOPTION_NOPAGING); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True; &thisDSP = %This.addParameter(&utility.DSPARAMETER_INCREMENTAL, ⇒ String(&utility.INCREMENTALOPTION_NO)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3008, "Message Not Found - Incremental"); &thisDSP.FieldType = &utility.FIELDTYPE_SIGNEDNUMBER; &thisDSP.DefaultValue = String(&utility.INCREMENTALOPTION_NO); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True; &thisDSP = %This.addParameter(&utility.DSPARAMETER_SF_MAXMINUTES, ⇒ String(&utility.SF_MAXMINUTES_ALLMSGS)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3007, "Message Not Found - Max Min"); &thisDSP.FieldType = &utility.FIELDTYPE_SIGNEDNUMBER; &thisDSP.DefaultValue = String(&utility.SF_MAXMINUTES_ALLMSGS); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True;
Important! The incremental feed option is incompatible with the paged feed option. Do not allow both options to be set simultaneously.
Modify the associated advanced feed options page to allow feed administrators the ability to set these options.
See Also
Creating real-time incremental feeds also requires additional steps. You must complete the following tasks when creating real-time incremental feeds:
Define the DSPARAMETER_INCREMENTAL data source parameter found in the PTFP_FEED:UTILITY:Utility application class and set it to an appropriate value in your implementation of the processSettingsChange method for your data source :
&thisDSP = %This.addParameter(&utility.DSPARAMETER_INCREMENTAL, ⇒ String(&utility.INCREMENTALOPTION_NO)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3008, "Message Not Found - Incremental"); &thisDSP.FieldType = &utility.FIELDTYPE_SIGNEDNUMBER; &thisDSP.DefaultValue = String(&utility.INCREMENTALOPTION_NO); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True;
Important! The incremental feed option is incompatible with the paged feed option. Do not allow both options to be set simultaneously.
Modify the associated advanced feed options page to allow feed administrators the ability to set this option.
Generate delta feed entries in your implementation of the execute method for your data source based on the QUERYPARAMETER_IFMODIFIEDSINCE query parameter of the PTFP_FEED:UTILITY:Utility application class.
Your implementation of the execute method must contain both the QUERYPARAMETER_IFNONEMATCH and the QUERYPARAMETER_IFMODIFIEDSINCE query parameters. QUERYPARAMETER_IFNONEMATCH is the feed ID and QUERYPARAMETER_IFMODIFIEDSINCE is the time at which the feed was last requested.
The following code excerpt shows how to get the QUERYPARAMETER_IFNONEMATCH and QUERYPARAMETER_IFMODIFIEDSINCE query parameters using RequestInfo in the execute method of the data source:
Local PTFP_FEED:DataSource:DataSourceParameter &thisDSP; Local string &ifNoneMatch, &ifModifiedSince, &select; Local datetime &lastmodified_dt = DateTime6(1900, 1, 1, 0, 0, 0); Local boolean &incremental; /* Get the Incremental Parameter */ &thisDSP = %This.getParameterById(&utility.DSPARAMETER_INCREMENTAL); If &thisDSP <> Null And (&thisDSP.EvaluatedValue = String(&utility.INCREMENTALOPTION_YES)) Then &incremental = True; Else &incremental = False; End-If; &ifNoneMatch = &utility.RequestInfo.getParameter(&utility.QUERYPARAMETER_⇒ IFNONEMATCH); &ifModifiedSince = &utility.RequestInfo.getParameter(&utility.QUERYPARAMETER_⇒ IFMODIFIEDSINCE); If All(&ifModifiedSince) Then &lastmodified_dt = &utility.httpStringToDatetime(&ifModifiedSince); End-If; /* Compare and verify that &ifNoneMatch is same as the feed ID */ /* Compare the &lastmodified_dt with appropriate datetime column like the */ /* LASTUPDDTTM field in the record used for generating the feed entries */
When the execute method of a data source returns no feed entries, the Feed Publishing Framework issues a 304-Not Modified HTTP header. If you are using a custom feed handler—that is, a service operation different from the PTFP_GETFEED service operation —then use the setMessageHeadersAndMimeType method to set HTTP conditional headers.
For example:
method OnRequest /+ &pRequestMsg as Message +/ /+ Returns Message +/ /+ Extends/implements PS_PT:Integration:IRequestHandler.OnRequest +/ Local Message &responseMsg; Local XmlDoc &xmlDoc; Local string &temp, &errorText; Local PTFP_FEED:UTILITY:Utility &utility = &feedFactory_inst.Utility; Local PTFP_FEED:XML_FEED:FeedDoc &feedDoc; Local PTFP_FEED:UTILITY:FeedRequest &request; /* Ccreate the Search Request object */ &request = create PTFP_FEED:UTILITY:FeedRequest("FeedRequest"); ... try &feedDoc = &feedFactory_inst.getFeedDoc(&request); catch PTFP_FEED:EXCEPTION:NotFoundException &ex1 &errorText = MsgGetExplainText(219, 3112, "(Message not found) Not Found"); catch PTFP_FEED:EXCEPTION:PrivilegeException &ex2 &errorText = MsgGetExplainText(219, 3113, "(Message not found) ⇒ Not Authorized"); catch PTFP_FEED:EXCEPTION:FeedException &ex3 &errorText = &utility.getExceptionText(&ex3); end-try; /* Create the response message */ &responseMsg = CreateMessage(Operation.PTFP_GETFEED, %IntBroker_Response); If None(&errorText) Then &responseMsg = &utility.setMessageHeadersAndMimeType(&responseMsg, ⇒ &feedDoc, &request); Else &temp = "<?xml version='1.0' encoding='UTF-8'?><ErrorMessage>" | ⇒ &errorText | "</ErrorMessage>"; &xmlDoc = CreateXmlDoc(&temp); &responseMsg.SetXmlDoc(&xmlDoc); &responseMsg.SegmentContentType = &utility.MIMETYPE_XML; End-If; Return &responseMsg; end-method;
Creating paged feeds also requires additional steps.
Note. Paged feeds are supported for scheduled feeds only. The framework supports paged feeds via Integration Broker message segments. %MaxMessageSize is recommended when creating Integration Broker message segments for paged feeds.
You must complete the following tasks when creating paged feeds:
Define the DSPARAMETER_SF_PAGING data source parameter found in the PTFP_FEED:UTILITY:Utility application class and set it to an appropriate value in your implementation of the processSettingsChange method for your data source.
For example:
/* PAGING parameter */ &thisDSP = %This.addParameter(&utility.DSPARAMETER_SF_PAGING, ⇒ String(&utility.SF_PAGINGOPTION_NOPAGING)); &thisDSP.Name = &thisDSP.ID; &thisDSP.Description = MsgGetText(219, 3007, "Message Not Found - Page Size"); &thisDSP.FieldType = &utility.FIELDTYPE_SIGNEDNUMBER; &thisDSP.DefaultValue = String(&utility.SF_PAGINGOPTION_NOPAGING); &thisDSP.Value = &thisDSP.DefaultValue; &thisDSP.Required = True;
Important! The paged feed option is incompatible with the incremental feed option. Do not allow both options to be set simultaneously.
Modify the associated advanced feed options page to allow feed administrators the ability to set this option.