Adding layout controls to pages and page templates

Overview

You can add layout controls to Pages and Page Templates. To create a LayoutControl to a Page or PageTemplate, you must:

  • Specify its type – If you will be adding the control to a Page, use a PageControl, but if it will be added on a Template, use a TemplateControl.
  • Specify its Caption – The text that is the label of your LayoutControl when it is dropped on a page or template.
  • Specify its Layout – The path to the LayoutControl’s template file (.ascx). For more information about the .ascx, see Layout widgets: Create custom layout widgets.
  • Specify its Placeholder – The name of the Placeholder on the Page or Template where your LayoutControl will be placed. By default, you can use “Body” which means your layout will be placed among all other controls in the main Body placeholder of the page/template. Alternatively you can query a specific placeholder on a page(or its template), for example:
public static string GetHeaderPlaceholderId(PageData pageData)
{
var headerControl = pageData.Template.Controls.FirstOrDefault(x => x.Caption.Contains("Header"));
// Col00 means the first column. As this control has only one column the number is 00;
var headerControlAsPlaceholderId = headerControl.Properties.FirstOrDefault(x => x.Name == "ID").Value + "_Col00";
return headerControlAsPlaceholderId;
}

Add a LayoutControl to a page

You add the Layout Control to the intended object’s Controls collection. The following example shows how to create a LayoutControl, and then add it to a Page:

/// <summary>
/// Creates a new Layout control and add it to the specified template
/// </summary>
/// <param name="pageToAddLayoutTo">The PageData object to add the layout control to</param>
/// <param name="caption">The LayoutControl Caption</param>
/// <param name="placeholder">The Placeholder on the template where the layoutControl will be placed</param>
/// <param name="layoutTemplatePath">The path to the LayoutControl's presentation part (ascx)</param>
/// <param name="manager">a PageManager instance</param>
/// <param name="persistChanges">whether to persist changes or not. Can be false if you're calling SaveChanges() later</param>
/// <returns>a PageControl instance that is wrapping the LayoutControl</returns>
public PageDraftControl AddLayoutControlToPage(PageData pageToAddLayoutTo, string caption, string placeholder, string layoutTemplatePath, PageManager manager, bool persistChanges)
{
var layoutControl = manager.CreateControl<PageDraftControl>();
layoutControl.Caption = caption;
layoutControl.ObjectType = typeof(LayoutControl).FullName; // "Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity";
layoutControl.PlaceHolder = placeholder;
layoutControl.IsLayoutControl = true;
manager.SetControlDefaultPermissions(layoutControl);
var prop = manager.CreateProperty();
prop.Name = "Layout";
prop.Value = layoutTemplatePath;
layoutControl.Properties.Add(prop);
var master = manager.PagesLifecycle.Edit(pageToAddLayoutTo);
var temp = manager.PagesLifecycle.CheckOut(master);
//add the LayoutControl to the template
manager.SetControlId(temp, layoutControl);
temp.Controls.Add(layoutControl);
master = manager.PagesLifecycle.CheckIn(temp);
manager.PagesLifecycle.Publish(master);
if (persistChanges)
manager.SaveChanges();
return layoutControl;
}

Add a LayoutControl to a Page Template

You simply add theLayoutControl to the intended object’s Controls collection. The following example shows how to create a LayoutControl, and then add it to a Page Template:

/// <summary>
/// Creates a new Layout control and add it to the specified template
/// </summary>
/// <param name="templateToAddLayoutTo">The pageTemplate object to add the layout control to</param>
/// <param name="caption">The LayoutControl Caption</param>
/// <param name="placeholder">The Placeholder on the temaplte where the layoutControl will be placed</param>
/// <param name="layoutTemplatePath">The path to the LayoutControl's presentation part (ascx)</param>
/// <param name="manager">a PageManager instance</param>
/// <param name="persistChanges">whether to persist changes or not. Can be false if you're calling SaveChanges() later</param>
/// <returns>a templateControl instance that is wrapping the LayoutControl</returns>
public Telerik.Sitefinity.Pages.Model.TemplateDraftControl AddLayoutControlToTemplate(PageTemplate templateToAddLayoutTo, string caption, string placeholder, string layoutTemplatePath, PageManager manager, bool persistChanges)
{
var layoutControl = manager.CreateControl<Telerik.Sitefinity.Pages.Model.TemplateDraftControl>();
layoutControl.Caption = caption;
layoutControl.ObjectType = layoutControl.ObjectType = typeof(LayoutControl).FullName;
layoutControl.PlaceHolder = placeholder;
layoutControl.IsLayoutControl = true;
manager.SetControlDefaultPermissions(layoutControl);
var prop = manager.CreateProperty();
prop.Name = "Layout";
prop.Value = layoutTemplatePath;
layoutControl.Properties.Add(prop);
var master = manager.TemplatesLifecycle.Edit(templateToAddLayoutTo);
var temp = manager.TemplatesLifecycle.CheckOut(master);
manager.SetControlId(temp, layoutControl);
//Add the LayoutControl to the template
temp.Controls.Add(layoutControl);
master = manager.TemplatesLifecycle.CheckIn(temp);
manager.TemplatesLifecycle.Publish(master);
if (persistChanges)
manager.SaveChanges();
return layoutControl;
}

