Programmatically add widget to page

Ryan Anthoney asked on December 3, 2019 14:13

Hi guys,

I have a Kentico 11 solution at the moment which has some documents (e.g. Blogs for example) that have fields that are populated by an import function (scheduled task).

I'm trying to build another task that populates page/widget content using the fields from the Form Tab (these are used in multiple places and there are conditions for there being a page).

int updateCounter = 0;
TreeProvider tree = new TreeProvider(MembershipContext.AuthenticatedUser);
var bNodes = DocumentHelper.GetDocuments<Blog>().Where(p => p.ListingHideLinkToPage);
var pageTemplateInfo = PageTemplateInfoProvider.GetPageTemplateInfo("OneColumn");
var pageTemplateID = pageTemplateInfo.PageTemplateId;
foreach (var b in bNodes)
{
    if (string.IsNullOrEmpty(b.DocumentWebParts))
    {

        // Initialize variables
        string culture = "en-GB";
        string aliasPath = b.NodeAliasPath;
        string widgetName = "HeroBanner";
        string zoneID = "cmsZoneMain";

        // Get document
        TreeNode staticNode = tree.SelectSingleNode(b.DocumentNodeID);

        if (staticNode != null)
        {
            // Get widget
            WidgetInfo insertWidget = WidgetInfoProvider.GetWidgetInfo(widgetName);

            // Get PageInfo of the document
            PageInfo docPageInfo = CMSWebPartPropertiesPage.GetPageInfo(staticNode.NodeAliasPath, staticNode.DocumentPageTemplateID, culture);

            // Get template instance
            PageTemplateInstance templateInstance = CMSPortalManager.GetTemplateInstanceForEditing(docPageInfo);

            // Get page template info
            PageTemplateInfo pti = templateInstance.ParentPageTemplate;

            // Add widget to the page into "Editor Widget Zone" with ID = "ZoneA"
            WebPartInstance newWidget = PortalHelper.AddNewWidget(insertWidget.WidgetID, zoneID, WidgetZoneTypeEnum.Editor, false, templateInstance);

            // Set custom widget properties
            // Set custom widget properties
            newWidget.SetValue("ImageLarge", b.ListingImage);
            newWidget.SetValue("Heading", $"{b.PinTitle.ToUpper()} CRUISES");

            // Save the changes  
            CMSPortalManager.SaveTemplateChanges(docPageInfo, templateInstance, WidgetZoneTypeEnum.Editor, ViewModeEnum.Edit, tree);
        }

        port.ListingHideLinkToPage = false;

        b.NodeTemplateForAllCultures = true;
        b.Update();
        b.Publish();
        updateCounter++;
    }
}

The code above 'seems' to work, nothing errors. But when I then go to the desired page in the CMS the page is not populated with the widget at all.

Is there something I'm missing? Or is there an alternative way to achieve this?

Thanks

Recent Answers


Brenden Kehren answered on December 4, 2019 15:49

Can you check in the database to see if the widget is added to the page in the cms_document table? Also, are you using versioning and workflow? If so, you may need to:

  • check to see if the page is checked out
  • check it in
  • check it back out under your user
  • perform the your update
  • check the page back in
  • publish the page
0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 15, 2020 21:31

Ryan did you ever figure this out, I am trying to get this to work with some custom code I am writing and I am having the same issue as you.

0 votesVote for this answer Mark as a Correct answer

Joseph Pickering answered on June 19, 2020 17:21

I'm currently facing the same issue too. Did you manage to resolve this issue? @Ryan Anthoney

0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 19, 2020 19:56

Joe, I finally figured out a solution.

First I set up a page that has exactly the layout I want in Kentico admin ui with the webparts and widgets. I then went in and to the CMS_Document table and pulled the xml for both DocumentContent and DocumentWebParts. I deserialized both xml to objects and managed the data by matching up guids which I first chagne to a random guid. The guids need to match in both xml strings. The layout is in documentwebparts and the content is then in documentcontent xml. I then added my content into documentcontent xml, serialized it back to a string and put into my page treenode.

TreeNode tnSample = DocumentHelper.GetDocuments()
                .Path(path)
                .OnCurrentSite()
                .FirstOrDefault();
page = TreeNode.New(<<pagetype here>>);
page.SetValue("DocumentContent", contentXml);
page.SetValue("DocumentWebParts", resultXml);
page.Insert(tnSample);
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.