Add-on Feed-Manager: Documentation

Search, read and import content easily from internal or external sources. This add-on quickly converts content from any XML-feed into documents.

Table of Contents

This is a paid Sophora add-on. For details, please refer to our website.

Working with the Feed-Manager

The feeds view can be used to import items of subscribed feeds to Sophora. The left part contains the list of subscribed feeds whereas the right-hand side consists of the items of the selected feed. Read section Importing Feeds for further information.

If you cannot see the feeds view, open it via User Menu >> Views >> Feeds.

Importing Feeds

In Sophora you can also integrate content from external sources that is provided by feeds. When you import a feed item, Sophora creates a corresponding document for you, a story for instance, and opens it automatically.

Feedmanager Sophora CMS

Before you can start, you have to subscribe to at least one feed within the feeds view. Click More Actions >> Edit Feed Subscriptions and select the feeds you want to subscribe to. Click OK to confirm your selection.

The subscribed feeds will be listed on the top whereas the items of the selected feed(s) will be shown below. To show all items of a feed or a group of feeds, select the according entry on the top. You can also change the display of feed items: Click on the Points Menu >> Display mode and select one out of three different ones.

The following operations are available for feed items. Note, that these operations are available in the Points Menu as well as in the context menu of feed items. You can select multiple items at once (left-click the items while keeping the CTRL key pressed) and, for example, import them in a single step.

  • Import – Imports the selected feed items and creates corresponding Sophora documents; stories for instance. The created documents will be opened in the editor section automatically as soon as the import finished successfully.
  • Update – Updates the corresponding Sophora documents with the item's content; thus, the selected feed items must already have been imported.
  • Open document – Opens the corresponding Sophora documents if the feed items have already been imported. This operation is only available in the context menu or by double-clicking an item.
  • Open in browser – Opens the websites referenced in the selected feed items within your default browser.

If you wish to update a certain feed or group of feeds, select the according entry on the top and click Points Menu >> Reload feed.

Feed items imported by other users are not displayed in imported state automatically. You have to refresh the feed by clicking Reload feed in the toolbar.

Feedmanager Menu Sophora CMS
Feeds context menu Sophora CMS

Searching Feeds

When you search for a certain keyword, all subscribed feeds will be scanned. If you search for multiple keywords, only those items are found that match all provided terms. The search result will then be displayed within the lower part of the view.

Administrating the Feed-Manager

Installation

The intention of the feeds view is that users can subscribe given XML feeds, read them and import relevant XML feed items as Sophora documents for further usage.

The administrator has to declare the available XML feeds in the Administration section and define the XSL transformation of the XML feed items into Sophora XML. The created Sophora XML will be imported into the Sophora system when the user imports the feed item via clicking the import icon in the top left corner of the feed item.

The very first time the feeds view is opened in the Sophora DeskClient (User >> Views >> Feeds) a dialog appears and asks for permission to register the required node types. After registration, (re-)open the Administration view which then contains two new entries: XML Feeds and XSL.

You may also be asked to perform a second update; if you agree, you also will see the entry XML Feed Importer Configurations. For informations about that, please see here.

If you declined the registration in the dialog, it can be triggered again by restarting the DeskClient and opening the Feeds view again.

Configuring XML Feeds

To configure feeds, at least two documents are required:

  1. a XML feed configuration document and
  2. a corresponding transformation document.

An XML Feed

To create a new XML feed, open the context menu of the XML Feeds entry and select New: XML Feed.

Each feed requires a name, the feed URL, a brief description (like the provider name), some XPath queries to read the XML items from the XML feed and a reference to an XSL transformation which transforms the feed items into valid Sophora XML, e.g. story documents.

The most important XPath field is the field Item-XPath. This XPath expression is applied to the complete XML document of the feed. It defines how the Feeds view finds the items in the XML feed. All other XPath expressions are relative to the XML snippet of the particular feed item. Only the XPath expression Item-XPath differs in this context: This XPath expression is applied to the result XML of the transformation process.

The name field is used to display the feed within the feeds view, grouped by the provider. The feed description appears as tooltip on each feed. The XPath fields, like Title XPath, Description XPath or Date XPath, declare the paths to the particular fields within the feed item, so that these fields can be displayed in the UI of the feeds view.

Some feed items contain an URL which points to an XML document with further and detailed content. If so, the Detail XPath field needs to be filled in, in order to find such URL within the feed item and get the actual content from the retrieved XML document.

The fields ID Stem and Structure Node contain the default Sophora ID stem and location for the imported documents. These fields are given as parameters idStem and structureNodePath to the XSL transformation process of the feed item. Moreover, custom parameters may be added to the XSL transformation by inserting them into the XSL Parameters table. So the same XSL transformation can be used for several feeds, but with different parameter values.

To check whether a feed item is already imported as a Sophora document or to update an already imported document, the external ID of the document is needed. The path to the external ID in the transformed feed item (that means the resulting Sophora XML) is defined in the field ExternalID XPath.

