Try our conversational search powered by Generative AI!

Trouble creating local block programmatically

Vote:
 

Hi,

I'm having troubles creating a local block programmatically to a page. This is a simplified example:

var newPage = _contentRepository.GetDefault(parent).CreateWritableClone();

newPage.Name = "MyName";
newPage.LocalBlock = CreateBlock();

_contentRepository.Save(newPage, SaveAction.Publish, AccessLevel.NoAccess);

private MyBlock CreateBlock()
{
    var block = new MyBlock();
    block.MainBody = new XhtmlString("MyMainBody");
    return block;
}

The above code doesn't work. The MainBody-property for MyBlock always end up empty.

I have managed to find a way which works:

var newPage = _contentRepository.GetDefault(parent).CreateWritableClone();

newPage.Name = "MyName";
newPage.LocalBlock.MainBody = new XhtmlString("MyMainBody");

_contentRepository.Save(newPage, SaveAction.Publish, AccessLevel.NoAccess);

But this way isn't so practical. In my case I have several block properties on several different page types which I want to create programmatically. So it would be alot of duplicated code. Why doesn't the first way work? Is there a way to make it work?

Thanks in advance

Anders

#122246
May 28, 2015 14:43
Vote:
 

Hello Anders

Have you considered an EPiServer intialization module? This should allow you to hook into the LoadedDefaultContent event and set your default properties on your local blocks apppropriately. 

David

#122247
May 28, 2015 15:02
Vote:
 

Thanks for your answer David. It doesn't solve my problem though. Every page I'm creating has unique property values in their blocks so it's not default values. Or am I misunderstanding you?

Anders

#122248
May 28, 2015 15:07
Vote:
 

Hello Anders

I assume your values can be worked out programmatically? If so then the following should/could work:

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class DefaultBlockProperties : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        var contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();
        contentEvents.LoadedDefaultContent += contentEvents_LoadedDefaultContent;
    }

    void contentEvents_LoadedDefaultContent(object sender, ContentEventArgs e)
    {
        if (e.Content is YourPageType || e.Content is SomeOtherPageType) //etc
        {
            //Do your work to populate your default property here
        }
    }


    public void Preload(string[] parameters) { }

    public void Uninitialize(InitializationEngine context) { }
}

You can also implement an interface on the page(s) that have the local block to simplify the access to the block if you want to make things more elegant.

#122249
Edited, May 28, 2015 15:13
Vote:
 

An InitModule is not an option since we need to run our service with different parameters and we also don't want it to run on Application_Start. 

According to the following link, what I want to accomplish doesn't seem possible: http://joelabrahamsson.com/working-programmatically-with-local-blocks-in-episerver-7/

#122251
May 28, 2015 15:27
Vote:
 

Hello Anders

The initialisaton module runs at application start, however the code I supplied sets up a handler to listen out for EPiServer content events, so the code in the contentEvents_LoadedDefaultContent method will ran after a content item has been created.

David

#122254
May 28, 2015 15:54
Vote:
 

Believe me, this wont work in this specific case :) I don't really have time sitting here describing all the requirements so you just have to take my word for it :) But thank you anyway.

I ended up doing something like this instead:

var newPage = _contentRepository.GetDefault<MyPage>(parent).CreateWritableClone();

newPage.Name = "MyName";
var myBlock = CreateBlock();
newPage.LocalBlock.MainBody = myBlock.MainBody;

_contentRepository.Save(newPage, SaveAction.Publish, AccessLevel.NoAccess);

private MyBlock CreateBlock()
{
    var block = new MyBlock();
    block.MainBody = new XhtmlString("MyMainBody");
    return block;
}

The number of code lines in my class increased quite a lot but atleast I still can use external methods for creating the different blocks.

#122256
Edited, May 28, 2015 16:04
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.