Getting Started With The Mura 7 Feed API

November 25, 2016

I’ve been doing a lot of work with the new Mura 7 Feed API lately and have found it very useful.  It’s an easy way to get a custom query (or Mura Iterator) of different groups of content in the site.  I’ve been using the Feed API to build various Display Objects in Mura — e.g. a list of the 3 most recent articles published.  On a particularly larger site, I’ve had to build a few reports for the Content Manager, so they can filter out duplicate content, old entries, content that’s missing some data, etc.  

These things used to mean writing custom SQL queries from scratch.  While I don’t mind writing SQL, I’d often forget some of the “boilerplate” that needs to be there for a Mura site.  For instance, filtering out records with the same ContentID (as I only need the records where “active=1” typically, and looking at the Display Date property), or remembering how to join the correct tables together so all the Extended Attributes can be queried.  The Mura 7 Feed API takes care of all of this automatically.  

The new syntax is pretty easy to start using.  If you’re in a Mura page (or Display Object, Component, etc), you start with getting a Feed to the “thing” in Mura you want to filter - Content, Categories, whatever:

<cfset myFeed = $.getFeed( "content" ) />

Or if you’re on a regular .CFM page that’s not part of a Mura site (the Content Manager reports I wrote were like this) you just need to get access to the Mura scope first, then get to the Feed, like so:

<cfset $ = application.serviceFactory.getBean( "muraScope" ).init( “[your site name]“ ) />
<cfset myFeed = $.getBean( "contentBean" ).getFeed( "content" ) />

From there you can use the Feed API to get whatever groups of Content you need. For example, to find every page in your site with the word “Technology” in the title:

<cfset qryTechArticles = $.getBean( "contentBean" ).getFeed( "content" ).where().prop( "title" ).contains( "technology" ).maxItems( 0 ).getQuery() />

Most of your custom filtering is done by stringing calls to .prop() together with some sort of “comparison” method. There are a few to pick from:

.contains()
.isEQ()
.isNEQ()
.isGT()
.isLT()

…and several others, you get the idea. You can find the whole list of these methods in /MuraCMS/requirements/mura/bean/beanFeed.cfc in Mura 7.

$.getBean() and .getFeed() are for getting access to the Feed itself. All of the filtering, querying, etc, begins with the .where() method and whatever comes after it. In this case we’re looking at the “Title” field of the Content to see if it contains the word “Technology”.  

The .maxItems( 0 ) call is to make sure we’re returning all the results. By default, the Feed API only returns 20 records; we set maxItem() to 0 to disable that.  And .getQuery() on the end just gives us the straight CFQuery result — you can also do getIterator() and get a Mura Iterator back if need be.

If you’re filtering on more than one Property, you can use the .andProp() method for the additional field(s).  Say we’re looking for Pages in our site with the word “Technology” in the title AND that were written by the author John Lennon. By default, author names are stored in the “credits” field.  So your report would look like so:

<cfset qryTechArticles = $.getBean( "contentBean" ).getFeed( "content" ).where().prop( "title" ).contains( "technology" ).andProp( “credits” ).isEQ( “John Lennon” ).maxItems( 0 ).getQuery() />

You can also sort the data using the .sort() method:

<cfset qryTechArticles = $.getBean( "contentBean" ).getFeed( "content" ).where().prop( "title" ).contains( "technology" ).andProp( “credits” ).isEQ( “John Lennon” ).maxItems( 0 ).sort( “Title” ).getQuery() />

For sites using the Mura Experience Platform add-on, you can also sort the articles by “relevance” for whichever user is logged in. This is useful for building those “Articles You May Also Like” sections:

<cfset qryOtherArticles = $.getBean( "contentBean" ).getFeed( "content" ).sort( "mxpRelevance" ).maxItems( 4 ).getQuery() />

In this example I’m not doing any filtering with .where(), I’m just sorting by “mxpRelevance” — that’s a reserved keyword (not an actual column in the tContent table) that activates the Mura Experience Platform add-on if it’s installed (note: this is not a free product, you’ll need to contact Mura for more details).  And then I’m just setting the maxItems() to only give me 4 results, assuming my “Articles You May Also Like” section only has space for 4 entries.

I’ll post some examples of other use cases shortly.

Enjoy.
nolan