In previous posts, I shared my journey with Sitecore Data Exchange Framework and using Merlin to migrate your site to Sitecore. Learning how to use Merlin was only one part of migrating a site. In this post, I’ll share my powershell script to pull in data from Merlin and populate your content tree. I’ll continue to use the blogs.perficient.com site to show some examples.
Prepare Sitecore for Import
Before we jump into populating our content tree, we do need to prepare Sitecore for the incoming data. You will need to create you datasource template first. This gives us the id of the template and the names of the fields that we will need to update the import script and map our fields. In this example, I used the default SXA Page template. I added _OpenGraphMetadata, _TwitterMetadata, and _Navigable as additional base templates. I did not add all the necessary fields for an actual blog article (date, author, etc).
I also created a simple partial design to display the title and content fields.
I added the partial to my default page design and assigned the page template to use the default page design.
At this point, you can continue testing the import. But you should be sure to fully build out and test your feature in Sitecore before running the final import.
Run Merlin
Now that we have our items in Sitecore, we can update our Merlin scripts and set the proper values for sitecore_root_path and sitecore_template_id.
Refer to my previous article for details on how to install, configure and run merlin.
Update Import Script
The import script contains a library of helper functions to make importing content fast and easy. But we still need to write some custom code per project and per section of the site.
In our example, we start by importing categories then importing the blogs. Merlin gave each category a GUID. I’ll create the categories in Sitecore with the same GUID value by using the ‘-ForceId’ property of the ‘New-Item’ command. When I import the blogs, I can simply join the category array from Merlin with a vertical bar ‘|’ to store in Sitecore. Creating mappings is fast and easy thanks to my custom Update-SitecoreItem function.
$updates = @{} $updates.Add("MetaDescription", $data.meta_description) $updates.Add("OpenGraphTitle", $data.title) $updates.Add("OpenGraphDescription", $data.meta_og_description) $updates.Add("TwitterTitle", $data.title) $updates.Add("Title", $data.title) $updates.Add("Content", $data.content.value) $updates.Add("NavigationTitle", $data.title) $updates.Add("__Semantics", $data.categories -join "|") Update-SitecoreItem $item $updates
Run Import Script
The helper functions do a nice job of telling you what is happening. Be sure to add some of your own logging into your script. You can see when existing items are found, when a new item is created, and when fields and items are updated
[I] Iterating Source Data - Categories [I] Importing category Accessibility [A] Created new item {F47D9F1B-DC4F-31FD-B896-3FA00FE4D304} - accessibility [I] Updating Item {F47D9F1B-DC4F-31FD-B896-3FA00FE4D304} - accessibility [U] Field Name 'Title' Current Value: 'accessibility' New Value: 'Accessibility' [I] Change Detected: True Item modified True [I] Importing category Quality Assurance [I] Found existing item {AB387FC1-CDF3-3BEE-8A1B-FC0A61BB7226} - quality-assurance [I] Updating Item {AB387FC1-CDF3-3BEE-8A1B-FC0A61BB7226} - quality-assurance [-] Field Name 'Title' Current Value: 'Quality Assurance' New Value: 'Quality Assurance' [I] Change Detected: False Item modified False [I] Publishing {78389634-922F-45A1-8D1D-BC772D43F28C} - /sitecore/content/ESTest/Prft/Data/Categories and children [I] Updating sitecore_master_index for {78389634-922F-45A1-8D1D-BC772D43F28C} - /sitecore/content/ESTest/Prft/Data/Categories [I] Updating sitecore_web_index for {78389634-922F-45A1-8D1D-BC772D43F28C} - /sitecore/content/ESTest/Prft/Data/Categories [I] Iterating Source Data - Blogs [I] Importing blog /2023/05/23/the-dialogue-element-modals-made-simple/ [I] Found existing item {B0AAFF76-542B-4CFA-934B-F4B9592D1CF1} - the-dialogue-element-modals-made-simple [I] Updating Item {B0AAFF76-542B-4CFA-934B-F4B9592D1CF1} - the-dialogue-element-modals-made-simple [-] Field Name 'MetaDescription' Current Value: 'The new dialogue element makes modals si...' New Value: 'The new dialogue element makes modals si...' [-] Field Name 'OpenGraphImageUrl' Current Value: 'https://blogs.perficient.com/files/Group...' New Value: 'https://blogs.perficient.com/files/Group...' [-] Field Name 'OpenGraphTitle' Current Value: 'The Dialogue Element: Modals Made Simple' New Value: 'The Dialogue Element: Modals Made Simple' [-] Field Name 'NavigationTitle' Current Value: 'The Dialogue Element: Modals Made Simple' New Value: 'The Dialogue Element: Modals Made Simple' [-] Field Name 'OpenGraphType' Current Value: 'article' New Value: 'article' [-] Field Name 'TwitterTitle' Current Value: 'The Dialogue Element: Modals Made Simple' New Value: 'The Dialogue Element: Modals Made Simple' [-] Field Name 'Title' Current Value: 'The Dialogue Element: Modals Made Simple' New Value: 'The Dialogue Element: Modals Made Simple' [-] Field Name '__Semantics' Current Value: 'f47d9f1b-dc4f-31fd-b896-3fa00fe4d304' New Value: 'f47d9f1b-dc4f-31fd-b896-3fa00fe4d304' [-] Field Name 'Content' Current Value: '<div id="bsf_rt_marker"><h2>Introduction...' New Value: '<div id="bsf_rt_marker"><h2>Introduction...' [-] Field Name 'OpenGraphSiteName' Current Value: 'Perficient Blogs' New Value: 'Perficient Blogs' [-] Field Name 'OpenGraphDescription' Current Value: 'The new dialogue element makes modals si...' New Value: 'The new dialogue element makes modals si...' [-] Field Name 'TwitterImage' Current Value: '' New Value: '' [I] Change Detected: False Item modified False [I] Importing blog /2023/05/16/getting-to-know-sitecore-search-part-4/ [I] Found existing item {9B894ED8-4BEE-45A2-B44E-579E32103140} - 2023 [I] Found existing item {3E82F04F-F575-420D-8C97-94C9F8023AF0} - 05 [I] Found existing item {BD12E2C6-51E6-47CC-8BA2-421DBE443C48} - 16 [A] Created new item {CF6D722A-BA14-4A28-AE2B-7D7B81FBCD3A} - getting-to-know-sitecore-search-part-4 [I] Updating Item {CF6D722A-BA14-4A28-AE2B-7D7B81FBCD3A} - getting-to-know-sitecore-search-part-4 [U] Field Name 'MetaDescription' Current Value: '' New Value: 'Dig into the weeds of managing your sear...' [U] Field Name 'OpenGraphImageUrl' Current Value: '' New Value: 'https://blogs.perficient.com/files/fores...' [U] Field Name 'OpenGraphTitle' Current Value: '' New Value: 'Getting to know Sitecore Search – Part 4' [U] Field Name 'NavigationTitle' Current Value: 'getting-to-know-sitecore-search-part-4' New Value: 'Getting to know Sitecore Search – Part 4' [U] Field Name 'OpenGraphType' Current Value: '' New Value: 'article' [U] Field Name 'TwitterTitle' Current Value: '' New Value: 'Getting to know Sitecore Search – Part 4' [U] Field Name 'Title' Current Value: 'getting-to-know-sitecore-search-part-4' New Value: 'Getting to know Sitecore Search – Part 4' [U] Field Name '__Semantics' Current Value: '' New Value: '205dd6d7-887c-3501-b20a-3a2137437a47|00b...' [U] Field Name 'Content' Current Value: '' New Value: '<div id="bsf_rt_marker"><p>Welcome back ...' [U] Field Name 'OpenGraphSiteName' Current Value: '' New Value: 'Perficient Blogs' [U] Field Name 'OpenGraphDescription' Current Value: '' New Value: 'Dig into the weeds of managing your sear...' [-] Field Name 'TwitterImage' Current Value: '' New Value: '' [I] Change Detected: True Item modified True [I] Publishing {413FD181-C662-4FC4-BC58-7F3447440FCF} - /sitecore/content/ESTest/Prft/Home/Blogs and children [I] Updating sitecore_master_index for {413FD181-C662-4FC4-BC58-7F3447440FCF} - /sitecore/content/ESTest/Prft/Home/Blogs [I] Updating sitecore_web_index for {413FD181-C662-4FC4-BC58-7F3447440FCF} - /sitecore/content/ESTest/Prft/Home/Blogs
The script worked perfectly! You can see my content tree populated with blog articles. The helper functions create any missing folder or items between the root and the actual item.
Linking to categories worked correctly. You can see the Sitecore category is correctly linked to three imported blogs.
My templates and page designs are configured correctly. You can see the title and content fields displayed on a basic page.
This is the same title and content from the live site.
Now, it is clear that my imported content does not look anything like the live site. Remember, I did not do a full site build out. We are missing a theme, styles, layout and many of the required fields for a blog article.
Conclusion
I’m really pleased how this process and script turned out! I actually had FUN doing a content import! In a real world scenario, you would be able to migrate a large chunk of an existing site quite quickly. You wouldn’t have to create the site structure nor enter basic content like meta description, title, og:title, twitter:title, breadcrumb navigation title, tags, etc. You could go any number of steps further with the script to break content into components to populate multiple datasources and add renderings to a page instead of using the page.content field as I’ve done here.
You can find my full powershell script as well as the merlin configurations and output on my github https://github.com/ericsanner/SitecoreMerlinImporter. Let me know if you find it useful or if you have any suggestions on things I could add based on an import you’ve done in the past.
Your detailed guide on using PowerShell to populate the content tree with Merlin data is incredibly insightful! The step-by-step walkthrough and custom script make the import process look seamless. Your expertise shines through in simplifying complex tasks, and the results are impressive. Thank you for sharing the GitHub repository as well – it’s a valuable resource for anyone looking to streamline their content migration. Your passion and practical approach truly make content importing an enjoyable task. Looking forward to exploring your script for our next project!
Thank you for this nice comment! I’d love to hear from you again if you use this script and find it useful. You can always connect with me here or on linkedin.