+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Working with Layout Controls Programmatically

by Stanislav Velikov
Sitefinity's backend UI allows adding various configurations for layout controls to control the page layout display and in this blog post I will provide a sample on how to create new layout controls on a page using the API and how to query layout controls on pages.

1. To create Layout control on a page refer to the sample method below, it refers to this documentation sample and extends it.

public void AddControlToPage(string pageTitle, string placeHolder, string caption)
       {
           var pageManager = PageManager.GetManager();
           var page = pageManager.GetPageNodes().Where(p => p.Title == pageTitle).SingleOrDefault();
  
           if (page != null)
           {
               var temp = pageManager.EditPage(page.Page.Id);
               Guid controlID = Guid.NewGuid();
               if (temp != null)
               {
                   var pageControl = pageManager.CreateControl<PageDraftControl>(controlID);
                   pageControl.Caption = caption;
                   pageControl.ObjectType = "Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity";
  
                   pageControl.PlaceHolder = placeHolder;
                   pageControl.IsLayoutControl = true;
                   pageManager.SetControlDefaultPermissions(pageControl);
  
  
                   var prop = pageManager.CreateProperty();
                   prop.Name = "Layout";
                   prop.Value = "~/SFRes/Telerik.Sitefinity.Resources.Templates.Layouts.Column1Template.ascx";
                   pageControl.Properties.Add(prop);
                     
  
                   temp.Controls.Add(pageControl);
                   pageManager.PagesLifecycle.CheckIn(temp);
                   pageManager.SaveChanges();
  
                   var bag = new Dictionary<string, string>();
                   bag.Add("ContentType", typeof(PageNode).FullName);
                   WorkflowManager.MessageWorkflow(page.Id, typeof(PageNode), null, "Publish", false, bag);
  
               }
           }
       }

The code creates a new control in the page and sets its ObjectType to the type of the Sitefinity layout controls.

var pageControl = pageManager.CreateControl<PageDraftControl>(controlID);
                   pageControl.Caption = caption;
                   pageControl.ObjectType = "Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity";

The other required property to make the PageDraftControl layout control is 

pageControl.IsLayoutControl = true;

Each layout control is different and to make the control place specific layout control on the page, you need to create a new property for the control with Name "Layout" and as value pass the path to the layout control template. All layout control paths can be found in Administration->Settings->Advanced->Toolboxes->Toolboxes->PageLayouts->Sections->TwoCol. To select the layout control you want to use, refer to its Layout Template textbox.

var prop = pageManager.CreateProperty();
                    prop.Name = "Layout";
                    prop.Value = "~/SFRes/Telerik.Sitefinity.Resources.Templates.Layouts.Column1Template.ascx";
                    pageControl.Properties.Add(prop);


2. Once added, the layout controls can be queried so you can find what is the placeholder id of each layout control and use it to place controls into it. To query layout controls based on different properties refer to the sample below.

public void QueryLayoutControls(string pageTitle)
        {
            var pageManager = PageManager.GetManager();
            var page = pageManager.GetPageNodes().Where(p => p.Title == pageTitle).SingleOrDefault();
            if (page != null)
            {
                Guid controlID = Guid.NewGuid();
               //find layout control on a page by one of the shown properties
                    var pageControls = pageManager.GetControls<PageDraftControl>()
                                            .Where(c=>c.ObjectType.Equals("Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity")
                                            && c.Caption.Equals("100%")
                                            && c.IsLayoutControl == true);
 
                    foreach (var control in pageControls)
                    {
                        var placeholder = control.PlaceHolder;
                        var placeholders = control.PlaceHolders;
                        var property = control.Properties;
                        var cap = control.Caption;
                        //here you can the name of the .ascx file used for this control
                        var nameProp = property.Where(pro=> pro.Name.Equals("Layout"));
                    }
            }
        }

In the query for retrieving layout controls I have used several properties to demo the available ways to query layout controls by different property to server different cases:

ObjectType.Equals("Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity")

 For caption enter the name of the layout control used. If the control is called "CustomLayoutControl", in its caption use this name to find specific controls:

c.Caption.Equals("100%")

 The placeholder name which each layout control produces is the property "placeholderId". Use this placeholder name to nest other controls in this layout control.

var placeholders = control.PlaceHolders;

4 comments

Leave a comment
  1. Martin Hoey Nov 21, 2013
    Hi Stanislav

    In the last example for querying layout controls, it gets all controls for all pages.

    How can the page.id be used to filter only layout controls for the Page?

    //find layout control on a page by one of the shown properties                    
    var pageControls = pageManager.GetControls<PageDraftControl>() .Where(c=>c.ObjectType.Equals("Telerik.Sitefinity.Web.UI.LayoutControl, Telerik.Sitefinity")

    Regards

    Martin
  2. Jonathan Read Dec 16, 2013
    Thanks for this article!  Once I have the layout control PlaceHolders how can I add a content block or any control via the API?   I have been unsuccessful in being able to add a content block to "left column" of a 25% 75% layout control.  Its confusing that the PlaceHolders return as strings and not objects that I can add controls too.

    Any advice?

    Thanks,

    Jonathan
  3. Jonathan Read Dec 16, 2013
    So after some guidance if you use  AddControlToPage() and pass in your PlaceHolder Id you can then add Controls to your LayoutControl columns
  4. Josh Feb 14, 2014
    this code doesn't appear to work for adding layouts to the backend pages. I ran the code, and if I look at the list of controls for the page, I see my layouts listed. but when I open the backend page, none of the controls are there.

    is there an extra step to make this work for the backend? or is this just not supported?

    Leave a comment