How toDeveloper Guide

Developer Guide

Sana Commerce 8.2
Your provider

Create a Custom Content Type

In this chapter you can read how to:

  • create a new content template;
  • make the created content template editable in the backoffice;
  • show the created content template in the frontend;
  • make the new page template linkable in the link manager;
  • enable the preview functionality for the created content template;
  • show the created content page on the Starter Site.

Follow the steps below to create a content template (for example 'Articles').

 Set Up the Data Model for the New Template

You should set up the data model for the new content template in order to store the content type in the database. To do this, follow these steps:

Step 1: Create a table in the database (for example 'Articles'). It will contain the next columns:

Column Required Type Description
Id Yes uniqueidentifier The unique identifier of the content item. (Primary Key)
Title No nvarchar(50) The title of the content item.
Description No ntext The description of the content item.
CreatedDate Yes Datetime The date when the content item was created.
ModifiedDate Yes Datetime The last modification date of the content item.
GroupCode Yes nvarchar(50) The group code is used to group the multiple content pages that have multiple languages using a code.

The required columns are used for the channels system. For more information about the channels system please read the 'Selecting Channels' paragraph in the 'Content Pages' chapter.


Creating the 'Articles' Table in the Database

Step 2: Create an interface with the 'IArticle' name and add it to the Sana.Commerce.DomainModel project. Add the properties needed for this interface to match the database table:

public interface IArticle : IChannelItem, IIdentityObject, IVersionedItem, IInternalPage
{
        string Title { get; set; }
        string Description { get; set; }
}

Step 3: Add the 'Article' class to 'Sana.Commerce.Content' namespace of the 'Sana.Commerce.DomainModel' project. Inherit this class from the 'ChannelItemBase' class and 'IArticle' interface:

public class Article : ChannelItemBase, IArticle
{
public string Title { get; set; }
     public string Description { get; set; }
}

Step 4: Add NHibbernate mapping to 'Content.hbm.xml' in the 'Content' folder of the 'Sana.Commerce.DomainModel' project: 

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" namespace="Sana.Commerce.Content" assembly="Sana.Commerce.DomainModel">

<class name="Article" table="Articles">
    <id name="Id" type="Guid">
      <generator class="guid"/>
    </id>
    <property name="Title" type="string" length="50" not-null="true" />
    <property name="Description" type="string" length="2000" not-null="true" />
    <property name="CreatedDate" type="System.DateTime" not-null="true" />
    <property name="ModifiedDate" type="System.DateTime" not-null="true" />
    <property name="GroupCode" type="string" length="50" not-null="true" />
  </class>
</hibernate-mapping>



 Make the Page Template Editable in the Backoffice

This step will allow you to make the content template editable in the backoffice. To do this, follow these steps:

Step 1: Locate the 'DataModel\Metadata' folder in the Sana.Commerce.Backoffice project.

Step 2: In this folder create the 'Article_Metadata' class inherited from 'ChannelItemBase_Metadata':

[DisplayName("Article")]
[DisplayNamePlural("Articles")]
public class Article_Metadata : ChannelItemBase_Metadata
{
    [UIFilter(UIFilterType.Contains, 0)]
    [DisplayName("Title")]
    [UserDisplayMode(1)]
    public object Title { get; set; }
    [DisplayName("Description")]
    [UserDisplayMode(UserDisplayModes.All &  ~UserDisplayModes.List, 2)]
[HtmlContentRequired, Required]
    [UIHint("Html")]
    public object Description  { get; set; }
}

The used attributes in the metadata class are described below:

Attributes Description
DisplayName The title of the content type or its data fields in the content page overview of the backoffice
DisplayNamePlural The title of the content type in the content pages list of the backoffice
UIFilter This attribute is used to filter the content pages by the data field to which this attribute is applied (for example 'Title')
UserDisplayMode This attribute is used to determine on which pages and in which order the data fields of the content type should be shown in the backoffice
UIHint Specifies the template or user-defined control which Dynamic Data must use to show a data field in the backoffice

