Adding ContentBlock to a Page via Fluent API

Posted by Community Admin on 04-Aug-2018 21:29

Adding ContentBlock to a Page via Fluent API

All Replies

Posted by Community Admin on 18-Mar-2015 00:00

Hello Sitefinity Team,

 I am trying to create Sitefinity pages via Fluent API and populate it with content by adding a ContenBlock control to the page. Everything seems fine except for the fact that the ContentBlock ends in the wrong place on the page, even though I specify the Placeholder name. The pages are based on built-in Sitefinity templates.

Here's the code snippet I'm using to create the page:

 

var content = new ContentBlock()
 
     Html = GetHtmlContent(),
     IsShared = false,
     Enabled = true,
 ;
 
 Guid pageId = new Guid();
 App.WorkWith()
     .Page()
     .CreateNewStandardPage(parentId, pageId)
     .Do(page =>
     
         page.Title = "Test page 1";
         page.UrlName = "tp-1";
         page.Name = "TestPage";
         page.Description = "";
         page.GetPageData().HtmlTitle = "This is a test";
         page.ShowInNavigation = false;
         page.DateCreated = DateTime.Now;
         page.Crawlable = true;
         page.RequireSsl = false;
     )
     .CheckOut()
     .SetTemplateTo(Guid.Parse("f669d9a7-009d-4d83-bbbb-000000000002"))
     .Control()
         .CreateNew(content, "Content")
         .Do(c =>
             
                 c.PlaceHolder = "Content";
             )
         .SaveChanges()
         .Done()
     .CheckIn()
     .SaveChanges();

 Any pointers would be greatly appreciated.

Posted by Community Admin on 23-Mar-2015 00:00

Hello Abe,

Currently we do not have a sample on how to add a control to a page using the Fluent API. What I can suggest is to refer to the following articles from our documentation for more details and sample code on how you can achieve this using the Native API.

Regards,
Sabrie Nedzhip
Telerik

 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 23-Mar-2015 00:00

Thanks Sabrie,

 

The issue is resolved now. I had to set the "zoneName" parameter to the correct value as shown in this screencast.

Posted by Community Admin on 30-Mar-2015 00:00

Hello Abe,

Thank for you for sharing your solution with the community and for the detailed video you have recorded.

I have also researched this on my side and here is another sample code you can use to place a content block on a page programatically:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Sitefinity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Modules.GenericContent.Web.UI;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Pages.Model;
using Telerik.Sitefinity.Workflow;
 
namespace SitefinityWebApp
    public partial class AddContentBlockToPageFluenApi : System.Web.UI.Page
    
        protected void Page_Load(object sender, EventArgs e)
        
            var content = new ContentBlock()
            
                Html = "<div>This is my content</div>",
                IsShared = false,
                Enabled = true,
            ;
 
            Guid pageId = Guid.NewGuid();
            var pageDataId = Guid.NewGuid();
 
            App.WorkWith()
                .Page()
                .CreateNewStandardPage(SiteInitializer.CurrentFrontendRootNodeId, pageId, pageDataId)
                .Do(page =>
                
                    page.Title = "Test page 3";
                    page.UrlName = "tp-3";
                    page.Name = "Test page 3";
                    page.Description = "";
                    page.GetPageData().HtmlTitle = "This is a test";
                    page.ShowInNavigation = false;
                    page.DateCreated = DateTime.Now;
                    page.Crawlable = true;
                    page.RequireSsl = false;
                )
                .SaveChanges();
 
            // Publish
            var bag = new Dictionary<string, string>();
            bag.Add("ContentType", typeof(PageNode).FullName);
            WorkflowManager.MessageWorkflow(pageId, typeof(PageNode), null, "Publish", false, bag);
 
            var templateId = new Guid("f669d9a7-009d-4d83-bbbb-000000000002");
            App.WorkWith().Page(pageId).AsStandardPage()
                .CheckOut()
                .SetTemplateTo(templateId)
                .Control()
                    .CreateNew(content, "Content")
                    .Do(c =>
                    
                        c.PlaceHolder = GetContentPlaceholderId(templateId, "Content", 1);
                        c.SiblingId = GetLastControlInPlaceHolderInPageId(pageId, c.PlaceHolder);
                    )
                    .SaveChanges()
                    .Done()
                .CheckIn()
                .Publish()
                .SaveChanges();
 
            //App.WorkWith().Page(pageId).AsStandardPage().CheckOut().UndoDraft().SaveChanges();              
        
 
        private static Guid GetLastControlInPlaceHolderInPageId(Guid pageId, string placeHolder)
        
            var pageManager = PageManager.GetManager();
            var page = pageManager.GetPageNodes().Where(p => p.Id == pageId).SingleOrDefault();
            var pageDraft = pageManager.EditPage(page.GetPageData().Id);
 
            var id = Guid.Empty;
            PageDraftControl control;
 
            var controls = new List<PageDraftControl>(pageDraft.Controls.Where(c => c.PlaceHolder == placeHolder));
 
            while (controls.Count > 0)
            
                control = controls.Where(c => c.SiblingId == id).SingleOrDefault();
                id = control.Id;
 
                controls.Remove(control);
            
 
            return id;
        
 
        public static string GetContentPlaceholderId(Guid templateId, string zoneName, int position)
        
            var pageManager = PageManager.GetManager();
            var contentAndSideBar = pageManager.GetTemplate(templateId).Controls.FirstOrDefault(x => x.Caption.Contains(zoneName));
            return contentAndSideBar.PlaceHolders[position];
 
        
           

In order to place the widget on the desired placeholder, you need to specify the zone name which is the for example the Caption of the placeholder and then the position. Please refer to the underlined part of the code below:

.Do(c =>
                    
                        c.PlaceHolder = GetContentPlaceholderId(templateId, "Content", 1);
                        c.SiblingId = GetLastControlInPlaceHolderInPageId(pageId, c.PlaceHolder);
                    )

Please also refer to the attached screenshot for more details about the positions.

Using the code sample above, the content block widget will be added in the placeholder with zone name Content and with position 1.

Regards,
Sabrie Nedzhip
Telerik
 
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items
 

Posted by Community Admin on 16-Apr-2015 00:00

Thanks for this post. It was a big help in my case. Could you add how you would set the default permissions on this control? When a control is created through the Fluent API like this, all of it's permissions are set to administrator only. I'm migrating roughly 800 pages and need the default permissions for a content block applied.

When I try to apply permissions, I get the following error:

Object references between two different object scopes are not allowed. The object 'Telerik.Sitefinity.Security.Model.Permission' is already managed by 'ObjectScopeImpl 0x48 OpenAccessRuntime.EnlistableObjectScope' and was tried to be managed again by 'ObjectScopeImpl 0x49 OpenAccessRuntime.EnlistableObjectScope'.

Here's my code:

App.WorkWith().Page(pageId).AsStandardPage()
    .CheckOut()
    .SetTemplateTo(templateId)
    .Control()
        .CreateNew(content, "Content")
        .Do(c =>
            
                c.PlaceHolder = primaryContentPlaceholder;
                c.Caption = "Primary Content";
                c.SetDefaultPermissions(pageManager);
            )
        .SaveChanges()
        .Done()
    .CheckIn()
    .SaveChanges();

If I remove the following line, I don't get the error but I don't get the desired permissions either:

c.SetDefaultPermissions(pageManager);

Thanks!

Posted by Community Admin on 16-Apr-2015 00:00

I fixed it on my own. For the sake of cleanup to post my code here, I moved some extra logic I had out of the API call and all is now well.

This thread is closed