Month: July 2012

Aliased custom 404 error page

This article describes how to create a custom 404 error page in Ektron CMS that will return a HTTP status code 404, use a friendly aliased URL and give content authors the ability to change the content within the page.

Create the template

Create a new ASPX Web Form template called Error404.aspx (or something similar).  Add a ContentBlock to the HTML source view and set the DynamicParameter property to “id”.

Add the template to the CMS in the Settings > Configuration > Template Configuration section in the Ektron workarea.

Now create a new content item in the CMS and assign it to the Error404.aspx template that you created earlier.  Assign an alias to the content item, something like “/page-not-found/”.

Test the page loads of by browsing directly to /page-not-found/.

HTTP status code 404

Now you need to tell the template to return the correct HTTP status code.  At present it is returning a status code of 200 which means “success”.  This will cause search engines to incorrectly believe that your 404 page is actually valid content – in other words, it will be indexed and returned in Google’s results!

To prevent this, go to the code-behind file (this is in C# of course):

    protected void Page_PreRender(object sender, EventArgs e)
    {
        Response.TrySkipIisCustomErrors = true;
        Response.Status = "404 Not Found";
        Response.StatusCode = 404; 
    }

What this does is set the HTTP status code to be 404.  This will indicate to search engines that they have found a missing page so they will not index it.

You can test your page by browsing to an invalid page and seeing if the custom error page is returned.

Enable custom error handling

The next step is to tell .Net that we want to use a custom error page.  This is done within the web.config file like so :

    <system.web>      
      <customErrors mode="On">
          <error statusCode="404" redirect="/page-not-found/" />
      </customErrors>
    <system.web>

This tells .Net to send any “404 page not found” errors to an alias called “/page-not-found/”.

Problems with invalid aliases

You may find that your custom 404 error page isn’t being activated if you try to browse to an invalid alias.  What I have found is that you instead get a nasty server 500 error instead:

Server Error in Application “###”

Internet Information Services 7.5

Error Summary

HTTP Error 500.0 – Internal Server Error

Internal Server Error

Detailed Error Information

Module ManagedPipelineHandler
Notification ExecuteRequestHandler
Handler ExtensionlessUrlHandler-Integrated-4.0
Error Code 0x800703e9
Requested URL http://###:80/wibble/
Physical Path C:\inetpub\wwwroot\###\wibble\
Logon Method Forms
Logon User ###

Eeek!  Where is my custom error page?!?!

I discovered that the problem was due to an incorrect setting in my web.config file.  I needed to remove a handler called “ExtensionlessUrlHandler-Integrated-4.0”, like so :

<system.webServer>
    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    </handers> 
</system.webServer>

(Please note I am using IIS 7)

By removing this HTTP handler it allows the request to be passed through to your custom 404 error page instead.

URL Redirects with Ektron 8.6

One of the new features of Ektron version 8.6 is to allow CMS administrators to define URL redirects from within the CMS itself.  Prior to 8.6 this could only be done by setting up redirects in IIS – this made it more of an IT/Server administrator role instead.

To access the new feature follow these steps :

  1. Open the workarea and browse to the Settings > Configuration > URL Aliasing section.
  2. Click Settings.
  3. Click Edit.
  4. Tick the checkbox labelled “Enable URL Redirects”.
  5. A new option will now appear in the URL Aliasing folder called “Redirects”.
  6. Click Redirects.
  7. Click  the “Add Redirect” button.
  8. You have the following options:
  • Choose which website the redirect is applied to.
  • Choose the redirect code.  This is an important SEO (Search Engine Optimisation) factor.  The “301 Permanent Redirect” is often used when moving content to a new website; it is used to tell search engines that a page which used to live in one place has now moved permanently to another.  The idea is that search engines won’t visit the old URL again and will instead visit the new one.
  • You may also set the new and original URLs.

Setting up redirects is a useful tool in preventing users and search engines from hitting dead links on your site.  Typically these dead links are introduced when you move to a new website or to a new CMS.

 

Add a PageBuilder page using the Ektron API

Pagebuilder pages are an Ektron feature that allow content authors to create flexible web pages by dragging and dropping widgets onto the page.  A widget is a module that can be added to a web page which provides a specific purpose such as an image, video, form or a block of HTML text.

There might be instances in which, during the course of a project, it becomes necessary to add pages into the CMS en masse, for instance, during a content migration excercise.

The following block of code below will allow you to create a Pagebuilder page and add a widget into it.

EDIT: Updated as original code sample wasn’t verbose enough
The code adds an Ektron ContentBlock control to the page.

long folderId = 86; // where to add the page to
var tmpPageData = new PageData(); // temporary object for page config

string controlUrl = "ContentBlock.ascx"; // name of the widget user control in widgets folder
string dropZoneId = "Middle"; // id of the DropZone control on the wireframe

var widget = new WidgetData
{
ControlURL = controlUrl,
ColumnID = 0,
Order = 0,
Minimized = false,
DropID = dropZoneId,
Settings = String.Format("{0}", 30);
};

tmpPageData.Widgets = new List(); // initialise widgetdata list on page
tmpPageData.Widgets.Add(widget); // add ContentBlock widget to page

// Create a drop zone data object
var dropZoneMain = new DropZoneData {DropZoneID = "Middle", Columns = new List()};

// Create a column data object
var columnDataMain = new ColumnData {columnID = 0, width = 100, unit = Units.percent};

// Add the column to the drop zone
dropZoneMain.Columns.Add(columnDataMain);

// Add the drop zone to the page
tmpPageData.Zones = new List {dropZoneMain};
tmpPageData.IsMasterLayout = false;

// Call a method to add the page (see method below)
AddPage(gameToPush.Title, gameToPush.Alias, folderId, 2, tmpPageData, 2057);

So the process above is add widgets to the PageData.Widgets property then add the Drop Zones to the PageData.Zones property (which also includes Columns).

The above code depends upon a method called “AddPage()” which is given below:

private void AddPage(string pageTitle, string alias, long folderId, long wireFrameId,
Ektron.Cms.PageBuilder.PageData pageData, int langId = 2057,
ContentMetaData[] metaData = null)
{

    var pageManager = new PageModel();
    var contentManagerOld = new Ektron.Cms.API.Content.Content();
    pageManager.RequestInformation = contentManagerOld.RequestInformationRef;

    var tmpPageData = new PageData();

    // First create the page entity in the CMS
    pageManager.Create(pageTitle, folderId, alias, langId, wireFrameId, String.Empty, "summary", out tmpPageData, true);

    // Assign widgets and drop zones
    tmpPageData.Widgets = pageData.Widgets;
    tmpPageData.Zones = pageData.Zones;

    // Save to the CMS
    pageManager.CheckIn(tmpPageData);
    pageManager.Publish(tmpPageData);

    // Assign metadata
    if (tmpPageData.pageID > 0)
    {
        if (metaData != null)
        {
            if (metaData.Length > 0)
            {
                contentManagerOld.ContentLanguage = langId;

                foreach (ContentMetaData meta in metaData)
                {
                    contentManagerOld.UpdateContentMetaData(tmpPageData.pageID, meta.Id, meta.Text);
                }
            }
        }
    }
}

At first glance this seems a bit counter-intuitive.  The addition of widgets and drop zones to the page is done separately, whereas you may have thought that widgets go into columns which go into zones which go pages.  In fact the widgets and zones are accessed through different properties as you can see above.