3

Asked this on the forums as well, but no luck as of yet. What I need to do is set the HTML content of each content block on a given page. It seems that I can set the html value okay, but saving it does not update the actual page.

I'm wondering if it's because there needs to be some sort of save call on the control. There doesn't seem to be any methods available for such an action.

foreach (var c in duplicated.Page.Controls)
{
    // go through the properties, se the ID to grab the right text
    foreach (var p in c.Properties)
    {
        if (p.Name == "ID")
        {
            var content = pageContent.Where(content_pair => content_pair.Key == p.Value).SingleOrDefault();
            var control = pageManager.LoadControl(c);
            if (control is ContentBlock)
            {
                var contentBlock = pageManager.LoadControl(c) as ContentBlock;
                contentBlock.Html = content.Value;
            }
        }
    }
}
pageManager.SaveChanges(); */

WorkflowManager.MessageWorkflow(duplicated.Id, typeof(PageNode), null, "Publish", false, bag);
agmcleod
  • 13,321
  • 13
  • 57
  • 96

1 Answers1

4

The following code may help you achieve what you need.
It will first get the page by its title (I am looking for a page by the title "duplicated" as it's implied by your code).
It generates a new draft of the current page, then go over its controls.
Controls which are detected as content blocks are then iterated in a foreach loop.
As written in the comment inside the foreach loop, you may detect controls by their explicit ID (by the property named "ID") or by their related shared content block (by the property named "SharedContentID") or any other condition (or ignore this condition altogether, which would result in updating all the controls n the page.
Once we have a control to update at hand, you can set its new value depending on the localization settings of your project.
After that the draft is saved and published and optionally a new version is created for it.

PageManager pageManager = PageManager.GetManager();
VersionManager vmanager = VersionManager.GetManager();
PageNode duplicated = pageManager.GetPageNodes().FirstOrDefault(p => p.Title == "duplicate");

if (duplicated != null)
{
    var draft = pageManager.EditPage(duplicated.Page.Id, true);
    string contentBlockTypeName = typeof(ContentBlock).FullName;

    PageDraftControl[] contentBlocks = draft.Controls.Where(contentBlock => contentBlock.ObjectType == contentBlockTypeName).ToArray();
    foreach (PageDraftControl contentBlock in contentBlocks)
    {
        Guid contentBlockId = contentBlock.Id;
        //User "SharedContentID" if you are looking up controls which are linked to a shared content block of a specific ID.
        //If you you are trying to locate a specific control by its own ID, use the explicit "ID" property instead of "SharedCotentID"
        if (contentBlock.Properties.Where(prop => prop.Name == "SharedContentID" && prop.Value.ToString() == contentItemIdstr).FirstOrDefault() != null)
        {
            ControlProperty htmlProperty = contentBlock.Properties.Where(prop => prop.Control.Id == contentBlockId && prop.Name == "Html").FirstOrDefault();
            if (htmlProperty != null)
            {
                if (AppSettings.CurrentSettings.Multilingual)
                {
                    htmlProperty.GetString("MultilingualValue").SetString(CultureInfo.CurrentUICulture, "New Value");
                }
                else
                {
                htmlProperty.Value = "New Value";
                }
            }
        }
    }
    draft = pageManager.SavePageDraft(draft);
    draft.ParentPage.LockedBy = Guid.Empty;
    pageManager.PublishPageDraft(draft);
    pageManager.DeletePageTempDrafts(draft.ParentPage);

    //Use the 2 next lines to create  a new version of your page, if you wish.
    //Otherwise the content will be updated on the current page version.
    vmanager.CreateVersion(draft, draft.ParentPage.Id, true);
    vmanager.SaveChanges();

    pageManager.SaveChanges();
}

I hope this code helps.

Alon.

alrotem
  • 92
  • 1
  • 7
  • Just working on implementing it now, thanks for your answer. Note that the line `htmlProperty` object for me does not have a `GetString` method. Any ideas as to why? – agmcleod Aug 20 '12 at 12:14
  • @agmcleod, GetString and SetString are extension methods which are stored in the Telerik.Sitefinity.Model.DataExtensions class. Be sure to include: `using Telerik.Sitefinity.Model;` in your source file. – alrotem Aug 20 '12 at 14:54