Showing posts with label CMS. Show all posts
Showing posts with label CMS. Show all posts

Wednesday, January 11, 2012

Designing a Generic Meta-Data Driven Transformation Template (Ektron Designing Content Delivery: Part 3)

In the previous Ektron Designing Content Delivery post (Designing Data Templates for Content Extraction with Ektron (JSon, XML) (Ektron Designing Content Delivery: Part 2)), I outlined the basics of creating a series of templates for data extraction.

While using Ektron content as data is useful (in particular SmartForm data), there is always a need to render transformed content (as Html, Text, Csv, or other formatted content). In this post, I will outline a method to create a simple Meta-Data driven Ektron template that can use used to transform your data for presentation.

What this is useful for:
  • SmartForm content that needs to be displayed as Html
  • SmartForm content that needs to be transformed (to other Xml, Html, Text, Csv, etc)
  • Any Ektron content that requires transformation before being rendered, and represents stand-alone content.
A high level overview of the rendering process:


Of note: I've also created an Ektron Widget control that follows the same pattern, so that I can render out this content as part of a page-builder page without any additional work by the end user. It pretty much works the same way with the template being a page-builder widget, and the end consumption being a Page-builder page.

Transformation Template:
System/Design Requirements:
1. Support Multiple Xsl/Xslt translations against the content set
2. When not configured properly then display a simple message back for the rendered content.
3. Support different separators/delimiters within the metadata in-case there is a conflict and it needs to be changed or updated.

ASPX:
       
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MetaDataTransformation.aspx.cs" Inherits="ContentManagement.Site.Shared.Template.Content.SmartForm.MetaDataTransformation" %>
<%@ Register Assembly="Ektron.Cms.Controls" Namespace="Ektron.Cms.Controls" TagPrefix="CMS" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <CMS:ContentBlock ID="ContentBlock1" runat="server" />
    </div>
    </form>
</body>
</html>
       
 

Code-Behind:
using System;
using ContentManagement.Ektron.Content;
using ContentManagement.Ektron.Transformation.Xsl;
using ContentManagement.Site.Shared.Pages;
using MetaData = Ektron.Cms.API.Metadata;
using ContentManagement.Ektron.Transformation;

namespace ContentManagement.Site.Shared.Template.Content.SmartForm
{
    public partial class MetaDataTransformation : AbstractCmsPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.ContentBlock1.SetDynamicParameterToIdAndFill(); //prep content block

            Response.Clear();

            WriteCmsDataToHeader(Response);
            Response.ContentType = ContentManagement.Web.ContentTypeDefinition.Html;

