Create block programmatically

Vote:
 

Hi,

I'm writing a script for data migration. I have a problem when creating the block.

You can create a page with the following code:

            var caAttribute = typeof(TResult).GetCustomAttributes(typeof(ContentTypeAttribute), true).FirstOrDefault() as ContentTypeAttribute;
            if (caAttribute != null)
            {
                Guid pageGuid;
                Guid.TryParse(caAttribute.GUID, out pageGuid);

                if (pageGuid != Guid.Empty)
                {
                    var pageTypeRepository = ServiceLocator.Current.GetInstance();
                    var child = ContentRepository.GetDefault(parentLink, pageTypeRepository.Load(pageGuid).ID);
                    child.PageName = newPageName;
                    ContentRepository.Save(child, SaveAction.Publish, AccessLevel.NoAccess);//todo check AvailablePageTypes attribute - it can block created page
                    return child;
                }
            }

            return null;

How can I get a similar result for the block?

#113868
Nov 28, 2014 17:06
Vote:
 

Use ContentTypeRepository instead and then you need to cast child to IContent in the Save method:

var caAttribute = typeof(TResult).GetCustomAttributes(typeof(ContentTypeAttribute), true).FirstOrDefault() as ContentTypeAttribute;
if (caAttribute != null)
{
    Guid contentGuid;
    Guid.TryParse(caAttribute.GUID, out contentGuid);

    if (contentGuid != Guid.Empty)
    {
        var contentTypeRepository = ServiceLocator.Current.GetInstance<ContentTypeRepository>();
        var child = ContentRepository.GetDefault<TResult>(parentLink, contentTypeRepository.Load(contentGuid).ID);
        child.Name = newPageName;
        ContentRepository.Save((IContent)child, SaveAction.Publish, AccessLevel.NoAccess);//todo check AvailablePageTypes attribute - it can block created page
        return child;
    }
}

return null;

This code will work for both pages and blocks.

#113870
Edited, Nov 28, 2014 20:50
Vote:
 

Btw, why are you parsing the content type guid from the model? GetDefault() should handle that for you. This should be enough:

var child = ContentRepository.GetDefault<TResult>(parentLink);
child.Name = newPageName;
ContentRepository.Save((IContent)child, SaveAction.Publish, AccessLevel.NoAccess);
return child;
#113871
Nov 28, 2014 20:55
Vote:
 

Hi Johan,

I realized where I was wrong because of your answers. Here is the result:

        public static TResult CreateBlockForPage<TResult>(ContentReference pageReference, string newBlockName, 
            SaveAction saveAction = SaveAction.Publish, AccessLevel accessLevel = AccessLevel.NoAccess)
            where TResult : BlockData
        {
            var assetsFolderForPage = ServiceLocator.Current
                .GetInstance<ContentAssetHelper>()
                .GetOrCreateAssetFolder(pageReference);

            var blockInstance = ContentRepository.GetDefault<TResult>(assetsFolderForPage.ContentLink);
            var blockForPage = blockInstance as IContent;
                                  
            blockForPage.Name = newBlockName;

            ContentRepository.Save(blockForPage, saveAction, accessLevel);
            return blockInstance;
        }

Thanks

#113877
Nov 29, 2014 13:55
Vote:
 

Hi all,

Just to tag on the back of this thread.

I am currently trying to achieve the same thing, however, what I am struggling with at the moment is how to set the display options for the block programatically.

Has anyone any advice on this?

Thanks

Adam

#113887
Dec 01, 2014 10:10
GR - Dec 28, 2020 21:56
Have you got the solution?
* 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.