Add a custom content source
We can also add our own custom content.To do this, proceed by the steps given in the following.
These instructions are intended for adminstrators and require basic javascript, json and dojo knowledge.
- Choose a content source with REST feeds containing items that can be added to a page.
- Create a data store for the source that complies with the Dojo Read API. If the source is in JSON format, extend the dojo.data.ItemFileReadStore or com.ibm.data.JsonStore.
- Extend the data store by subclassing com.ibm.portal.data.CatalogMixin, including the mapItem and prepareQuery functione that allow the Add Content widget to search and access all of the sources uniformly. Refer to the following descriptions to learn more about the mapItem and prepareQuery functions:
- mapItem
- Returns a mas containing parameters for a given data store item. The following map keys are single strings: label, description, rating, url, thumbnail, and id. The map key tags is an array of strings. When all of the data stores create item maps with the same keys, widgets can uniformly access information across all sources. If a data store does not have an appropriate attribute for one of the keys, the map entry can be omitted or a static default value can be substituted. We can also add custom attributes that you need for step 4 to the map.
- Example: This data store item has the title, summary, rating, and identifier attributes:
mapItem: function(/*DatastoreItem*/ item) { // does not include the "tags", "thumbnail", and "url" keys var map = {}; map["label"] = this.getValue(item, "title", "untitled"); map["description"] = this.getValue(item, "summary", ""); map["rating"] = this.getValue(item, "rating", 0); map["id"] = this.getValue(item, "identifier", ""); return map; }
- prepareQuery
- Provides an extension point to modify the keywordArgs object used in dojo.data.api.Read.fetch so its query parameters can be used to create the feed url. It is called after keywordArgs.query has been normalized to an object map but before any other processing has taken place to build the url. Any other items in the query parameter are appended to the feed url in the form (?|&)key1=value1&key2=value2&key3=value3=value3.
- Extracts other parts of the keywordsArgs map to add properties to the query object that are dependent on the back end implementation of the feed. Properties of keywordArgs.querthat are not part of the URL should be deleted.
- Example: See how the prepareQuery function is used when a feed URL has the searchTerms, startIndex, and count parameters:
prepareQuery: function(/*Object*/ keywordArgs) { if(keywordArgs.query.keywords) { // searchTerms is a comma separated list of search parameters keywordArgs.query.searchTerms = keywordArgs.query.keywords.join(","); delete keywordArgs.query.keywords; } if(keywordArgs.count) { keywordArgs.query.count = keywordArgs.count; if(keywordArgs.start == null) { keywordArgs.start = 0; } keywordArgs.query.startIndex = keywordArgs.start; } }In this example, if the keywordArgs.query.keywords had a value of ["term1","term2","term3"], keywordArgs.count has a value of 12, and keywordArgs.start had a value of 3, the result is a URL like: http://baseURL?searchTerms=term1,term2,term3&count=12&startIndex=3.
- Determine what will be used to render a piece of content from the data store. For each renderer, write a short function that takes an item map returned by the mapItem function, from com.ibm.portal.data.CatalogMixin and returns a map of preferences that the renderer can use to display the content.
For example, this function creates the preference map for the Feed Reader portlet:
feedReader: function(/*Object*/itemMap) { var map = {}; map["FeedReaderPortlet_feedURL"] = itemMap.url.replace(/&/g,"&"); map["FeedReaderPortlet_feedName"] = itemMap.label; map["FeedReaderPortlet_feedActionPane"] = "false"; return map; }These functions are accessed by the Add Content widget using the dojo.getObject(String) function. You need to verify these functions are available in the theme. If you do not provide any renderers, each item from the source is assumed to be a renderer itself and will be added to the page directly. An example of this type of content are the portlets available in the Add Content widget out of the box.
- To register a new source with the Add Content widget, edit the addContent.json and addContent_wcm.json files located in WebDAV at dav/fs-type1/themes/Portal8.0/system/. Add this JSON to the categories array in the file:
{ "label":"your_category_name", "searchStr":"Search your_category_name", "datastore":"your.Datastore.Name", "url":"base_url_to_your_source_REST_service" "visibilityFn":"my.visibility.function.path", "renderers":[{"id":"renderer_unique_id", "label":"renderer_name", "fcn":"renderer.prefMapper.fcn.name"}, {"id":"another_renderer_unique_id", "label":"renderer_name", "fcn":"another.renderer.prefMapper.fcn.name"}] }Example of a category containing all portlet definitions tagged with "myShelfCategoryTag":{ "label":"My category with tags", "searchStr":"Search my category with tags", "datastore":"com.ibm.pb.data.TaggedItemStore", "visibilityFn":"com.ibm.theme.shelf.checkForVP", "url":ibmPortalConfig.contentHandlerURI + "rm/empty?tmparam=tm%3aname%3amyShelfCategoryTag", "renderers":[] }The label and search string for the category are two separate attributes. The label shows up in the list of categories on the side of the toolbar. The search string shows up as text in the search box. They are two separate strings, because simply concatenating “Search” and the label does not work correctly in all languages. If translation is not an issue, we can leave the searchStr attribute out of the category definition. In this case concatenation is used.
The visibilityFn attribute can be used to control whether or not the category shows up. Its value is a string containing the dot notation for a function which can be retrieved by dojo.getObject(String). A return value of false will hide the category.
We can also add a new content source using the webdav-modify-file configuration task, instead of editing the addContent.json and addContent_wcm.json files directly. For details, refer to Registering a new content source with a ConfigEngine task.
- Decide whether to nationalize the category, source, and renderer display strings provided in the json file. To do this, the json files must provide a localizationPackageName and a localizationBundleName like so:
{ localizationPackageName:'bundle object notation', localizationBundleName:'bundle name', categories:[category array] }These will be used by dojo.i18n to provide localized strings by creating bundles with dojo.i18n.getLocalization("bundle object notation", "bundle name") . If there is already a bundle provided in the json file, add to it the keys and values needed. Otherwise, create a new bundle. To use the new keys, they must be provided in the json file in place of the display strings. The widgets will automatically pull the value out of the bundle for each key. Here is an example of a completed json file with the keys highlighted:{ localizationPackageName:"com.ibm.bundles", localizationBundleName:"Shelf", categories:[ { "label":"new_createCategory", "searchStr":"shelf_searchCreate", "datastore":"com.ibm.data.JsonStore", "url":ibmCfg.themeConfig.themeRootURI+"/system/new.json", "renderers":[] }, { "label":"shelf_all", "searchStr":"shelf_searchAll", "datastore":"com.ibm.portal.data.InstalledPortletStore", "url":ibmPortalConfig.contentHandlerURI + "pdl/addable:oid:"+com.ibm.mashups.enabler.navigation.Factory.getNavigationModel(). find(com.ibm.mashups.builder.model.Factory.getRuntimeModel().getCurrentPage().getID()).start().getContent().start().getID()+"?rep=compact", "idPrefix":"pm:oid:", "renderers":[] }, { "label":"My Category", "searchStr":"Search my Category", "datastore":"com.ibm.pb.data.TaggedItemStore", "url":ibmPortalConfig.contentHandlerURI + "rm/empty?tmparam=tm%3aname%3amyCategoryTag", "renderers":[] } ] }
- To pick up the new files, refresh the browser cache.
- Verify the custom source has been added.
We can also add a new content source using the webdav-modify-file configuration task, instead of editing the addContent.json and addContent_wcm.json files directly. For details, refer to Registering a new content source with a ConfigEngine task.
Parent: Customize the site toolbar