Hi, I'm Ray

I'm a software developer, full-time nerd and occasional human (while heavily caffeinated).

Using Episerver CMS as a makeshift API – Part 1, Get All Pages

At the end of last year (between Christmas and New Years), I had the task of auditing all the pages in an installation of Episerver. The problem was that the Service API wasn’t installed and the possibility of deploying code to the server was pretty slim. This got me thinking about the feasible solutions:

a) Always code

I could write code for Episerver, run it on a development instance using recent copy of the production database but I’d need a recent copy of the production database.

This could be done but required more moving-parts from other departments than I was willing to wait for.

It was, after all, the last two working days of the year. Also, I suspected the skeleton crew at work was an actual plastic skeleton that had a name-badge pinned to it.

b) I’m an idiot

I could crawl the website for all pages. I can’t guarantee that the crawler will find all the pages and definitely not the expired pages. Even if I could find all the pages, how would one reconcile the public pages to the ContentID or the PageType?

This was a stupid idea which I blamed on the dangerously low caffeine levels in my blood.

After a short coffee break, I started to think about the Episerver CMS. The web interface had everything I needed, a menu tree with all the pages (even the expired ones), the ContentID and ContentType. The site has fancy AJAX (or whatever) “async” loading and Dojo.

This started me off on a path about looking for REST requests and JSON responses.

c) Using the Episerver CMS website as a makeshift API.

I found that the back-end website effectively runs on REST and JSON (likely via the JS framework). Once I logged in, I could start making these requests manually.

Let’s be clear that these requests are no different than what the website is making on its own, I’m just going to be using the responses in some custom code.

I actually completed my task with only one type of request “action” but the idea got me thinking. I started writing a helper class so I could extend the functionality in the future, if I needed it.

In this example, I’m going to retrieve all the pages as if I were building the menu tree. As always, the code is linked at the end of the article.

 

0) Preparations

In preparation, I’m defining a structure for holding the menu items (pages) and setting up the helper class. I’m also using the demo Alloy Site for the endpoint.


using RyzStudio.Web.Episerver;

public struct ContentTreeItem
{
  public int Level { get; set; }
  public string Icon { get; set; }
  public ContentStructure Item { get; set; }
}

EpiserverCMS episerverCMS = new EpiserverCMS();
episerverCMS.BaseURL = @"http://localhost:5156";
episerverCMS.BaseURLCMS = @"http://localhost:5156";

 

1) Login


bool hasLoggedIn = episerverCMS.Login("Admin", "Password1234");
if (hasLoggedIn)
{
  string username = episerverCMS.GetProfile_Username();

  Console.WriteLine("Hello, " + username);
  Console.WriteLine("Episerver Version " + episerverCMS.Version);
}
else
{
  Console.WriteLine("Login Failed!");
}

 

2) Retrieve Page Menu Tree

I started intending to include the icon for each menu item but it became excessively more involved that I was prepared to go into for a quick code demo. If you’re interested it would involve pulling the CSS theme and matching the class definitions. The icons is a sprite.


List<ContentTreeItem> contentCollection = new List<ContentTreeItem>();

traversePageTree(ref contentCollection, 0, "1");

protected void traversePageTree(ref List<ContentTreeItem> contentCollection, int level, string pageID)
{
  List<ContentStructure> contentStructure = episerverCMS.GetContentStructure_GetPageChildren(pageID);
  foreach (ContentStructure item in contentStructure)
  {
    string icon = string.Empty;

/*    if (item.IsStartPage)
    {
      icon += "H";
    }

    icon = item.Properties.PageShortcutType.ToString();
*/

    contentCollection.Add(new ContentTreeItem
    {
      Level = level,
      Icon = icon,
      Item = item
    });

    if (item.HasChildren)
    {
      traversePageTree(ref contentCollection, (level + 1), item.ContentLink);
    }
  }
}

 

3) Show

Here is an idea on what’s inside the ContentStructure. There is a lot more, go nuts.


foreach (ContentTreeItem item in contentCollection)
{
  Console.WriteLine("Level = " + item.Level.ToString());
  Console.WriteLine("Icon = " + item.Icon);
  Console.WriteLine("Name = " + item.Item.Name);
  Console.WriteLine("ContentTypeName = " + item.Item.ContentTypeName);
  Console.WriteLine("PublicURL = " + item.Item.PublicURL);
  Console.WriteLine(string.Empty);
}

 

4) The Code

I really hope someone finds this interesting or useful.

Available Code Repository (GitLab)

The Author

Ray
  • Hi, I'm Ray. I'm a software developer, full-time nerd and occasional human (while heavily caffeinated).

Copyright © 2014-2019 Ray Lam. All Rights Reserved.