2

We often need to refactor existing pages and blocks due to new requirements. Usually one or more properties are to be replaced by one or more new properties. Existing pages and blocks need to keep on working and it is not uncommon that settings made using the old properties need to affect the settings of the new properties. Creating new pages or blocks to replace existing ones is not an option - unless it can be automated.

Simple example #1: The old Boolean property UseDarkBackgroundColor is replaced by the new string property BackgroundColor. If UseDarkBackgroundColor was set, BackgroundColor should be set to a specific color.

Simple example #2: The old Boolean property IsWide is replaced by the new property IsNarrow (basically flipping name and value). If IsWide was true, IsNarrow should be false and vice versa.

In the past we have solved this by updating the Episerver database using an SQL script. I find this kind of scary and I would therefore like to find a better approach.

The following article gives me some hope: https://world.episerver.com/documentation/developer-guides/CMS/Content/Refactoring-content-type-classes#API

The information under the section "Renaming a content type by API" is easy to understand and when testing it the result was as expected. However, the text under the section "Changing the type for a property" is next to gibberish to me. I don't even know where to start, even after a lot of googling.

Does anybody know of an example that shows how to change the type (and value) of a property in Episerver without an SQL script?

Andvik
  • 119
  • 1
  • 12
  • Did you ever find an example or manage to produce something yourself you can share as an example? Just looking to do something like example #1. Thanks – bytesnz Nov 01 '22 at 00:09
  • No, @bytesnz, sorry. We have a solution, but it's not a pretty one. We have a "Legacy" tab in EPi for old properties that should no longer be used but might still affect the output. UseDarkBackgroundColor was moved to this tab and if BackgroundColor is not set it will still be used. When BackgroundColor is set on all blocks, UseDarkBackgroundColor can be removed. – Andvik Nov 01 '22 at 15:56
  • Cool. Thanks @andvik. I was going to try some SQL hackery to solve mine (store the old values as a _old property, then update the existing value). – bytesnz Nov 02 '22 at 04:12

2 Answers2

4

We never change types for an existing property, but rather we introduce a new property, hide the old one from the UI, and (if applicable) implement a custom getter for the new property so that it uses the old property as "fallback" until an editor has published content with the new property.

Sometimes we migrate the old property value to the new property through some type of batch job, and then delete the old property.

We never manipulate the database directly.

Also check out migration steps, commonly used if you for example need to rename a property: https://www.jondjones.com/learn-episerver-cms/episerver-developers-tutorials/importing-content-into-episerver-programmatically/episerver-migration-steps-explained/

Ted Nyberg
  • 7,001
  • 7
  • 41
  • 72
  • Good suggestions! However, if I recall correctly, property getters and setters are ignored in when editing in Epi (at least when using "all properties" mode). This would confuse editors as what you see in Epi would not match what you see on the "real" page. A bit unclear (as you have to read the referenced article to get it), but I've tried migration steps and they seem to work great for renaming properties. A batch job might be the right way to go. But since I really do not understand what the Epi folks said about changing types in the article, I just hoped that somebody else would. – Andvik Jan 27 '21 at 17:19
0

Just want to add to Ted's answer that you can hide the old property and use an existing value for the new by providing a fallback/default value in the getter:

[ScaffoldColumn(false)]
[Obsolete("BackgroundColor should be used now")]
public virtual bool UseDarkBackgroundColor { get; set; }

public virtual string BackgroundColor
{
    get { return this.GetPropertyValue(block => block.BackgroundColor, UseDarkBackgroundColor ? "Black" : null); }
    set { this.SetPropertyValue(block => block.BackgroundColor, value); }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939