New in Kaliko CMS 1.0.0

With the beta-release of version 1.0.0 Kaliko CMS introduces versioning of pages among a few other new features and bug fixes.

New features

Page versioning

One of the major features in this new release is versioning of pages. This means that you can work on a new version of a page behind the scenes without affecting the currently published version and then publish the new one once it's ready. If you wish to go back to the content of a previous version you can also do that.

Each page can have one published version and one working copy at any time. Each version that have been previously published is stored as archived.

When editing a page you now are presented with three buttons on the bottom of the screen.

If you want to continue to work on your page before publishing Save working copy lets you do just that. Once you are pleased with the content you can go ahead and press Publish page.

If you want to see a list of all version of the page (and perhaps revert to an older version) you find them behind the Show versions button.

If you click Edit the editor will bring up a copy of the selected version. The system will never change an archived version, it will instead create a new version based of the old one.

Every time you enter the edit mode of a page it will try to bring up the latest working copy. If no working copy exist it will bring up the published version.

New Markdown property type

If you prefer writing your texts using Markdown instead of HTML you can now replace your HtmlProperty type with the all new MarkdownProperty.

[Property("Main body")]
public virtual MarkdownProperty MainBody { get; set; }

Option to manually set or change the URL segment

By default the URL segment for a page is determined by the system based on the page name when the page first is created. This works for most occasions, but sometimes you might want a shorter URL even though the page name is long. This can now be achieved by editing a page and under "Show advanced options" change the "URL segment" manually. If you leave it blank the system will use the page name in order to create it.

Option to set visibility in sitemaps when editing a page

The flag VisibleInSitemap found on the CMS page object can now be set in the editor (found under "Show advanced options").

Specify child sort order to pages

It's now possible to choose how pages should be sorted when listed. This affects both how they are presented in the page tree in edit mode, but also the order in which they are returned from PageFactory.GetChildrenForPage. This property - "Sort children by" - is found in the editor under "Show advanced options".

Available sort modes are; Created date, Page name, Sort index, Start publish date and Updated date.

Each pagetype can have a default child sort order that is inherited to pages created of that type. It's specified through the DefaultChildSortOrder and DefaultChildSortDirection properties of the PageType attribute.

An example would be a news list page where you always want to see the latest news first. This is accomplished through:

[PageType("NewsList", "News list", "~/Templates/Pages/NewsListPage.aspx", DefaultChildSortOrder = SortOrder.StartPublishDate, DefaultChildSortDirection = SortDirection.Descending)]
public class NewsListPage : CmsPage {

Drag-and-drop sort order in page tree

Child pages that are sorted by "Sort index" (as defined under "Show advanced options" on the parent) can now be reordered by drag and drop in the editor page tree.

This only affect children to parents with "Sort index", for any other setting the drop action will be undone.

The root is always set to sort it's children by "Sort index".

New page published event

Due to versioning a new event has been added called PagePublished (and as previous PageSaved available through the PageFactory class). PageSaved is called when a working copy is saved or prior to PagePublished when a page is published.

Function to fetch all pages based on a predicate filter

A new function has been added to do site wide selections based on a specified criteria:

// Gets all pages marked as visible in sitemap
var pages = PageFactory.GetPages(p => p.VisibleInSiteMap);

// Gets all news pages on the site
var newsPageType = PageType.GetPageType(typeof(NewsPageType));
var newsPages = PageFactory.GetPages(p => p.PageTypeId == newsPageType.PageTypeId);

Improved pagetype selector

The pagetype selector has been improved and can now show a thumbnail of the pagetype. The image should have the resolution of 80 x 60 pixels. To define a preview, set the PreviewImage property of the PageTypeAttribute:

[PageType("ArticlePage", "Article", "~/Templates/Pages/ArticlePage.aspx", PreviewImage = "/images/articlepreview80x60.png")]

Improved custom routing in MVC provider

Kaliko CMS supports direct calls to controller actions for pages, but sometimes there can be a need to handle the request somewhere else and then reroute it to the proper action. One such case is when using a page extender.

The new RouteUtils.RedirectToController function takes a page, an action name and a an optional set of parameters as arguments.

[PageType("SamplePage", "Sample page", "")]
public class SamplePage : CmsPage, IPageExtender {
    public bool HandleRequest(Guid pageId, string[] remainingSegments) {
        // Normally we would check the remaining segments and extract data,
        // but the main purpose for this example is the re-routing
        var page = PageFactory.GetPage(pageId);
        // Build the list of arguments to the action
        var arguments = new Dictionary<string, object> {{"query", "Hello world!"}};
        // Re-route to the controller action
        RouteUtils.RedirectToController(page, "custom", arguments);
        // Tell the system that we've handled the request
        return true;

public class SamplePageController : PageController<SamplePage> {

    public override ActionResult Index(SamplePage currentPage) {
        return View(currentPage);

    // Our  action that will be called from the page extender
    public ActionResult Custom(SamplePage currentPage, string query) {
        return Content(query);

Specify available pagetypes for each pagetype

Another new feature is the ability to specify which pagestypes that should be available when creating a new page under a particular pagetype. This can help the editors alot since it limits the choise down to the pagetypes that are intended for that particular section of the website.

To specify the available types, set the AllowedTypes property of the PageType attribute. If AllowedTypes isn't set all pagetypes will be available.

If - for instance - you have a news list pagetype that you only want news pages to appear under you can specify it like:

[PageType("NewsList", "News list", "~/Templates/Pages/NewsListPage.aspx", AllowedTypes = new [] { typeof(NewsPage) })]
public class NewsListPage : CmsPage {

Split startup code in pre and post CMS initialization

It's now possible to decide if startup code (implemented through IStartupSequence) will run before or after the standard CMS initialization. This is done by setting the StartupOrder property. Any value below zero will run prior to the system startup. This value also determine which order the startup will run.

An example of startup code that will run before the system initialize the database, content etc:

public class CustomStartup : IStartupSequence
    public void Startup() {
        // Do some magic

    public int StartupOrder {
        get { return -1; }


Support for application paths in page URLs

The system now supports to run under an application path other than the root.

Support for abstract (inehrited) MVC controllers

MVC controllers can now be inherited from abstract base classes.

Fixed property HTML output for Razor views

HtmlProperty among other property types generated encoded HTML when rendered in Razor views. They now have been fixed to output proper HtmlString results.

Fixed default log path to use the application data directory

The logger has been updated to use the application data directory (App_Data) as default when the system is installed. This is done by prefixing the path with |DataDirectory|. This will make deployment easier.

Fixed bug overwriting image preview in editor

Bug that sometimes replaced the correct preview image was fixed.

Defined log level for data context

In some development environments there was an excessive amount of log information from the data layer to the debug view. This has been limited to only errors.

Fixed assembly resolver for SQLite

This fix replaces the previous need to add an assembly binding for using SQLite, now it's solved by code instead.

Fixed bug in collection properties when including an apostrophe

Using an apostrophe within a collection property previously broke the save of the property values.

Cleaned up NuGet package removing bundle source files

Source files (such as LESS and already bundled scripts) have been removed from the NuGet-packages.


A big THANK YOU to Ed Chavez, yemoku, Barış Akpunar, Juan Aguiar, Alain Barbie and all others who have contributed to the project!

Related posts:


comments powered by Disqus