Skip to main content

Migration Step – renaming properties and content types

· 2 min read
Nikola Sekiw
Backend developer at Epinova

When working with Optimizely, it's important to handle the renaming of properties and content types carefully to avoid data loss.

Content types with GUIDs

If your content type (such as a block or page) has a GUID specified using the [ContentType(GUID = "...")] attribute, renaming the class is safe and does not require a migration step. Optimizely uses the GUID to track the content type, so changing the class name won't affect the stored data. However, if no GUID is specified, or if you're renaming a property within a content type (since properties don't have GUIDs), you must use a migration step to ensure that existing data is preserved. Here's how you can do that:

Migration Step

If you rename a property or content type programmatically, Optimizely will treat it as a new field, and any data stored under the old name will be lost in the CMS interface.

To preserve existing data, you should implement a MigrationStep. Migration steps are part of the EPiServer.DataAbstraction.Migration namespace. It is a special class where you explicitly tell Optimizely:

  • What the new name is
  • What the old name was

This ensures that the old data is correctly mapped to the new field.

Example: Renaming a property

private void RenameProperty()
{
ContentType("Car")
.Property("Color")
.UsedToBeNamed("CarColor");
}

This tells Optimizely that the property Color on the Car content type was previously named CarColor. This way, any existing data under CarColor will be preserved and accessible under the new name.

Example: Renaming a content type (e.g., block or page)

private void RenameContentType()
{
ContentType("Vehicle")
.UsedToBeNamed("Car");
}

This ensures that the content type previously known as Car is now recognized as Vehicle, and all existing content will be retained.

Switching git user per folder on macOS

· 2 min read
Nikola Sekiw
Backend developer at Epinova

When I push or merge from Rider IDE, my personal email shows up in the commits on Bitbucket. This isn’t ideal for client projects. The reason this happens is because git is configured globally on my machine with my personal email, since I also use GitHub for personal projects and want my private email associated with those.

To avoid this, I configure a local git identity for each client project folder. This way I can keep my personal and professional git activity separate. Here are the steps for setting up a local git user.

Step 1. Navigate to the project folder in your terminal:

cd /path/to/your/project

Step 2. Check the current Git email for this folder:

git config user.email

If nothing is returned, it means the folder is using the global git configuration.

Step 3. Set a new email for this specific project:

git config user.email "myemail@myemail.com"

Step 4. Verify the change:

git config user.email

You should now see the updated email address.

Check your global git configuration

To confirm that your global git user is still set to your personal email:

git config --global user.email

This will show the email configured globally on your machine.

Fixing node version issues

· 2 min read
Nikola Sekiw
Backend developer at Epinova

A quick guide to resolving common Node.js version errors when building a project

When running npm build, you might encounter an error like this:

Error: error:0308010C: digital envelope routines::unsupported

This often indicates a mismatch between your Node.js version and the requirements of the project you're working on. Here's how you can troubleshoot and fix it.

Step 1: Check Your Current Versions

Start by checking which versions of Node.js, npm, and nvm you have installed:

$ nvm -v        # → 0.38.0
$ npm -v # → 10.2.4
$ node -v # → v18.19.1

Step 2: List and Manage Node Versions

Use nvm (Node Version Manager) to list and switch between Node.js versions:

$ nvm list              # Lists all installed Node.js versions
$ nvm install 16.14.0 # Installs the required version
$ nvm use 16.14.0 # Switches to the installed version

Step 3: Clean Up and Reinstall Dependencies

After switching Node versions, it's a good idea to remove existing node_modules and reinstall dependencies to avoid conflicts:

$ rm -rf node_modules   # Removes all installed packages
$ npm install # Reinstalls dependencies
$ npm run develop # Starts the development server

Summary

If you're getting cryptic errors during npm build, it can be due to an incompatible Node.js version. Using nvm to switch to the correct version and reinstalling dependencies often resolves the issue.

Use of virtual and override in methods

· 2 min read
Nikola Sekiw
Backend developer at Epinova

Practical examples of how and why virtual and override can be useful in c#

Virtual method in a base class

A virtual method allows derived classes to extend or modify its behavior. Here’s an example of a base class method that sets up an Excel header:

protected virtual void CreateExcelHeader(ExcelWorksheet ws)
{
ws.Cells[1, 1].Value = Resources.PageName;
//additional setup code
}

Overriding in a derived class

A derived class can override the virtual method to add more specific functionality while still calling the base implementation:

protected override void CreateExcelHeader(ExcelWorksheet ws)
{
base.CreateExcelHeader(ws);
ws.Cells[ws.Dimension?.End.Row ?? 0, ws.Dimension?.End.Column+1 ?? 0].Value = Resources.Unit;
//additional customization
}

Why this is useful

By making CreateExcelHeader virtual, we can extend and personalize its behavior in subclasses. This is especially helpful when different subclasses need slightly different setups.

Before using virtual and override

Previously, the method was not virtual, so additional code had to be written outside the method call:

ExcelWorksheet ws = package.Workbook.Worksheet.Add(Resources.PublishedPages);
CreateExcelHeader(ws);
ws.Cells[] //more code here

After overriding the virtual method

Now, all necessary logic is encapsulated within the overridden method:

ExcelWorksheet ws = package.Workbook.Worksheet.Add(Resources.PublishedPages);
CreateExcelHeader(ws);

This approach is much cleaner and more maintainable. The code that was previously outside the method was tightly coupled with the logic inside CreateExcelHeader, so it makes sense to keep them together. Npw, calling a single method handles everything, making the code easier to read and reuse.