← Back to knowledge base |
  • Xperience by Kentico

How to Migrate Content from Kentico CMS Portal Engine to Xperience by Kentico

In this article, I'll guide you through the process of migrating page content between Kentico CMS Portal Engine and Xperience by Kentico sites.

👋 Introduction

Kentico CMS 12 was the last version of Kentico’s product that included the beloved Portal Engine 🥰 development model. As websites on this version become obsolete, clients are increasingly seeking site redesigns and Kentico upgrades. Currently, the go-to product is Xperience by Kentico (XbyK), which is based on the MVC development model. Unfortunately, there is virtually no compatibility between the old and new versions, meaning that redesigns and upgrades require a complete site rebuild 🧱.

Xperience by Kentico Migration Tooling

One of the first tasks during such a site rebuild is content migration. Kentico has created a set of migration paths and tools: the Xperience by Kentico Migration Toolkit, that may help you migrate your site. These tools handle the complex task of migrating various types of objects using a 1:1 approach from the old Kentico instances to XbyK.

While migrating pages and their data, I had concerns about the outcome from a content modeling perspective. In the Portal Engine, content is stored directly within pages. However, Xperience by Kentico recommends storing content in reusable content items and linking them to pages, which now serve primarily as a medium for displaying content. This is something the Migration tool cannot do. However, it can be very useful when migrating other objects, such as users.

Disclaimer

The migration mentioned below in this article was completed in April 2024, and since then, Kentico has been diligently working on enhancing migration paths and the Migration Toolkit. Be sure to check it out! As of August 2024, I've noticed that there are now options for structured content-only migration in the Portal Engine. However, when I recently revisited the Migration Toolkit to migrate a Kentico 11 site, I encountered a roadblock due to some issues. So, it's important to be patient with the process.

Or, if you prefer a hands-on approach, you can follow along with this article to design your own migration path.

Migration Experience on a Client Project

We went through a site rebuild going from Portal Engine v12 to XbyK. We wanted to migrate 1:1 a subset of site data, like news and their media assets, while also restructuring the site, refreshing the visuals, and modeling content types as recommended by Kentico’s documentation and representatives. We had a clear vision of how things should look in XbyK.

We were recommended to use a migration path that involved KX13 as a proxy. The idea of using KX13 as a proxy felt a bit crazy to me. 

However, we needed to get the job done, so I put effort into that. Regrettably, I gave up after reviewing the process we would have to go through. I became overwhelmed by the complexity. Additionally, since we knew how the result should look in XbyK, we were not sure what the outcome of the migration process would be as it attempts to migrate the site as a whole.

To manage content modeling effectively and maintain full control, I decided to choose my own content migration path. Instead of attempting to migrate the entire site in one go, I opted to create migration scripts only for pages that would require significant effort to migrate manually, such as news pages, of which my client has hundreds 💯.

Final Approach

In the end, we decided to avoid Kentico’s migration tooling. Instead of learning and utilizing dedicated migration tools, we invested our time in creating the XbyK site from scratch the right way and migrating only the data we needed directly from Portal Engine to XbyK, ensuring we had complete control over the end result.

In Portal Engine, I created endpoints exposing the data as JSON. In XbyK, I created controllers that consume these endpoints and store data using the XbyK API. It was quite simple in the end and beneficial, as I was investing my time in learning XbyK properly rather than migration tools.

Further in this article, I will share technical details about the data migration path we took on a simplified example.

Source code is also available as a Github gist.

🧠 Mental Model Behind the Migration

Let’s imagine we have a Portal Engine site. Among other content, we have numerous news pages, each with its content stored under the Form tab.

New page type outline in Page application in Kentico CMS Portal Engine

When migrating to Xperience by Kentico, we aim to have the content fields (Title, Date, and Text) stored in a reusable content item inside the Content Hub. This reusable content item would then be linked to a page inside a Website channel.

Outline of News page content model in Xperience by Kentico

Transferring data from one location to another is efficiently done using JSON serialized data. This process involves two primary steps:

  1. Serialize page data into JSON and expose through a URL in the Portal Engine.
  2. Read and deserialize the JSON data in Xperience by Kentico, then store it to achieve the desired result.

This article will guide you through these steps.

🤖 Serialize Page Data into JSON in Portal Engine