Step 3: Register the 'Article' class in the 'RegisterTypes()' method of the 'WebApplication' class in the Sana.Commerce.Sdk project:

ObjectManager.RegisterType<IArticle, Article>();

Step 4: Register the 'Article_Metadata' class in the 'RegisterMetadata()' method of the backoffice 'Global.asax' file:

MetadataTypeFactory.Register<IArticle, Article_Metadata>();

Step 5: To add the link to the 'Articles' module item the 'web.sitemap' file, which is in the root of the Sana.Commerce.Backoffice project, must be modified.

For example if you want to add 'Articles' module item to the 'Content' module in the backoffice insert the XML given below into the 'Content' section  of the 'web.sitemap' file (the 'siteMapNode' with a specific URL "~/Landing.aspx?section=Content"):

<siteMapNode url="~/Content/Articles/List.aspx" title="Articles" image="Img/open.gif" isNavigationItem="true">
         <siteMapNode url="~/Content/Articles/Edit.aspx" title="Edit article" showinnavigation="false" />
         <siteMapNode url="~/Content/Articles/Insert.aspx" title="New article" image="Img/new.gif" />
</siteMapNode>

After you complete these steps a new menu item 'Articles' will be added to the 'Content' module.
In case of a multi-shop solution the new articles with a specific localization can be created by setting the channels at the bottom of the page.


Creating New Article with English Localization

 Create the ASP.NET Page Template in the Frontend

This step will allow you to show the content template in the frontend. To do this, follow these steps:

Step 1: Create the '.aspx' template. Open the 'Sana.Commerce.Startersite' project. Add the new page template to the 'Content' folder (for example 'article.aspx'). The page class must be inherited from the StarterSitePage class.

Step 2: Retrieve the data from the database.

Retrieve the content item data from the database (for example 'Article'):
To retrieve an article by the group code you can use the 'GetChannelItem' method of the Content Manager.  This method will return article by the group code for current webshop using current language:
CommerceFramework.Content.GetChannelItem<IArticle>("GroupCode");
To retrieve a list of articles you can use the 'GetChannelItems' method of the Content Manager.  This method will return all articles for current webshop using current language.
CommerceFramework.Content.GetChannelItems<IArticle>();

Use the following code to retrieve the data item from the database in order to show it on the page:

IArticle article = CommerceFramework.Content.GetChannelItem<IArticle>(GetParamFromRequest("id"));
For example if you have labels with the 'Title' and 'Description' ids on the template you can use the following code to fill it with data:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
      {
var article = CommerceFramework.Content.GetChannelItem<IArticle>(GetParamFromRequest("id"));
            Title.Text = article.Title;
            Description.Text = article.Description;
}
}

Now the step is completed and you can see the created content template on the frontend.


 Enable URL Rewriting for SEO

This step will allow you to create a search engine friendly URL for the content item. It will increase the presence of the created content item in the index of the search engine.

To do this create a route record for the new template in the 'Routes' table in the database:

In the table below the description of the columns to which the values should be set and the example of the created record are given:

Column name Description Value Remarks
Id The route identifier. Article  
Name The route name. Article  
RewrittenUrl The pattern for the virtual URL. articles/{id}/{title}.aspx The 'id' route parameter which defines the id of the record is used.
You can use this route parameter to get the record id from the URL by the following method: StarterSitePage.GetParamFromRequest("id")

The RewrittenUrl must be with the '.aspx' extension.

PhysicalUrl The path to the physical resource on the server, to which the virtual URL is mapped. ~/content/article.aspx The path to the created page template.
Type The type of the link provider associated with the route. The link provider with the corresponding type will use current route to build the URL. Article The type which will be used in the link provider for the articles.
IsLinkable The value should be set to 'True' if the link can be created for current route. true  
OrderNo The order number of the route. All routes will be registered in the order which is defined by the 'OrderNo' field. 100  

