CONTENTSTART
EXCLUDESTART EXCLUDEEND

Deep Dive into Kentico – Intro

 Sometimes the best way to really understand how something works is to take it apart, see the nuts and bolts and really understand how something works, instead of just knowing that it works.  In this series, I want to show you all how Kentico does what it does.  Ultimately knowing how it works will lead you to develop and build your sites in a way that will be consistent with Kentico’s framework, and give you the power to leverage systems and resources that are inside of Kentico to do amazing things.  Many of my tools were built using this deeper knowledge of Kentico, and I hope it will help inspire better sites and better tools in the future!

Part 1: Portal Method

Kentico’s recommended development method is what is called the “Portal Method.”  Portal method can be summed up in “Everything should be doable in the portal (the web interface).”  This means all the pieces that make up a webpage (HTML Structure, Webparts, Widgets, etc) should be built through the web interface and managed there.  We’ll give a very brief look at these elements but then get into how Kentico stores and builds from them.

Pages and Page Templates

Page Templates comprise of the skeleton of a web page.  Inside of Kentico, each “Page” that you can visit on your site has a Page Template attached to it.  The Page template consists of 2 main items:
  1. Layout: The actual HTML Code
  2. WebParts: The Dynamic Elements / Controls
Page Templates also have inheritance that can inherit other Page Templates (Such as a Master Template that contains the Header/Footer).
Pages on the other hand, are a little simpler.  Pages contain:
  1. A Page Template
  2. Widgets
  3. Document Content
The general concept is that a Page Loads its Template (which renders itself and any parent templates, like the master template), then adds its Content / Widgets into that Page Template to give the user the finished page.  Let’s dive into how it does that at each level.

Page Template Layout: HTML and Web part Zones

The Page Template’s “Layout” (CMS_PageTemplate.PageTemplateLayout) is the starting point of our structure.  Itself, it contains 2 elements:
  1. Html Code: The actual Html structure of the page.  Divs, classes, sections, really any html.  It provides the backbone to the page
  2. Web part Zones: These either ASCX or Macro line dictates an area where WebParts are rendered.  Zones have a unique ID (Name).

Here’s my Layout for this test Template:

<div class="container">
  <cms:CMSWebPartZone ZoneID="ZoneA" runat="server" />
  <cms:CMSWebPartZone ZoneID="ZoneB" runat="server" />
</div>

Page templates also can do things like Conditional Layouts and Device Layouts, but that’s for another discussion.  Right now I want everyone to focus on the Web part Zones, and its unique name you give it as we go into the next part of the Page Template, the Web Parts.

Web Parts

Before we talk about adding Web Part’s to the Page Template, let’s define what a Web Part is.  In its simplest form, a Web Part is an ASCX Control by which you can pass parameters to and it does something (in most cases spitting our HTML or other controls). 

In Kentico, when you create a new Web Part, you have to point to an ASCX control, and then define the parameters (fields) which you want to capture from the user, and then once stored pass to the web part to render.

Page Templates: Design / Web Parts

Now that we have covered Webparts, let’s get back to our Test Template.  In the Page Templates tool, under the “Design” tab on our template, we see our 2 zones (ZoneA and ZoneB)

Let’s go ahead and add a Repeater to the ZoneA:

When you hit “Save and Close” What happened?  Well, to show you that, let’s switch to the Web Parts tab of the page template to reveal the magic.  Analyze the below XML (I removed many of the tags to shorten it), taking note of the highlights and bolded items.

<page>
  <webpartzone id="ZoneA" v="1">
    <webpart controlid="MyRepeater" guid="01cea96a-e301-41fd-a3f1-1a8f33f0741e" type="repeater" v="1">
      <property name="alternatingtransformationname"></property><property name="checkpermissions">False</property>
      <property name="classnames">CMS.MenuItem</property><property name="contentbefore"></property>
      <property name="controlid">MyRepeater</property><property name="partialcacheminutes"></property>
      <property name="path">/%</property><property name="timezonetype">inherit</property>
      <property name="transformationname">CMS.MenuItem.Default</property></webpart>
  </webpartzone>
</page>