If the display of the item in the feeds view should contain a teaser image, the field Teaser Image XPath is required as well to get the URL of that image.

Be sure to publish the created feed documents because only the last published versions are respected and available for users.

The Transformation

To create a new XSL transformation, open the context menu of the XSL entry and select New: XSL.
Each XSL transformation consists of a name and the XSL code that transforms a feed item XML into Sophora XML.

There are a few predefined XSL template parameters which are set during the transformation process and thus can be used in the XSL templates.

VariableDescription
feedUrlThis is the URL of the feed.
detailUrlIf the feed uses detail XML documents, this parameter is set to the URL of the detail document for the current item.
idStemThis is the ID stem set in the feed configuration document.
structureNodePathThe structureNodePath contains the complete path as set in the feed configuration document; from the site 'down' to the target structure node.

To access these variables you only have to declare the parameters in the head of the XSL template as is shown in the following example code.

 

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
 
    <!-- Declaring the predefined parameters . -->
    <xsl:param name="idStem" />
    <xsl:param name="structureNodePath" />
    [...]
 
    <xsl:template match="story">
        <!-- Using a predefined parameter. -->
        <idstem>
            <xsl:value-of select="$idStem" />
        </idstem>
    </xsl:template>
 
</xsl:stylesheet>

Accessing custom parameters of a feed is analogous (defined within XSL Parameters table of its configuration document as explained above): If a parameter, for instance myCustomParameter, has been added to the XSL Parameters table of a feed, it is given to the XSL transformation process. There its value can be accessed via the variable $myCustomParameter if it was declared via an XSL-"param"-element: <xsl:param name="myCustomParameter" />.

Note that the current working version of the transformation document is used.
Exemplary Transformation