Now the step is completed and the search engine friendly URL is created for the content item.


 Enable the Preview Functionality

This step will allow you to use the preview functionality for the new content type. After performing this step you will be able to see how the content item is going to look even before saving it. To do this, follow these steps:

Step 1: Inherit the 'article' page class from the 'ChannelItemPreviewPage<IArticle>' class in 'article.aspx.cs'. The 'GetGroupCodeRouteParam' abstract method must be implemented. This method will return the route parameter which defines the record id. The method can be implemented this way:

protected override string GetGroupCodeRouteParam()
{
    return "id";
}
The 'GetChannelItem' method from the 'ChannelItemPreviewPage<Article>' class must be used in the page template to get the data item. Otherwise the template will work incorrectly in the preview mode.

Step 2: Add the 'Previewable' attribute for the metadata type which is defined for the article type. The route id must be passed as a parameter. The route defined in the 'Previewable' attribute is used to build the preview URL. For each property of the 'Article' class, which must be accessible in the preview mode, the 'PreviewRequired' attribute for the corresponding property in the metadata type must be added.

The example of the metadata type defined for the 'Article' class:

[DisplayName("Article")]
[DisplayNamePlural("Articles")]
[Previewable("Article")]
public class Article_Metadata : ChannelItemBase_Metadata
{
    [UIFilter(UIFilterType.Contains, 0)]
    [DisplayName("Title")]
    [UserDisplayMode(1)]
    [PreviewRequired]
    public object Title { get; set; }
    [UserDisplayMode(UserDisplayModes.All & ~UserDisplayModes.List, 2)]
    [DisplayName("Description")]
    [UIHint("Html")]
    [HtmlContentRequired, Required]
    [PreviewRequired]
    public object Description { get; set; }
}

Now the step is completed and you can use the preview functionality for the new content type.


 Make the New Page Template Linkable in the Link Manager

This step will allow you to use the link manager to link to the new content template. To do this, follow these steps:

Step 1: Create an 'ArticleLinkProvider' class in the Sana.Commerce.Sdk.Links.Providers namespace and inherit it from the 'ContentLinkProviderBase<T>' abstract class. Implement all abstract properties and methods:

Name Description
TableName The name of the property or field in the 'SanaDataContext' class that represents a data collection of the specified type.
Type The identifier of the link provider type. Must be the same as defined in the 'Routes' table (the 'Type' column of the record).
Name The link provider name. It will be shown in the backoffice dropdown where the link type can be selected.
GetUrl The method to get the URL by the item and the 'LinkData' instance.

For example the 'ArticleLinkProvider' class can be defined this way:

public class ArticleLinkProvider : ContentLinkProviderBase<Article>
{
    public override string TableName
    {
        get { return "Articles"; }
    }
    public override string Type
    {
        get { return "Article"; }
    }
    public override string Name
    {
        get { return "Article"; }
    }
    protected override string GetUrl(Article item, ILinkData linkData)
    {
        var url = ReplaceParameter(UrlTemplate, "id",
                 EncodeUrl(((IInternalPage)item) .GroupCode));
        url = ReplaceParameter(url, "title",
            UrlUtils.CleanParameterForUrl(item.Title));
        return url;
    }
}

In the example above the 'UrlTemplate' property is used. This property is defined in the 'InternalLinkProviderBase<T>' class and contains the 'RewrittenUrl' column value from the 'Routes' table. In the 'GetUrl' method the URL parameter is filled with the item values.

Step 2: Register the 'ArticleLinkProvider' class in the 'RegisterLinkManagerProviders' method of the 'Sana.Commerce.Sdk.WebApplication' class. Add the following line to the 'RegisterLinkManagerProviders' method:

linkManager.AddProvider(new ArticleLinkProvider());

Now the step is completed and you can see the new page template in the link manager dropdown in the backoffice.

How toDeveloper Guide