Making an OpenSearch-based Feed

The basic Atom feed mechanism described above works fine if the Atom feed returned by the src attribute is not too large. If the data set you want to provide access to is very large, however, then it will soon become impractical. Using an OpenSearch-based feed solves this problem. An example of this kind of feed is actually included with the Content Store: the Content Store web service includes a special section feed that provides information about all the sections to which the current user has access.

This feed is available at the following URL:

http://host-ip-address/webservice/escenic/section

If you follow this link at your installation you will be required to log in, and then get an empty feed like this returned:

<?xml version="1.0"?>
<feed>
  <author>
    <name>Escenic Content Engine</name>
  </author>
  <id>http://host-ip-address/webservice/escenic/section</id>
  <link rel="self"
        href="http://host-ip-address/webservice/escenic/section"
        type="application/atom+xml"/>
  <updated>2012-09-25T10:51:02.419Z</updated>
  <title type="text">Dummy Atom Feed</title>
  <link rel="search"
        href="http://host-ip-address/webservice/open-search/section-search-description.xml"
        type="application/opensearchdescription+xml"/>
</feed>

If you follow the (highlighted) search link, then an OpenSearch document like this is returned:

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
  <ShortName>Section Search</ShortName>
  <Description>Search for sections</Description>
  <Url type="application/atom+xml" template="http://host-ip-address/webservice/escenic/section/search/{searchTerms}"/>
  <LongName/>
  <Developer/>
  <Attribution/>
  <SyndicationRight/>
  <AdultContent>false</AdultContent>
  <OutputEncoding>UTF-8</OutputEncoding>
  <InputEncoding>UTF-8</InputEncoding>
</OpenSearchDescription>

The important part of this document is the highlighted URL template. You can search for sections by simply replacing the {searchTerms} placeholder with a search string and submitting the resulting URL. The results of the search are returned in an Atom feed that looks something like this:

<feed xmlns:ece="http://www.escenic.com/2007/content-engine" xmlns:dcterms="http://purl.org/dc/terms/" 
      xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom">
  <title>+(acl:"section\:4225" acl:"publication\:723") +(+a* +contenttype:com.escenic.section) -state:deleted</title>
  <author>
    <name>Escenic Content Engine</name>
  </author>
  <link rel="self" type="application/atom+xml" href="http://host-ip-address/webservice/escenic/section/search/a?pw=1&amp;c=2"/>
  <link rel="first" type="application/atom+xml" href="http://host-ip-address/webservice/escenic/section/search/a?pw=1&amp;c=2"/>
  <link rel="last" type="application/atom+xml" href="http://host-ip-address/webservice/escenic/section/search/a?pw=1&amp;c=2"/>
  <updated/>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
  <opensearch:totalResults>2</opensearch:totalResults>
  <opensearch:startIndex>0</opensearch:startIndex>
  <opensearch:itemsPerPage>2</opensearch:itemsPerPage>
  <opensearch:Query role="request" 
    searchTerms="+(acl:"section\:4225" acl:"publication\:723") +(+a* +contenttype:com.escenic.section) -state:deleted" startPage="0"/>
...
  <entry>
    <title>News</title>
    <link rel="edit" href="http://host-ip-address/webservice/escenic/section/3984"/>
    <link rel="self" href="http://host-ip-address/webservice/escenic/section/3984"/>
    <link href="http://host-ip-address/webservice/publication/dev.nightly/" rel="http://www.vizrt.com/types/relation/top" type="application/atom+xml; type=entry" title="dev.nightly"/>
    <id>urn:com.escenic.section:3984</id>
    <dcterms:created>2008-05-15T06:55:45Z</dcterms:created>
    <published>2012-02-02T13:16:43Z</published>
    <updated>2012-02-02T13:16:43Z</updated>
    <summary ui:align="right">tps / News</summary>
    <ece:state>published</ece:state>
    <ece:type>com.escenic.section</ece:type>
    <ece:home>
      <ece:uri>http://host-ip-address/webservice/content/com.escenic.section/</ece:uri>
      <ece:name/>
    </ece:home>
    <ece:last_edited_by/>
  </entry>
...
</feed>

You can define a collection field to use this service as follows:

<field name="sectionSearch" 
  type="collection" 
  src="escenic/section" 
  select="link"
  linkrel="self"
  mime-type="text/plain">
  <ui:label>Section</ui:label>
</field>

Note that the src attribute is set to just escenic/section: if you enter a relative URL here, then it is resolved relative to the URL of the Content Store web service.

When a content item containing this kind of collection field is opened in CUE, CUE follows the src attribute URL, and then follows the search link in the empty Atom feed in order to retrieve the OpenSearch document. As soon as the user starts to type in the sectionSearch field, CUE:

  1. Combines the typed character(s) with the search template.

  2. Submits the resulting search URL.

  3. Displays the titles from the returned Atom feed entries in a list below the field.

A new search is submitted each time a new character is entered in the field, giving the same "search as you type" behavior as with a simple Atom feed set up.

You can retrieve this field's value in your publication templates as follows:

${article.fields.sectionSearch.value.value.name}

Since ${article.fields.sectionSearch.value.value} in this case retrieves a complete section object, you can in fact substitute name in the above example with the name of any other section property you are interested in, for example:

${article.fields.sectionSearch.value.value.lastModified}