The following XSL template transforms an RSS/Metaplus feed item into the Sophora XML of a document of type "sophora-content-nt:story" with an external ID depending on the feed item. This XSL also transforms the teaser image information (if present) and thus an image document will be created along with the story document.

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0" xmlns:sophora="http://www.sophoracms.com/import/2.3"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss="http://purl.org/rss/1.0/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <xsl:output indent="yes" />
 
    <!-- Define the special parameters for ID stem and structure node -->
    <xsl:param name="idStem" />
    <xsl:param name="structureNodePath" />
 
    <xsl:template match="/rss:item">
        <sophora:documents>
            <!-- Determine the external ID of the Sophora document -->
            <xsl:variable name="externalID">
                <xsl:text>ts_rss_import_</xsl:text>
                <xsl:choose>
                    <xsl:when test="dc:identifier and normalize-space(dc:identifier) != ''">
                        <xsl:value-of select="dc:identifier" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="@rdf:about" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
 
            <!-- Determine the external ID of the teaser image of the Sophora document -->
            <xsl:variable name="externalIDImage"><xsl:value-of select="$externalID" />_image</xsl:variable>
 
            <!-- Create the Sophora document (a story) -->
            <sophora:document nodeType="sophora-content-nt:story" externalID="{$externalID}">
                <!-- Fill the documents properties with data of the feed item -->
                <sophora:properties>
                    <sophora:property name="sophora-content:topline">
                        <sophora:value>
                            <xsl:value-of select="substring-after(dc:subject, '/')" />
                        </sophora:value>
                    </sophora:property>
                    <sophora:property name="sophora-content:title">
                        <sophora:value>
                            <xsl:value-of select="rss:title" />
                        </sophora:value>
                    </sophora:property>
                    <sophora:property name="sophora-content:shorttext">
                        <sophora:value>
                            <xsl:value-of select="rss:description" />
                        </sophora:value>
                    </sophora:property>
                </sophora:properties>
 
                <!-- Add a reference to the Sophora document of the teaser image -->
                <sophora:childNodes>
                    <xsl:if test="*[local-name() = 'image' and contains(namespace-uri(), 'metaplus')]">
                        <sophora:childNode nodeType="sophora-content-nt:imageref" name="sophora-content:image">
                            <sophora:properties>
                                <sophora:property name="sophora:reference">
                                    <sophora:value>
                                        <xsl:value-of select="$externalIDImage" />
                                    </sophora:value>
                                </sophora:property>
                            </sophora:properties>
                            <sophora:childNodes />
                            <sophora:resourceList>
                                <xsl:apply-templates
                                    select="*[local-name() = 'image' and contains(namespace-uri(), 'metaplus')]">
                                    <xsl:sort
                                        select="*[local-name() = 'width' and contains(namespace-uri(), 'metaplus')]"
                                        order="descending" />
                                    <xsl:with-param name="externalIDImage" select="$externalIDImage" />
                                </xsl:apply-templates>
                            </sophora:resourceList>
                        </sophora:childNode>
                    </xsl:if>
                </sophora:childNodes>
                <sophora:resourceList />
 
                <!-- Set the special fields of the Sophora document -->
                <sophora:fields>
                    <!-- Set the site -->
                    <sophora:site>
                        <xsl:call-template name="getSiteFromStructureNodePath" />
                    </sophora:site>
                    <!-- Set the structure node -->
                    <sophora:structureNode>
                        <xsl:call-template name="getStructureNodeFromStructureNodePath" />
                    </sophora:structureNode>
                    <sophora:categories />
                    <!-- Set the ID stem -->
                    <sophora:idstem>
                        <xsl:if test="$idStem != ''">
                            <xsl:value-of select="$idStem" />
                        </xsl:if>
                    </sophora:idstem>
                    <sophora:forceLock>false</sophora:forceLock>
                    <sophora:forceCreate>false</sophora:forceCreate>
                    <sophora:enabledChannels />
                    <sophora:disabledChannels />
                </sophora:fields>
                <sophora:instructions>
                    <sophora:lifecycleActivities />
                    <sophora:proposals />
                </sophora:instructions>
            </sophora:document>
        </sophora:documents>
    </xsl:template>
 
    <xsl:template match="*[local-name() = 'image' and contains(namespace-uri(), 'metaplus')]">
        <xsl:param name="externalIDImage" />
        <xsl:if test="position() = 1">
            <!-- Create the Sophora document of the teaser image -->
            <sophora:document nodeType="sophora-extension-nt:image" externalID="{$externalIDImage}">
                <!-- Fill the documents properties with data of the feed item -->
                <sophora:properties>
                    <sophora:property name="sophora-extension:alttext">
                        <sophora:value>
                            <xsl:value-of select="*[local-name() = 'alt' and contains(namespace-uri(), 'metaplus')]" />
                        </sophora:value>
                    </sophora:property>
                    <sophora:property name="sophora-extension:caption">
                        <sophora:value>
                            <xsl:value-of select="*[local-name() = 'caption' and contains(namespace-uri(), 'metaplus')]" />
                        </sophora:value>
                    </sophora:property>
                </sophora:properties>
 
                <!-- Add the original image data -->
                <sophora:childNodes>
                    <sophora:childNode nodeType="sophora-extension-nt:imagedata" name="sophora-extension:imagedata">
                        <sophora:properties>
                            <sophora:property name="sophora-extension:binarydata" mimetype="image/jpeg">
                                <sophora:value>
                                    <xsl:value-of select="*[local-name() = 'data' and contains(namespace-uri(), 'metaplus')]" />
                                </sophora:value>
                            </sophora:property>
                            <sophora:property name="sophora-extension:imagetype">
                                <sophora:value>original</sophora:value>
                            </sophora:property>
                        </sophora:properties>
                        <sophora:childNodes />
                        <sophora:resourceList />
                    </sophora:childNode>
                </sophora:childNodes>
                <sophora:resourceList />
                <!-- Set the special fields of the Sophora document -->
                <sophora:fields>
                    <!-- Set the site -->
                    <sophora:site>
                        <xsl:call-template name="getSiteFromStructureNodePath" />
                    </sophora:site>
                    <!-- Set the structure node -->
                    <sophora:structureNode>
                        <xsl:call-template name="getStructureNodeFromStructureNodePath" />
                    </sophora:structureNode>
                    <sophora:categories />
                    <!-- Set the ID stem -->
                    <sophora:idstem>image</sophora:idstem>
                    <sophora:forceLock>false</sophora:forceLock>
                    <sophora:forceCreate>false</sophora:forceCreate>
                    <sophora:enabledChannels />
                    <sophora:disabledChannels />
                </sophora:fields>
                <sophora:instructions>
                    <sophora:lifecycleActivities />
                    <sophora:proposals />
                </sophora:instructions>
            </sophora:document>
        </xsl:if>
    </xsl:template>
 
    <!-- Returns the site from 'structureNodePath' -->
    <xsl:template name="getSiteFromStructureNodePath">
        <xsl:variable name="pathTemp" select="substring-after($structureNodePath, '/')" />
 
        <xsl:choose>
            <xsl:when test="contains($pathTemp, '/')">
                <xsl:value-of select="substring-before($pathTemp, '/')" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pathTemp" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
 
    <!-- Returns the structure node path without the site name from 'structureNodePath' -->
    <xsl:template name="getStructureNodeFromStructureNodePath">
        <xsl:variable name="pathTemp" select="substring-after($structureNodePath, '/')" />
 
        <xsl:choose>
            <xsl:when test="contains($pathTemp, '/')">
                <xsl:text>/</xsl:text>
                <xsl:value-of select="substring-after($pathTemp, '/')" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>/</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
 
</xsl:stylesheet>  <xsl:text>/</xsl:text>            </xsl:otherwise>        </xsl:choose>    </xsl:template> </xsl:stylesheet>

Caching

The downloaded feeds and transformed feed items are cached within the Feeds View. To configure the duration of caching the following parameter can be set in the configuration document, see Configuring the Deskclients.

ParameterDescriptionExample
feeds.cache.expirationTimeExpiration time of cached XML feeds in minutes. Set to 0 to disable caching. Default is 60 (1 hour).120