Build your own CMS – Iteration 1: the CMSification of the client website

February 5, 2011

This is the fifth post in a series documenting my development and implementation of a content management system (CMS) built on the ASP.NET MVC Platform.

In my previous post, Iteration 1: Data Model, Templates, Content Creation, I gave an overview of how the CMS worked from a data and architecture-centric perspective. This post will pick up where the previous left off, showing you how a client website gets built on this platform.

GlobalBeers.com – now completely content-managed

GlobalBeers is my fictitious client – an online beer retailer with a previously static website. I discussed them and their website in a previous post, Build your own CMS - an overview.

image

All of the site’s old pages have been deleted, and replaced by CMS content pages. To convert the site, I took the following steps:

  1. Create Templates
  2. Create View pages (one for each template)
  3. Create pages in CMS Administration site
  4. Delete all the old static pages

Creating the templates

I started with the individual product pages, so I created a “Product” template, Product.xml, and a master template, PageMaster.xml, which I intend for the product template and others to include. I discussed how this works in my previous post. This is the product template:

<?xml version="1.0" encoding="utf-8" ?>
<template name="Product">
    <contentItems>
        <include template="_Includes\PageMaster.xml" />
        <content id="Title" type="text" isHtml="false"></content>
        <content id="Body" type="textarea" isHtml="true"></content>
        <content id="PrimaryImageUrl" type="text" isHtml="false"></content>
    </contentItems>
</template>

I also created a similar “Default” template, because I realized for now I could get away with using the same template for all of my other pages. It’s identical to the product template, minus the PrimaryImageUrl content element.

Creating the View pages

I created a View page, Product.aspx, for the product pages. It sits in the same master page from the original site and is laid out the exact same way. The only difference is that it inherits a view page of type CmsPageViewModelBase and all CMS content items are rendered via blocks like <%=Html.ContentItem(Model, "Title") %>

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<GlobalBeers.Cms.Web.ViewModels.CmsPageViewModelBase>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    <%=Html.ContentItem(Model, "PageTitle") %>
</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="HeaderContent" runat="server">
    <meta name="keywords" content="<%=Html.ContentItem(Model, "MetaKeywords")%>" />
    <meta name="description" content="<%=Html.ContentItem(Model, "MetaDescription")%>" />    
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2><%=Html.ContentItem(Model, "Title") %></h2>

    <div>
        <img style="float:right; width:150px;" src="<%=Html.ContentItem(Model, "PrimaryImageUrl") %>" />
        
        <%=Html.ContentItem(Model, "Body") %>

        <br /><br />
        
        Quantity: <input type="text" value="1" style="width:20px;" />
        <input type="button" value="Add to cart" />
        
        <div style="clear:both;"></div>
    </div>
</asp:Content>

A Default.aspx page was also created and it is very similar.

Creating the CMS content pages

I went into the CMS Admin site and began creating pages and filling them with content – copying and pasting the content from the original non-CMS website.

 Creating a CMS Page - 1 Creating a CMS Page - 2

Creating a CMS Page - 3

I did the same for all products, the product type pages, the products page, the about page, the contact page and the home page. That leaves me with all 12 pages, all CMS-driven.

CMS Pages

The completed site

The GlobalBeers website is now delightfully simple. Only the 3 highlighted CMS view pages are specific to the CMS implementation. There aren’t even any Controllers (the CMS controller is lives in the GlobalBeers.Cms namespace). Everything else you see here is the same as it was – the code, content, scripts, etc. is just what’s necessary to support the original, CMS-agnostic infrastructure and functionality of the site.

GlobalBeers.WebUI project

But what about the templates?

Okay, you got me. For now, the templates actually live in the GlobalBeers.Cms project. This is part ease, part necessity. Both the GlobalBeers.WebUI (the globalbeers.com website) and the GlobalBeers.Cms.WebUI (the CMS admin site) projects need access to the templates. It would be natural to place them in the GlobalBeers.WebUI project, but then how does the CMS admin site know about them? These web applications are decoupled by design.

GlobalBeers.Cms project

The obvious answer is to put them in a shared resource, such as a database, but then I’d lose all the flexibility of editing template files right through Visual Studio. I’m still contemplating the ideal solution. For now the templates live in the shared project, GlobalBeers.Cms – the heart of the CMS code that both web apps reference.

Conclusion

That’s iteration 1. I’ve built the core CMS architecture and fully converted the fictitious globalbeers.com website to be CMS-driven.

Of course, there’s a long way to go. A few outstanding issues and missing features off the top of my head:

  1. Localization – I have this in the bag, but I’m waiting for the architecture to firm up before implementing. To do.
  2. 90% of a CMS page is one giant HTML blob (the body content item). This is unsustainable.
    1. Content editors aren’t likely to be proficient with HTML, so I’ll need to provide some sort of rich-text editor if I realistically expect editors to produce HTML content. (this could also be a nightmare)
    2. Pages need to be broken up into more granular parts. The Product pages, for instance, list some attributes of the beers. This might best be refactored into individual content items or some sort of content item “list”.
  3. The Menu needs to be CMS-driven.
  4. Need to demonstrate a manual-layout of a CMS content page editing interface as opposed to the dynamically generated ones.
  5. Need to organize content pages in some sort of logical format and allow them to be moved .

I’ll be tackling this and more in future posts.

blog comments powered by Disqus

About Kurt

I'm a senior consultant at Headspring in Austin, TX. My passion is creating web-based applications that are well crafted and solve real problems for real people. Want to know more? Check out my about page.