K10 - Add Widget to New Page Created.

William Reed asked on June 15, 2020 20:45

I am pulling data from a json feed through a scheduled task that will look at the feed and create/update/delete pages (news feed). I am adding the feed per article guid into a created property on the page type. Basically if the guid is there then do not create the page and look if it needs to be updated. I have the pages/documents being created correctly. I am using a for each through all the articles from the feed and if it meets the condition of not existing I create a new treenode. I set values to the treenode that are needed. This creates the page in not published which is what I want. I then go to create the widget (which is existing) object because I want to add it but I cannot for the life of me get the widget to add to the page. The code does not error, I just have an empty page.

I am using the following..tthis is old code but man I cannot easily find the code or anything sample related to adding an existing widget to a page through the API and add content to the widget.

tree = new TreeProvider(MembershipContext.AuthenticatedUser);

// Initialize variables
string culture = "en-US";
string widgetName = "editabletext";
string zoneID = "phWidgetZone";

// Get document
TreeNode staticNode = tree.SelectSingleNode(page.NodeID);

if (staticNode != null)
{
    // Get widget
    WidgetInfo insertWidget = WidgetInfoProvider.GetWidgetInfo(widgetName);
    WebPartInfo insertWebPart = WebPartInfoProvider.GetWebPartInfo(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.AddNewWebPart(insertWebPart.WebPartID, zoneID, false, 0, 0, templateInstance);

    // Set custom widget properties
    newWidget.SetValue("Title", "Sample title");

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

Correct Answer

Dmitry Bastron answered on June 16, 2020 17:50

Content is stored in the same XML as a widget structure. In CMS_Document table find your example document with these widgets filled with content and look in the column DocumentWebParts, you will see something like this:

<page>
    <webpartzone id="widgetZone" v="1" widgetzonetype="editor">
        <properties>
            <property name="containerhideonsubpages">False</property>
            <property name="disableviewstate">False</property>
            <property name="hideonsubpages">False</property>
            <property name="timezonetype">inherit</property>
            <property name="useupdatepanel">False</property>
            <property name="visible">True</property>
        </properties>
        <webpart controlid="DancingGoat_EditableTextWithBackground" guid="99fdcdf5-1aec-49f3-ae2f-2315b21774ed" iswidget="true" type="DancingGoat-EditableTextWithBackground" v="1">
            <property name="checkpermissions">False</property>
            <property name="container">DancingGoat-HomePageBanner</property>
            <property name="containercssclass"></property>
            <property name="containercustomcontent"></property>
            <property name="containertitle"></property>
            <property name="contentafter"></property>
            <property name="contentbefore"></property>
            <property name="controlid">DancingGoat_EditableTextWithBackground</property>
            <property name="customtimezone"></property>
            <property name="defaulttext">&lt;h2 class="banner-heading"&gt;ROASTING PREMIUM COFFEE&lt;/h2&gt;  &lt;p class="banner-text"&gt;Discover the fascinating world of Dancing Goat high-quality coffee and you&amp;#39;ll never miss a single coffee break.&lt;/p&gt; </property>
            <property name="dialogheight"></property>
            <property name="dialogwidth"></property>
            <property name="disablemacros">False</property>
            <property name="disableviewstate">False</property>
            <property name="displaytoroles"></property>
            <property name="enableoutputfilter">False</property>
            <property name="encodetext">False</property>
            <property name="hideonsubpages">False</property>
            <property name="htmlareatoolbar"></property>
            <property name="htmlareatoolbarlocation">In</property>
            <property name="htmleditorcssstylesheet"></property>
            <property name="imageautoresize"></property>
            <property name="instanceguid">99fdcdf5-1aec-49f3-ae2f-2315b21774ed</property>
            <property name="iswidget">True</property>
            <property name="maxlength"></property>
            <property name="minlength"></property>
            <property name="outputconverttablestodivs"></property>
            <property name="outputfixattributes">True</property>
            <property name="outputfixhtml5">True</property>
            <property name="outputfixjavascript">True</property>
            <property name="outputfixlowercase">True</property>
            <property name="outputfixselfclose">True</property>
            <property name="outputresolveurls">True</property>
            <property name="pathtoimage">~/DancingGoat/media/Homepage/banner-default.jpg?ext=.jpg</property>
            <property name="regiontitle"></property>
            <property name="regiontype">HtmlEditor</property>
            <property name="resolvedynamiccontrols">True</property>
            <property name="selectonlypublished">False</property>
            <property name="showfordocumenttypes"></property>
            <property name="timezonetype"></property>
            <property name="useparentcontent">False</property>
            <property name="useupdatepanel">False</property>
            <property name="visible">True</property>
            <property name="webparttitle"></property>
            <property name="webparttype">DancingGoat-EditableTextWithBackground</property>
            <property name="wordwrap">True</property>
        </webpart>
    </webpartzone>
</page>

This is an example of EditableTextWithBackground widget, where defaulttext - is a text content editor put in the widget and pathtoimage - is the image he selected in widget.

In your case you need to analyze what are the "content" related fields in your widgets so to speak and populate these fields. Also note that GUIDs should be generated carefully to avoid duplications where necessary.

1 votesVote for this answer Unmark Correct answer

Recent Answers


Trevor Fayas answered on June 15, 2020 21:04

You may need to save the widget to the Template Instance before calling SaveTemplateChanges. I've always modified the DocumentContent xml using the API and then saved it back to it, but there is probably a better way that you are close to executing.

I would inspect both the docPageInfo and templateInstance and see if they have any refernece to your widget, i'm guessing that's the missing part.

0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 15, 2020 21:26 (last edited on June 15, 2020 21:36)

I did and I see that it has the page, and that it gets the widget (which I was using web part up there but now I am using widget) but I have the same issues as this question - https://devnet.kentico.com/questions/programmatically-add-widget-to-page basically nothing happens.

I am checking if it's checked out before doing the widget add, if it isn't I check it out. Then check back in after the code. I can't find anything about saving the widget to the template instance.

Also referred to this - https://devnet.kentico.com/forums/f68/t32143/add-widget-to-page-programtically which has answer from kentico_mirekr and he says editor widget versus user widget, how do I know which it is?

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on June 15, 2020 21:38

It's possible it's trying to add a widget to the page template, not to the page itself. You can add "widgets" to a page template (which when you create a NEW page, it will add that widget in there, but won't effect existing pages).

Does your page template itself have the widget being added by your API?

Otherwise like i said, so far i've only had success with building the DocumentWebPart's via xml and saving it to the document value.

Saving pages can be complex with things like Publish/Unpublish/Versions, checking/checkout, etc.

I would start by changing a document field (not widget) and make sure you have your document saving correct, then move onto trying to add the DocumentWebParts.

1 votesVote for this answer Mark as a Correct answer

William Reed answered on June 15, 2020 21:45

So I originally had tried to add xml myself by forming it. I could add content but that was not a widget within the web part, when I tried to do that it wouldn't work. I have the xml so do you just add the xml to the treenode? I assume my guid shouldn't be unique but whatever the guid is for my widget? I am pretty sure I tried this but I have pulled out a lot of hair trying to do this :)

page.SetValue("DocumentWebParts", $"<content><webpart id=\"editabletext;{Guid.NewGuid().ToString()}\"><![CDATA[{article.currentArticle.description}]]></webpart></content>");
0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 15, 2020 22:33

So I used your way and basically I looked up a successful page did getvalue on DocumentWebParts and got the value, used that on the new page and did SetValue and it added my widgets! But I am missing the content in the widgets, is there a second step to add that? I would expect getvalue on an existing page with widgets that have content would give me the content too?

0 votesVote for this answer Mark as a Correct answer

Dmitry Bastron answered on June 16, 2020 10:15

Hi William,

You can try it the other way. Do you really need here widget at all to deal with this complicated insert logic? Instead, you can add it to the page template as a web part so it will always be there. Display or other appearance logic can be decided via Visible field of the web part or in the web part code.

0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 16, 2020 17:17

The widget and template were all created by the vendor and I am trying to just reuse them. I basically am pulling content from a feed that is where our marketing department is using to stage content and retrieve content. I want to pull that content and bring it into kentico as a page/document. Which means I need to use the widgets because that is the layout they are looking for. So are you saying I create a new template that then has the widgets as webparts built into the template instead of trying to create it on the fly?

0 votesVote for this answer Mark as a Correct answer

Dmitry Bastron answered on June 16, 2020 17:31

So are you saying I create a new template that then has the widgets as webparts built into the template instead of trying to create it on the fly?

Yes, I'd explore that route at least. Please note it will only work if the widget (web part) is built with the logic to fetch the content but doesn't store the content itself, e.g. widget references content item (say with title, description and image) from the CMS tree but doesn't store these fields. Because the template will be the same for multiple pages.

Otherwise, like Trevor mentioned, I'm afraid combining XML and putting it in DocumentWebParts field would be sensible option. Or try redeveloping these bits to support more structured content rather than storing it in widgets.

0 votesVote for this answer Mark as a Correct answer

William Reed answered on June 16, 2020 17:35 (last edited on June 16, 2020 17:42)

Ok I don't mind the XML route, which I did and populated the documentwebparts but that only does the structure of the widgets which show up in my page after creation. How do I get content into the widgets if I add the xml to documentwebparts?

EDIT I am looking at this after I update documentwebparts https://docs.kentico.com/api10/development/web-parts#Webparts-Updatingawebpart

0 votesVote for this answer Mark as a Correct answer

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