Query LayoutControls

To query the LayoutControls, you access the Controls collection on the Page or Template to work on those where the ObjectType is LayoutControl.

Example of a query of the LayoutControls on a Page by the Caption property:
var pageData = manager.GetPageDataList()
.Where(pd => pd.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live
&& pd.NavigationNode.Title == "Home")
.SingleOrDefault();
var layoutControlOnPage = pageData.Controls
.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Sample caption").FirstOrDefault();
Example of a query of the LayoutControls on a page's Page Template:
var pageData = manager.GetPageDataList()
.Where(pd => pd.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live
&& pd.NavigationNode.Title == "Home")
.SingleOrDefault();
var layoutControlOnPageTemplate = pageData.Template.Controls
.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Sample caption").FirstOrDefault();

Work with LayoutControl’s placeholders

When you want to put a widget inside a LayoutControl programmatically, you work with the Placeholders collection of the LayoutControl. The placeholders are the containers that form the docking zones in Sitefinity that allow you to “dock” a widget on them. For example, a LayoutControl whose template defines only a single 100% layout has a single Placeholder object in its Placeholders collection. A LayoutControl with 3 columns has three Placeholders. First, you must locate the Placeholder you want. Since the Placeholders collection is a string [] you use index to get the desired Placeholder. For example:

var pageData = manager.GetPageDataList()
.Where(pd => pd.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live
&& pd.NavigationNode.Title == "Home")
.SingleOrDefault();
var layoutControlOnPage = pageData.Controls
.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Sample caption").FirstOrDefault();
var placeholder = layoutControlOnPage.PlaceHolders[0];

Then you specify the widget’s placeholder. When you create a new widget that will be added to a Sitefinity page through code, you can supply the placeholder on the page where it will be added. To do this, use the the PageManager.CreateControl<T>()method. The following example shows the creation of a basic ContentBlock and setting its placeholder before adding it to the page:

public PageControl AddControlToPage(Control controlToAdd, PageManager manager, PageData pageData, string caption, string layoutControlPlaceholderName, bool persistChanges)
{
var control = manager.CreateControl<PageControl>(controlToAdd, layoutControlPlaceholderName);
control.Caption = caption;
control.SiblingId = GetLastControlInPlaceHolderInPageId(pageData.NavigationNode, layoutControlPlaceholderName);
manager.SetControlDefaultPermissions(control);
pageData.Controls.Add(control);
if (persistChanges)
manager.SaveChanges();
return control;
}

Code sample

The following sample demonstrates:

  • Creating a PageTemplate
  • Adding a LayoutControl to it
  • Creating a Page based on the Template
  • Adding a control in the template’s placeholder on the page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.UI;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Localization;