            var id = this.ContentBlock1.EkItem.Id; //retrieve the id from the item

var metaData = this.ContentBlock1.GetMetaData().GetItemByName("Transformation"); //Note: This should be content/error content from Ektron. Action badRender = () => Response.Write("Oppps. It looks like this content isn't ready yet. Try back again soon."); if (metaData == null) //meta data not located on this item, so we do not want it to render. badRender(); else { var data = new MetaData(); var metaDataType = data.GetMetadataType(long.Parse(metaData.ID)); var xsltTransformationFromMetaData = this.ContentBlock1.GetMetaData().GetItemByName("Transformation").Value.ToString().Split(new string[1] { metaDataType.Separater }, StringSplitOptions.RemoveEmptyEntries); var transform = XslTransformFactory.Get(); var input = this.ContentBlock1.EkItem.Html; if (xsltTransformationFromMetaData.Length <= 0) //no content, write out a simple error message. badRender(); else if (xsltTransformationFromMetaData.Length == 1) { //apply single transformation, and output directly to response stream transform.Transform( new XmlStringInput(input) , new XslFileInput(TransformationPath.MapPathAndValidate(this, xsltTransformationFromMetaData[0])) , Response.OutputStream , Response.Output.Encoding); } else { //apply multiple translations xsltTransformationFromMetaData.ForEach(trns => input = transform.Transform(new XmlStringInput(input), new XslFileInput(TransformationPath.MapPathAndValidate(this, trns)))); } } Response.End(); } } }


The steps for setup and configuration are pretty simple:
Ektron Configuration
  • Creation of the Meta-Data within Ektron
  • Sample Metadata Transformation within Ektron 8.0.2
  • Apply the Metadata to the Content Folder(s)
  • Metadata applied to the content folder
  • Add Meta-Data Driven Transformation Template to your content
Content Configuration
  • Add the MetaData to the Content
  • Meta Data Transformation on Content (Note: This has two transformations)
  • Set the Template for the Content to the Transformation Template
  • Add the correct meta data transformation template.


Notes
If your planning on using this with any type of volume you will want to cache the output of the transformation.

It's important to note that I am not referring to adding a custom style sheet to an Ektron web control (which you can do, and is extremely flexible) in particular this template will retrieve Ektron content, apply transformations and then write the result of the transformation to the response output. The application (and usage) of this for consumption of Ektron content is quite different. If your developing pages within Ektron, and want to transform the output of the control, using Ektron's own transformation infrastructure is a much better option. Here, I am transforming, and then providing content via a push/pull to other sites for content presentation (and providing an option to present that content fully rendered).

Q & A
Q: How is this different than adding a Cms control to the page and selecting a transformation? 
A: At the end of the day, it's not all that different, but I wanted a way to make this process completely configuration driven so I can set up additional content at will without having to create a page or a template for each set of content. 

In my next posts
1. Designing a wrapper-API for consumption, caching and rendering of Ektron data.
2. Now look what we can do: Render Ektron client-side with data templates and JsRender (for smoking fast response times).
3. My Ektron page templates

Resources:
Designing an Ektron Content Delivery and Provider Mechanism (Part 1)
Designing Data Templates for Content Extraction with Ektron (JSon, XML) (Ektron Designing Content Delivery: Part 2)
Guest Blogger-Cameron Jordan: No More XSLT?!

Thursday, January 5, 2012

Designing an Ektron Content Delivery and Provider Mechanism (Part 1)

As your designing your Ekron Content Management System (CMS) you need to design the level of interaction your enterprise will have with the CMS.

From the design of Ektron you can see it prefers to be the center of your offering. Most of the controls, pages, API and other components are geared towards building a site. In that regard, it seems to be competent.

For the project I am currently working on, the idea is something very different. It's to use Ektron for management of the content, with the idea of pushing (or pulling) content from this system to be consumed by a host of other sites (and potentially applications).

In some regards, Ektron is not designed to do this type of work. The out-of-the-box offering for exporting content supports PDF, and a synronization utility integrated with the product called ESync is designed to move content through the environments, and for content generation. Their marketing literature describes ESync as: "Automate the secure provisioning of web content, code, assets, and templates from development through production. Deploy only the necessary changes, from a single content update to an entire site, speeding time to Web and eliminating site downtime.".

Based upon Ektron's functionality and the desire to use it as a content repository there is a need to:
1. Design a way to generic render XML (SmartForm) content into Html, Text, Csv
2. Design a way to extract content information (SmartForm) into Xml, JSon
3. Design a way to extract html (or Ektron rendered content) in it's native format
4. Develop an Intermediate/Proxy API capable of extracting content on demand, providing caching of that content at the destination, and providing the content when requested.
5.

These deliverables combined with Ektron as a system itself (including the best practices documentation) generated these additional constraints or parameters:
1. The content delivery and provider mechanism should not interact directly with Ektron's data-storage.
2. The system should rely heavily on using the Ektron website for content extraction, and avoid direct interaction with the database, or Ektron APIs where possible.
3. The delivery mechanism should be extremely flexible and should scale with demand.
4. Any development should wrap Ektron, and not involve changing the core application or product.
5. The strategy support upgrading Ektron at any time.

In order to achieve the deliverables and system requirements, I designed a series of extraction templates (to be included within the Ektron site), and an API for use by these templates, and for extraction of the content (in it's various forms).

This is the high-level design:

Each of the sites consuming the content access Ektron's information via the API, and then store the content within one of the caching mechanisms (file/IO, HttpContext caching, RavenDB) and retrieve any missing content on demand.

Since the API capable of retrieving, caching and filtering content it supports on-demand requests, pull-requests from sites. The next goal is to add content-push from Ektron into the caching mechanisms (proactively staging updated content for the sites to consume).

In my next post:
1. Designing Data Templates for Content Extraction with Ektron (JSon, XML)
2. Designing a Generic Meta-Data Driven Transformation Template with Ekron

References:
Ektron
ESync