This XML structure (located in the database at CMS_PageTemplate.PageTemplateWebParts) contains the configuration for that page Template.  Note it has <webpartzone> tags with their IDs (“ZoneA”), then a list of <webpart> elements with an ID (MyRepeater), a type (the Web Part Code Name), and all of the Properties that will be available to that web part by Property Name.

So when this page template renders, this is what occurs:

  1. Grab the Page Template Layout and PageTemplateWebParts XML
  2. For each Web Part Zone in the Layout, find any <webpartzone> with matching ID in the XML, then:
    1. Loop through all of the <webpart> elements under that <webpartzone> and then:
      1. Look up the WebPart’s control from its type attribute (Ex: Repeater), found in the CMS_WebPart.WebPartName
      2. Grab the WebPartFileName to get the ASCX control path, and load it in.
      3. Pass the Properties for that <webpart> into the ASCX Control
        1. The ASCX Control (webpart) then Get’s those properties (through GetValue(“ThePropertyName”) and builds and renders itself.

In our case, the Page Template will add a Repeater control, passing it the parameters such as the Path, Page Types (classnames), and Transformation Name, which in turn the repeater control will load and render into HTML.

Pretty brilliant, aye? 

Pages, Widget Zones and Widgets – Similar to Page Templates and Web Parts

Page templates span across multiple pages, which give the flexibility to modify functionality (like menus) across a large amount of pages at once.  However each individual page needs to have its own content as well.  This is done through Widgets and Document Content.

Widget Zones?

What are Widget Zones?  Well Widget zones are just Web Part Zones that have their attribute set to be a “Widget Zone.” In the Page Template, if you configure the Web Part Zone and set it’s “Widget Zone Type” to anything other than “None” it will become a widget zone and allow widgets to be added on the pages that use this template.  The most common Widget Zone type is “Customization by page editor,” but widget zones can be set to be User Personalized (widgets will contain a reference to the user that added them so they only render for that user) and Group administrator (widgets contain a reference to the group administrator so they only render for that group admin and the group they control, I believe).

Here’s the Web Part XML for a Widget Zone:

<webpartzone id="ZoneB" v="1" widgetzonetype="editor">
    <properties>
      <property name="containerhideonsubpages">False</property>
      <property name="disableviewstate">False</property>
      <property name="hideonsubpages">False</property>
      <property name="timezonetype">inherit</property>
      <property name="useupdatepanel">False</property>
      <property name="visible">True</property>
    </properties>
  </webpartzone>

Notice the “Widgetzonetype” attribute is set to Editor.  This way when the Web Part Zone control renders, it will instead look for widgets, but I’m getting ahead of myself.

How are widgets stored?

Since widgets are Page Specific, their confirmation is stored on the CMS_Document.DocumentWebParts field in the database.  Let’s add a widget to a page using our Test Template and take a look at the field:

 I set the Rich text to “Hello, World!” and saved (widgets only save to the document when you hit “Save”)

<page>
	<webpartzone id="ZoneB" v="1" widgetzonetype="editor">
		<properties>
			<property name="containerhideonsubpages">False</property>
			<property name="disableviewstate">False</property>
			<property name="hideonsubpages">False</property>
			<property name="timezonetype">inherit</property>
			<property name="useupdatepanel">False</property>
			<property name="visible">True</property>
		</properties>
		<webpart controlid="richtext" guid="8545e873-ff6a-4cf9-9e7d-42989775c802" iswidget="true" type="richtext" v="1"><property name="showfordocumenttypes"/>
			<property name="text">Hello, World!</property></webpart>
	</webpartzone>
</page>

Here we see a similar structure to the Page Templates, it has the WebpartZone (with ID), and the Webpart’s (Widgets) within it, including the type which identifies the widget’s code name.

So when the page renders:

  1. Render the Page Template, load in the Document’s DocumentWebParts XML
  2. For each webpartzone in the XML, find any Webpart Zones in the Page Template that are of the correct type (widget) and have an ID that matches the XML’s webpartzone ID
    1. Loop through the <webpart> elements in that <webpartzone> element, and then
      1. Based on the webpart’s ‘type’, find the widget that has that type codename
      2. From the widget find the Web Part that the widget is based off of
      3. Load in the ASCX from the web part, and then pass it the Properties from the <webpart> in the XML

Very similar in its processes, which really reveals the magic of it.

Document Content

Worth noting, there are specific types of Web Parts that you can set in the Page Template, but record data at a Page Level.  A great example of this is the Editable Text Web Part, which allows you to enter text/html on each individual page.  This works almost the same as Widgets, let’s add an Editable Text Web Part to our Page Template, then put in some text on our Test Page, and examine/compare the CMS_PageTemplate.PageTemplateWebParts and the CMS_Document.DocumentContent XML:

Page Template Web Parts:

<webpartzone id="ZoneA" v="1">
		<webpart controlid="MyRepeater" guid="01cea96a-e301-41fd-a3f1-1a8f33f0741e" type="repeater" v="1"></webpart>
		<webpart controlid="MyEditableText" guid="fdddce62-c321-410b-8578-91f464d7d143" type="editabletext" v="1">
			<property name="cat_open_ajax"/></webpart>
	</webpartzone>

Document Content:

<content>
	<webpart id=myeditabletext;<;strong>fdddce62-c321-410b-8578-91f464d7d143>
		<![CDATA[This is content in the Editable Text!]]>
	</webpart>
</content>

Again we can see the link.  The Document Content has the <webpart>’s id and guid, which when rendering the Page Template for that page can pass it’s content (“This is content in the Editable Text!”) to that Web Part to render.
 

Inline Widgets

A Special note should be made for Inline Widgets.  Inline Widgets use the Macro Engine (to a degree) to allow you to place widgets in content sections.  I added a “Link” widget to my Editable Text area on my test page, and this is what renders in the DocumentContent field:

<content>
	<webpart id="myeditabletext;fdddce62-c321-410b-8578-91f464d7d143">
		<![CDATA[This is content in the Editable Text! 
			{^widget|(name)Link|(LinkText)This+is+an+inline+link+widget!|(LinkUrl)http%3a%2f%2fgoogle.com|(LinkTarget)_blank|(widget_displayname)Link^}
		]]>
	</webpart>
</content>

If you look here, the are being declared, and include the (name) which is the widget code name, and the properties set (LinkText, LinkUrl, LinkTarget, widget_displayname).  When the Content is being rendered, it passes through Kentico’s rendering engine which can take this, and then resolve the inline control’s content with the text. 
 

Nested Templates, Web Part Zones

Kentico’s controls have a sort of recursive nature that allows them to nest content.  For Page Template, there is a web part called “Page Placeholder” which when a template inherits parent templates, it will place the Page + Page Template’s content in that Page Placeholder of its parent templates.  An example is a Master Template has a Header/Footer, and a Page Placeholder in the middle.  Subpages inherit the master page, so when they render, they place their content into the Page Placeholder of the master page.

Likewise, you can add “Web Part Zones” inside of web part zones, as long as the Webpart Zone’s ID is unique.  And upon rendering one zone, when it hits another Web Part Zone webpart inside of itself, will render that zone with any web parts defined in it.

Application

Since you now know that the Webpart/Widget Configuration that’s saved in the document is linked by the Webpart Zone ID, you can easily “import” web parts form one template into another if you create a zone with matching Zone ID.  Also if you make multiple templates that have different structure (Say a 25-75 page, and a 50-50 page), as long as you keep the zone IDs the same you can switch between templates without having to adjust.

Likewise if something on a Page messes up, and you can’t roll back the version, you can carefully modify the DocumentWebParts field value and update it (I’ve had to do that a couple times).

You can also, using Kentico’s API, get at the Document or Page Template information.  Although Kentico 10 has the tools now, in the past if you wanted to find out where something was used or reference, you would have to run a SQL query, and look in these fields (say you wanted to know if a transformation was used anywhere, Page Templates, Widget Default Values, Documents, etc.)

Conclusion

I hope you enjoyed this deep look into Kentico!  Next one we’re going to go into the Form Control Engine and a couple more resources and how they work and run in Kentico.
Comments
Blog post currently doesn't have any comments.
= one - six
CONTENTEND