Dependencies and Outbound Feeds Development
xmlbuilder2
The Xmlbuilder2 package converts objects to and from xml. This allows you to create the feed using a simple object and have it converted automatically to xml by the output-type. Be sure to use a version <= 2.1.7 or version >= 3.0.0 as other (2.4.x) versions are not compatible with OBF.
Create a Tag
To create a tag just add it to the object that is being built by the feed:
{ title: "Title Here", }
It will be converted to:
<title>Title Here</title>
Attributes
If you need to add attributes to a tag use an
@
in front of the tag name. If you need to include text with the tag use
#
:
{ link: { "@href": "http://www.example.com", "@type": "application/rss", "#": "tag text goes here" } }
It will be converted to:
<link href="http://www.example.com" type="application/rss">tag text goes here</link>
Multiple Tags Using a Key
You can use an object to group items. The previous example can be rewritten using an object like:
{ link: { "@": { href: "http://www.example.com", type: "application/rss" }, "#": "tag text goes here" } }
It will be converted to:
<link href="http://www.example.com" type="application/rss">tag text goes here</link>
This can be used anywhere you need to include duplicate tags. Imagine that you want to use a
<p>
to wrap each paragraph of an article. If you add two
p
keys to the same object the second one would overwrite the first.:
{ description: { "p": [ "The first sentence", "The second sentence", ] } }
It will be converted to:
<description><p>The first sentence</p><p>The second sentence</p></description>
CDATA
To wrap data in a CDATA tag use the
$
Note that the $
(CDATA) tag only works with strings, not an object. If you try to use an object in a $
it will generate <![CDATA[[object Object]]]>
. We can wrap a field it in CDATA like:
{ title: { "$": "<em>Breaking News</em>" }}
It will be converted to:
<title><![CDATA[<em>Breaking News</em>]]></title>
Index error
Using the xml output-type to convert the object to xml keeps the feature code clean. But it can make debugging harder. If the xml conversion fails it will generate an index error in the output-type and not in the feeds code. xmlbuilder2 will give an error if you try to convert a null. If you are getting an index error, add console.log’s to your feature code and run it locally to determine where the error is.
Jmespath
Jmespath is a language to query objects. Think of it as a more flexible version of lodash’s get. jmespath is used extensively with customFields where any valid jmespath expression can be used to find the data you want. It can also be used to modify the structure of the data. For example, we want to include keywords in a feed. Some clients want to use taxonomy.tags, which is an object. Others might want to use taxonomy.seo_keywords, which is an array. We could create a customField with two choices;
taxonomy.tags[].text
taxonomy.seo_keywords
Which ever value they select can be used by the same line of code:
const keywords = jmespath(storyANS, keywordCustomField) || []
This way regardless of which field is searched for, it will be returned as an array.
Moment
We use the https://momentjs.com/ package to format ANS datetime strings. ANS uses ISO-8601 to encode all datetimes using UTC
2020-09-08T00:22:54Z
All feeds output datetimes in UTC. To convert an ISO-8601 format to that used by RSS feeds (rfc-822) you can use:
javascript const rssDate = moment.utc(dateString).format('ddd, DD MMM YYYY HH:mm:ss ZZ')
Cheerio
The Cheerio package is used for HTML processing. It is used in the alexa feed to strip out html tags from the article body.
cheerio.load(rssBuildContent.parse(body)).text() // convert content_elements to text
In the utils/content-elements package it is used to search and replace links for <a>
and <img>
tags that are not fully qualified
He
The He Js package is used to decode html encodings in the utils/content-elements package. The content_elements
array is converted into html that goes into the <content:encoded>
tag. Since it can contain html, it must be in a CDATA tag. But xmlBuilder2 only allows a string to be used with CDATA. So the content-element package uses xmlBuilder2 to create a xml fragment then converts it to a string, then uses the he package to convert the html encoded tags <
and >
tags back to “<” and “>” expected by RSS consumers.