Convert Episerver Blocks!
Content in Episerver CMS is organized using pages and blocks. Pages are instances of page types, and blocks are instances of block types. If you by accident create the wrong page type, or you want to move existing pages to a new and enhanced page type, Episerver provides a feature for converting pages to a different page type.
I have wondered why Episerver has not extended their existing page converting tool, to also handle blocks. Both pages and blocks are content, right? It shouldn't be that hard?
Figuring out how this converting stuff actually works, and why converting blocks obviously is so much different than pages that Episerver stills ignore the 2014 (and very popular) feature request has been on my todo-list for years. This Easter, with the coronavirus situation, one night after the kids fell asleep, I finally decided to investigate how all this works.
Armed with very little hope, but with a beer by my side, I fired up JetBrains dotPeek. I discovered that all the converting stuff is handled in SQL using two stored procedures. First, the properties are mapped in the GUI, and for each property mapping the stored procedure
netConvertPropertyForPageType is called. It is exactly 300 lines, quite well-structured SQL with some nice comments. My initial thought was, that it should be possible to convert this stored procedure to a version for converting blocks. Maybe I could create my very own
netConvertPropertyForBlockType! After finishing reading the stored procedure my impressions were that even though the word «page» is found 112 times in the stored procedure nothing looked page-specific. It all looked content-specific. Promising!
So what happens next? After the properties are converted, the page is converted using the stored procedure
netConvertPageType. This stored procedure only had 40 lines, but actually looked less promising than the first. It seemed to update the database table
tblPage and was working with
PageID and stuff that looked very page-specific. But it turns out
tblPage is just a view for
tblContent, and after reading through the SQL one more time, nothing seemed tied to pages - this should work with blocks too!
To actually convert the blocks I would have to provide a mapping for each property. So I tried to make my own version of the Convert Pages tool. I found Episerver's tool for converting pages inside
CMS.zip located in the
Episerver.CMS.UI folder in the packages folder of an Alloy site. Then I started making some small changes. Listing block types instead of page types, changing some variable names. And before my beer was empty, I was converting blocks!
My unpolished version, including history from the starting point of the tool for converting pages, is available at GitHub.
Just include the files in your solution, and if needed place the provided XML file together with your other language files, or somewhere it will be picked up by Episerver's LocalizationService. Or install the nuget package Gulla.Episerver.ConvertBlocks from nuget.optimizely.com.
This is not thoroughly tested and is just provided as is, as a proof of concept. Use it at your own risk. Maybe Episerver has good reasons for not releasing the block converter themselves? Maybe my code will corrupt your database? Use with caution.
The user interface is the same as for converting pages, but instead of the page selector dialog you will have to enter the ID for the block you want to convert. If you want to convert all blocks of a specific type, just leave the textbox empty and check the checkbox.
My approach will duplicate a lot of code that exists in Episerver. It will use the internal and unsupported API, and could possibly break in a future update. My hope is still that Episerver will fix this themselves - only they can do this the right way.
How hard can it be, guys? Grab a beer (probably non-alcoholic during working hours) and search-replace page type with content type in a few files, modify the validation logic, and create a slightly better user interface than what I did.