Portal Based APIs (JSON, XML, CSV, CAL)

Throughout my Kentico career and the dozens of sites I’ve built, one need seems to always come up: The ability to get information that is IN Kentico, out of Kentico. This takes the form of various things:

  1. API Feeds to fuel AJAX based requests on pages, making them functional without requiring page loading each time.
  2. External Partners requiring access to the data within Kentico
  3. Export of information into a file

All three of these have something in common. They get the data (source + ability to filter), and then format it for consumption. In this article, we're going to cover how to create your own API feeds within Kentico, managed through the Portal interface.

Why Portal API? Why not Coding?

Some may ask “Why would we create an API through the portal, instead of through a Web Service?” My opinion has always been, a CMS is there so you don't have to touch code to manage anything, only touch code to create needed functionality. So if you need a JSON feed of Dealers to run your AJAX based locator, and you create it in a Web Service, what happens when a new piece of information is added to your dealers that you now need in that JSON feed? You would have to go into your web service code, and add that new field, save, possibly push this to the live site, and if anything was in the App_Code folder, cause the site to recycle. What a pain!

But if the API was built and managed in the portal method, you would simply go to your Page Template, make your adjustments, and voila, done. No code, no pushing (except through Kentico's Staging Module), no hassle.

Tools Required

Webpart to API Converter – This tool is available through the Kentico marketplace, and was created by myself specifically for these purposes.

Optionally, JSON / XML / CAL Transformation Methods – These will be outlined in the article. While they are not required, they make generating the JSON, XML, and CAL feeds easier. Please see the article on how to add custom transformation methods to Kentico.

The Trinity of the API


The concept of how this all works is quite simple. We need 3 elements, the Source, the ability to Filter the Source, and the Display.

We use Kentico's existing tools (Repeaters, Repeaters with Custom Queries, etc) as the source of our information, we use Macros to get the Url Parameters to filter the sources (through Where Conditions, filters, etc), then we use Kentico's Transformation Engine to render the data into the display we want (JSON, XML, Cal, etc).

The last thing is the Webpart to API Converter takes that display and feeds only it back to the response with the proper content type.

Use the Source, Luke!

Puns aside, our first task is to get our Source of data.  Kentico has a plethora of tools to get data out of it's system (the source). Here are some common ones.

Repeaters / Hierarchy Repeaters

Repeaters are the bread and butter of Kentico. If whatever you are trying to export in your feed exists on the Content Tree (Pages), then this is most likely the tool you will be using to create your feed. Hierarchy Repeaters are a bit trickier to configure, but allow you to structure your data in a parent-child relationship (since both JSON and XML are capable of holding Parent-Child relationships).

Repeater with Custom Query / Universal Viewer with Custom Query

Since everything that exists in Kentico is stored in the database, you can essentially get any piece of data you want just by writing the correct Query. Using the Universal Viewer with Custom Query, you can even assign Parent-Child relationships and make Hierarchy Repeaters of Custom Query Data.

Filtering Repeaters

Repeaters can be filtered through a variety of means, but most of them consist of using Macros to get the filter parameters (from the URL), and then filtering the source through Where Conditions, Filters, and Fields.

Macro Syntax

First we should discuss the means of getting information.  Kentico's Macros allow you to have access to a wide variety of resources, but the primary one we'll be discussing is the QueryString.

Failed to load widget object.
The file '/CMSWebParts/Custom/HighlightJS/HighlightJS.ascx' does not exist.

Where Conditions

For simple filtering, sometimes adding Macros to the "WHERE" condition in your repeater is all that's needed.  Below is an example of how to get a Year parameter from the URL and get only Blog Posts for that year.

Failed to load widget object.
The file '/CMSWebParts/Custom/HighlightJS/HighlightJS.ascx' does not exist.

A couple notes on the above:

  1. I utilized the "Convert" methods to ensure that the value passed through the QueryString was of a certain type.  If i didn't, then someone could pass jibberish and cause a SQL error.
  2. I made the year optional, because if you did not pass a year at all then the query would still be true (since the last portion would resolve to 1900 = 1900 which is true).
Also should be noted, by default any Url Parameter passed into a WHERE condition automatically has it's single quotes escaped, this is to prevent SQL injection attachs.  This can be disabled, but then you must be very careful to properly escape the quotes yourself!

Custom Filters / Filter Web Partners

You can attach Custom Filters to your repeaters in order excercise more control over your API filtering. All Filter web parts in the end render a Where Condition that is appended to the repeater's query.  This does require touching code to create, but that's okay since it doesn't require touching code to maintain it once it's built.  You shoudl use Custom Filters if the filters you want to provide the API numerous and complex.

Custom Data Source Fields

If you need even more flexibility and you build a Custom Data Source (and attach a basic repeater to it).  The benefit of this is a Custom Data Source is pretty much a Source and Filter combined into one.  You can create and assign your own fields for you to pass URL Parameter macros to, and control how they alter your source.

These are also great if you need to incorporate other sources of data, such as from files or external services (things that Kentico doesn't have built in Data Sources for).

Final Notes and Resources

I hope this guide helps! Below are a handful of helpful Custom Transformations that you can add to the default Kentico Transformations (ASCX). Additionally if you are using Text/XML, you can create Custom Macro Methods using this logic.

Failed to load widget object.
The file '/CMSWebParts/Custom/HighlightJS/HighlightJS.ascx' does not exist.

Blog post currently doesn't have any comments.
Is three > than six? (true/false)