Adding layout controls to pages and page templates

Layout controls can be added to Pages and Page Templates. In order 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 the  Custom layout widgets article.
  • 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;

        }

 

To add a LayoutControl to a Page: 

The Layout Control is simply added 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;

        }

 

To add a LayoutControl to a Page Template: 

The LayoutControl is simply added it 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;

        }

Querying 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();

 

Working 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 Sitefinty 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;

        }

 

The following example demonstrates a complete use case:

  • 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)

        {

            //NOTE: It's very important to set the Thread.CurrentThread.CurrentUiCulture,

            //for your template and layout controls to be persisted in a specific language, otherwise it might behave abnormally

            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;

        }

    }

}

 

 

 

Was this article helpful?