using Telerik.Sitefinity.Modules.GenericContent.Web.UI;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Pages.Model;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Web.UI;
using Telerik.Sitefinity.Workflow;
namespace SitefinityWebApp
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
using (new CultureRegion("en"))
{
var manager = PageManager.GetManager();
//create a new template
var templateName = "MyNewTemplate" + Guid.NewGuid().ToString();
var description = "Sample template created through code";
var pageTemplate = CreatePageTemplate(templateName, description, manager, true);
//create layout control and add it to the Template
var caption = "Custom layout control";
var layoutPath = "~/CustomLayoutControlsSamples/Column1Template.ascx";
var placeholderName = "Body";
AddLayoutControlToTemplate(pageTemplate, caption, placeholderName, layoutPath, manager, true);
//create page and assign template to it
var pageTitle = "MyTestPage" + Guid.NewGuid().ToString();
CreatePageNativeAPI(manager, Guid.NewGuid(), pageTitle, false, Guid.Empty, pageTemplate);
var pageData = manager.GetPageDataList()
.Where(pd => pd.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live
&& pd.NavigationNode.Title == "Home")
.SingleOrDefault();
var layoutControlOnPage = pageData.Controls
.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Sample caption").FirstOrDefault();
var layoutControlOnPageTemplate = pageData.Template.Controls
.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Sample caption").FirstOrDefault();
var placeholder = layoutControlOnPage.PlaceHolders[0];
AddLayoutControlToPage(pageData, "1234", "Body", layoutPath, manager, true);
}
}
/// <summary>
/// Creates a PageTemplate
/// </summary>
/// <param name="templateName">The name of the new template</param>
/// <param name="description">The template description</param>
/// <param name="manager">a PageManager instance</param>
/// <param name="persistTemplate">whether to persist the template or not. Can be false if you're calling SaveChanges() later</param>
/// <returns>a PageTemplate instance</returns>
public PageTemplate CreatePageTemplate(string templateName, string description, PageManager manager, bool persistTemplate)
{
var pageTemplate = manager.CreateTemplate();
pageTemplate.Category = SiteInitializer.CustomTemplatesCategoryId;
pageTemplate.Title = templateName;
pageTemplate.Name = templateName;
pageTemplate.Description = description;
pageTemplate.ShowInNavigation = true;
pageTemplate.Visible = true;
var editTemplate = manager.TemplatesLifecycle.Edit(pageTemplate);
manager.TemplatesLifecycle.Publish(editTemplate);
if (persistTemplate)
manager.SaveChanges();
return pageTemplate;
}
/// <summary>
/// Creates a new Layout control and adds it to the specified template
/// </summary>
/// <param name="templateToAddLayoutTo">The pageTemplate object to add the layout control to</param>
/// <param name="caption">The LayoutControl Caption</param>
/// <param name="placeholder">The Placeholder on the template where the layoutControl will be placed</param>
/// <param name="layoutTemplatePath">The path to the LayoutControl's presentation part (ascx)</param>
/// <param name="manager">a PageManager instance</param>
/// <param name="persistChanges">whether to persist changes or not. Can be false if you're calling SaveChanges() later</param>
/// <returns>a templateControl instance that is wrapping the LayoutControl</returns>
public Telerik.Sitefinity.Pages.Model.TemplateDraftControl AddLayoutControlToTemplate(PageTemplate templateToAddLayoutTo, string caption, string placeholder, string layoutTemplatePath, PageManager manager, bool persistChanges)
{
var layoutControl = manager.CreateControl<Telerik.Sitefinity.Pages.Model.TemplateDraftControl>();
layoutControl.Caption = caption;
layoutControl.ObjectType = layoutControl.ObjectType = typeof(LayoutControl).FullName;
layoutControl.PlaceHolder = placeholder;
layoutControl.IsLayoutControl = true;
manager.SetControlDefaultPermissions(layoutControl);
var prop = manager.CreateProperty();
prop.Name = "Layout";
prop.Value = layoutTemplatePath;
layoutControl.Properties.Add(prop);
var master = manager.TemplatesLifecycle.Edit(templateToAddLayoutTo);
var temp = manager.TemplatesLifecycle.CheckOut(master);
manager.SetControlId(temp, layoutControl);
//Add the LayoutControl to the template
temp.Controls.Add(layoutControl);
master = manager.TemplatesLifecycle.CheckIn(temp);
manager.TemplatesLifecycle.Publish(master);
if (persistChanges)
manager.SaveChanges();
return layoutControl;
}
/// <summary>
/// Creates a new Layout control and adds it to the specified template
/// </summary>
/// <param name="pageToAddLayoutTo">The PageData object to add the layout control to</param>
/// <param name="caption">The LayoutControl Caption</param>
/// <param name="placeholder">The Placeholder on the temaplte where the layoutControl will be placed</param>
/// <param name="layoutTemplatePath">The path to the LayoutControl's presentation part (ascx)</param>
/// <param name="manager">a PageManager instance</param>
/// <param name="persistChanges">whether to persist changes or not. Can be false if you're calling SaveChanges() later</param>
/// <returns>a PageControl instance that is wrapping the LayoutControl</returns>
public PageDraftControl AddLayoutControlToPage(PageData pageToAddLayoutTo, string caption, string placeholder, string layoutTemplatePath, PageManager manager, bool persistChanges)
{
var layoutControl = manager.CreateControl<PageDraftControl>();
layoutControl.Caption = caption;
layoutControl.ObjectType = typeof(LayoutControl).FullName; // "Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity";
layoutControl.PlaceHolder = placeholder;
layoutControl.IsLayoutControl = true;
manager.SetControlDefaultPermissions(layoutControl);
var prop = manager.CreateProperty();
prop.Name = "Layout";
prop.Value = layoutTemplatePath;
layoutControl.Properties.Add(prop);
var master = manager.PagesLifecycle.Edit(pageToAddLayoutTo);
var temp = manager.PagesLifecycle.CheckOut(master);
//add the LayoutControl to the template
manager.SetControlId(temp, layoutControl);
temp.Controls.Add(layoutControl);
master = manager.PagesLifecycle.CheckIn(temp);
manager.PagesLifecycle.Publish(master);
if (persistChanges)
manager.SaveChanges();
return layoutControl;
}
/// <summary>
/// Creates a new page
/// </summary>
/// <param name="manager"></param>
/// <param name="pageId"></param>
/// <param name="pageName"></param>
/// <param name="isHomePage"></param>
/// <param name="parentPageNodeId"></param>
/// <param name="template"></param>
/// <param name="layoutControlPlaceholderName"></param>
public void CreatePageNativeAPI(PageManager manager, Guid pageId, string pageName, bool isHomePage, Guid parentPageNodeId, PageTemplate template)
{
PageManager manager = PageManager.GetManager();
PageData pageData = null;
PageNode pageNode = null;
// Get the parent node Id
if (parentPageNodeId == Guid.Empty)
parentPageNodeId = SiteInitializer.CurrentFrontendRootNodeId;
PageNode parent = manager.GetPageNode(parentPageNodeId);
// Check whether exists
var initialPageNode = manager.GetPageNodes().Where(n => n.Id == pageId).SingleOrDefault();
if (initialPageNode != null)
return;
// Create the page
pageNode = manager.CreatePage(parent, pageId, NodeType.Standard);
//pageData.NavigationNode = pageNode;
pageData = pageNode.GetPageData();
pageData.Culture = Thread.CurrentThread.CurrentCulture.ToString();
pageData.HtmlTitle = pageName;
pageData.Template = template;
//create a sample ContentBlock and place it in the desired LayoutControl
var layoutControlOnTemplate = template.Controls.Where(c => c.ObjectType == typeof(LayoutControl).FullName
&& c.Caption == "Custom layout control").FirstOrDefault();
var placeholderId = layoutControlOnTemplate.PlaceHolders[0];
ContentBlockBase sampleContentBlockControl = new ContentBlockBase();
sampleContentBlockControl.Html = "<h1>Account Registration</h1>";
AddControlToPage(sampleContentBlockControl, manager, pageData, "Sample Content Block", placeholderId, false);
pageNode.Title = pageName;
pageNode.Description = pageName;
pageNode.Name = pageName;
pageNode.UrlName = Regex.Replace(pageName.ToLower(), @"[^\w\-\!\$\'\(\)\=\@\d_]+", "-");
pageNode.ShowInNavigation = true;
pageNode.DateCreated = DateTime.UtcNow;
pageNode.LastModified = DateTime.UtcNow;
// Check whether home page
if (isHomePage)
SystemManager.CurrentContext.CurrentSite.SetHomePage(pageId);
manager.SaveChanges();
// Publish
var bag = new Dictionary<string, string>();
bag.Add("ContentType", typeof(PageNode).FullName);
WorkflowManager.MessageWorkflow(pageData.Id, typeof(PageNode), null, "Publish", false, bag);
}
public PageControl AddControlToPage(Control controlToAdd, PageManager manager, PageData pageData, string caption, string layoutControlPlaceholderName, bool persistChanges)
{
var control = manager.CreateControl<PageControl>(controlToAdd, layoutControlPlaceholderName);
control.Caption = caption;
control.SiblingId = GetLastControlInPlaceHolderInPageId(pageData.NavigationNode, layoutControlPlaceholderName);
manager.SetControlDefaultPermissions(control);
pageData.Controls.Add(control);
if (persistChanges)
manager.SaveChanges();
return control;
}
private static Guid GetLastControlInPlaceHolderInPageId(PageNode page, string placeHolder)
{
var id = Guid.Empty;
var controls = new List<PageControl>(page.Page.Controls.Where(c => c.PlaceHolder == placeHolder));
while (controls.Count > 0)
{
PageControl control = controls.SingleOrDefault(c => c.SiblingId == id);
if (control != null)
{
id = control.Id;
controls.Remove(control);
}
}
return id;
}
}
}

Want to learn more?

Increase your Sitefinity skills by signing up for our free trainings. Get Sitefinity-certified at Progress Education Community to boost your credentials.

Get started with Integration Hub | Sitefinity Cloud | Sitefinity SaaS

This free lesson teaches administrators, marketers, and other business professionals how to use the Integration hub service to create automated workflows between Sitefinity and other business systems.

Web Security for Sitefinity Administrators

This free lesson teaches administrators the basics about protecting yor Sitefinity instance and its sites from external threats. Configure HTTPS, SSL, allow lists for trusted sites, and cookie security, among others.

Foundations of Sitefinity ASP.NET Core Development

The free on-demand video course teaches developers how to use Sitefinity .NET Core and leverage its decoupled architecture and new way of coding against the platform.

Was this article helpful?