To expose page data as JSON in the Portal Engine, we use a Custom Response Repeater web part. While I've previously written about this web part here, I believe a tailored explanation for our current situation is beneficial.

Import the Custom Response Repeater Web Part

The Custom Response Repeater web part isn't included with Kentico by default, so we need to import ⬇️ it into a project. You can find the import process described here. I've prepared import packages for versions 10 and 12:

With some effort, we can modify the package to be compatible with other Portal Engine-based versions. When we unzip the package, there are metadata files stating the Kentico version that you can modify. There might also be minor updates in the web part implementation as Kentico may have introduced API changes between versions.

Rendering JSON Data

After successfully importing the web part, we can use it to render JSON data. In our Portal Engine site, we go to the Pages application, create a new page with an empty page template, and place the Custom Response Repeater web part inside a web part zone.

Using Custom response repeater web part in Pages application in Kentico CMS Portal Engine

Now, it's time to set up the web part properties and create a transformation. The Custom Response Repeater web part is like any other Repeater web part in Kentico, with the added ability to define Content type and other properties for the page response.

Custom response repeater properties

The final step is to reveal the transformation.

News pages migration - JSON object transformation

Besides the obvious page type fields Title, Date, and Text, we also expose DocumentID and NodeAlias, which are system fields that we will use in the migration script to build unique names and URL slugs. Title and Text fields in the transformation use additional replace methods to render valid JSON string values. Here is the code:

Loading...

After saving the transformation and the web part, we can request the page on the live site and receive a valid JSON response.

News pages JSON output example

Excellent 🎉! We've serialized our news pages data into JSON output and exposed it through a URL. We will use this as input for a migration script that will create pages and reusable content items in our target Xperience by Kentico site.

🫗 Import data in Xperiece by Kentico

As I mentioned earlier, our primary task is to create a migration script. However, before we proceed, we need to ensure a few prerequisites are met. Firstly, we must have an existing parent News page, under which the migrated pages will reside. Also, please note the Page ID value which we will use later in our migration script.

News parent page in Xperience by Kentico outlining its Page ID

Secondly, we need to have prepared content types and models generated in the codebase for the News pages that will be migrated.

Content type for News reusable content item that will be linked to News page:

News item reusable content type definition

Content type for News page:

News page content type definition

📜 The Migration Script

The migration script, which will deserialize the JSON and create pages and reusable content items on our site, will be managed by a controller within our Xperience by Kentico codebase. I recommend running the migration locally to avoid potential timeouts when migrating a large amount of content.

The logic of the migration script is as follows:

  1. Request the URL where our JSON data resides and deserialize it into a list of News, based on a Data Transfer Object model.
  2. Iterate through the list and for each item:
    1. Generate unique code name identifiers for the page and reusable content item.
    2. If a page or a reusable content item with such names already exist (when we repeat the migration), delete them.
    3. Parse incoming data into appropriate data types.
    4. Create a reusable content item.
    5. Obtain a reference to the reusable content type.
    6. Create a page using the reference, attach the page to the parent News page by its Page ID, and assign it a URL slug.

The solution is comprised of three files:

  • NewsDtoModel.cs - This file defines the type for the deserialized News item.
  • NewsMigrationController.cs - This file implements the core migration logic as described above.
  • MigrationHelper.cs - This file contains methods that can be reused across multiple migration scripts.

The NewsDtoModel.cs file

Loading...

The NewsMigrationController.cs file

Loading...

The MigrationHelper.cs file

Loading...

⚙️ Executing the Migration

Once everything is set up, we can run our site and initiate the migration script by making a POST request to the URL http://localhost:<port>/migration/news. Depending on the volume of data being migrated, it may take some time ⏱️. After completion, the page data from our Portal Engine site should be migrated to our Xperience by Kentico site.

Conclusion

I acknowledge that the migration process can be daunting 😅. In this article, I've detailed the approach I adopted for a client's project, using a simplified News pages scenario as an example. Your situation may differ, necessitating adjustments to align with your specific needs. Nonetheless, I hope this article offers a comprehensive insight into the process and code, serving as a valuable guide and source of inspiration for your migration journey. Or you can ask me of course 🙃.

About the author

Milan Lund is a Freelance Web Developer with Kentico Expertise. He specializes in building and maintaining websites in Xperience by Kentico. Milan writes articles based on his project experiences to assist both his future self and other developers.

Find out more
Milan Lund