Seamless Media Migration to XM Cloud: A Step-by-Step Guide from Sitecore XP 10.4 and Content Hub Integration - Part 2

This article covers how to migrate the media library content from Sitecore XP to Sitecore Content Hub. 

In the previous article, we have seen how to connect Sitecore XP with Sitecore Content Hub for accessing the assets from DAM.

Steps to migrate the content from Sitecore XP:

  • Create an Excel file import with all the media library items with the required fields that need to be imported in Sitecore Content Hub as Assets
  • Fields to be added in the Excel sheet for the Asset creation in Sitecore Content Hub are provided below.
    • ItemName
    • SitecoreItemId (SitecoreItemIdentifier)
    • Alt (Title)
    • FinalLifeCycleStatusToAsset (Approved)
    • ContentRepositoryToAsset (Standard)
    • LocationToAsset (For multilingual Content)

  • We will create a PowerShell script that will loop through the media library and create an Excel sheet. Once the Excel is created, we will import the content to Sitecore Content Hub.
    #Domain url to public else Content Hub will not be able to access the images from Excel.
    $donainNameUrl = 'https://publicsitedomain/'

    #Set the assest to Approved status to see the assets in the Approved Assest tab for adding in sitecore
    $lifeCycleStatus = 'M.Final.LifeCycle.Status.Approved'
    $ContentRepository = 'M.Content.Repository.Standard'
    $Localization = 'M.Localization.'
    $mediaItems = @()
    #get all the media library items
    $allMediaItems = Get-ChildItem -Path 'master:/sitecore/media library' -Recurse |
    Where-Object { $_.TemplateName -ne "Media folder" }

    if ($allMediaItems -ne $null) {
        $allMediaItems | ForEach-Object {
            $item = $_
            #looping through all the language version, incase version created for media items
            $_.Languages | ForEach-Object {
                   
                $languageBasedMediaItem = Get-Item -Path "master" -ID $item.ID -Language $_.Name
                if ($languageBasedMediaItem -ne $null) {
                    #we need to point the public domain name from where we can access the images ($donainNameUrl),
                    #as Content Hub needs to access the public URL and do import the images as assets.
                    #if we use localhost site url/-/media/abc.jpg , this url will not be accessible by the
                    #Content hub while doing excel import.
                    $url = [Sitecore.Resources.Media.MediaManager]::GetMediaUrl($languageBasedMediaItem) -replace '/sitecore/shell/', $donainNameUrl
                   
                    #Get the file extension from the media item
                    $extension = $languageBasedMediaItem["Extension"]
                    $itemName = $languageBasedMediaItem.Name

                    #Get the item Name
                    if ($itemName.EndsWith(" " + $extension)) {
                        $itemName = $itemName.Substring(0, $itemName.Length - $extension.Length - 1)
                    }

                    #Get Alt text in case of image, if other files types then this alt will be empty
                    #in that case have use title or itemname
                    $title = $languageBasedMediaItem["Alt"]
                    if ($title -eq '' -or $title -eq $null) {
                        $title = $itemName -replace '-', ' '
                    }
                    if ($title.EndsWith(" " + $extension)) {
                        $title = $title.Substring(0, $title.Length - $extension.Length - 1)
                    }

                    #get the file extension
                    if ($extension -ne '' -and $extension -ne $null) {
                        $fileName = $itemName + "." + $extension
                    }
                    else {
                        $fileName = $itemName
                    }

                    #create the object for exporting to csv
                    $mediaItemDetails = [pscustomobject]@{
                           
                        SitecoreItemIdentifier      = $languageBasedMediaItem.ID
                        ItemName                    = $itemName
                        FileName                    = $fileName
                        Title                       = $title
                        File                        = $url
                        Updated                     = $languageBasedMediaItem.Updated
                        FinalLifeCycleStatusToAsset = $lifeCycleStatus
                        ContentRepositoryToAsset    = $ContentRepository
                        LocalizationToAsset         = $Localization + $languageBasedMediaItem.Language
                    }
                    if ($mediaItemDetails -ne $null) {
                        $mediaItems += $mediaItemDetails
                    }
                }
            }          
           
        }
        #export the media items to excel file
        $mediaItems |
        Export-Csv -Path "C:\nelson\latest_published_items.xlsx" -NoTypeInformation -Encoding UTF8
        Write-Host "Export completed successfully."  
    }
  • The above script will generate the media library item details with image URL in the Excel file, which will now be imported into Content Hub.
  • Open Excel and update the sheet name from Sheet 1 to M.Asset
  • But before importing the Excel to Sitecore Content Hub, we need to add the SitecoreItemIdentifier field in the Content Hub for the M.Asset schema.

  • This field will be useful in the later stages, like finding all the media items referred by Sitecore items in the fields like Image, RTE, and General Link. And update these field images with the public link from the Content hub for that particular SitecoreItemIdentifier.
  • To add a SitecoreItemIdentifier field in Sitecore Content Hub, go to Manage -- Schema -- M.Asset
Add a New Group named "Sitecore" and click New Member and select PROPERTY, and then select String Type like below.





  • Create a Public link automatically once assets get approved. This is important as we are going to import a lot of media content from Sitecore XP to Sitecore Content Hub, so it is necessary to have a public link created automatically once the asset's final life cycle status is set to approved, ie, M.Final.LifeCycle.Status.Approved
  • Steps to create a public link automatically on asset status changes to approved.
    • Create a Script
      • Go to manage and click Script, add the below script, and build and save it.
      • Once done, enable the Script


      • using System.Linq;
        using System.Threading.Tasks;

        var assetId = Context.TargetId;

        // Check if public links don't exist yet
        var query = Query.CreateQuery(entities => from e in entities
          where e.DefinitionName == "M.PublicLink"
          && e.Parent("AssetToPublicLink") == assetId.Value
          && e.Property("Resource") == "downloadOriginal"
          && e.Property("IsDisabled") == false
          select e);
        query.Take = 1;

        var result = await MClient.Querying.QueryIdsAsync(query);
        if (result.TotalNumberOfResults > 0)
        {
          MClient.Logger.Info("Public links already exist for asset with id '" + assetId + "'");
          return;
        }

        // Create public links
        await CreateForRendition("downloadOriginal", assetId.Value);
        MClient.Logger.Info("Created public link 'downloadOriginal' for asset with id '" + assetId + "'");

        async Task CreateForRendition(string rendition, long assetId)
        {
          var publicLink = await MClient.EntityFactory.CreateAsync("M.PublicLink");

          if (publicLink.CanDoLazyLoading())
          {
            await publicLink.LoadMembersAsync(new PropertyLoadOption("Resource"), new RelationLoadOption("AssetToPublicLink"));
          }

          publicLink.SetPropertyValue("Resource", rendition);

          var relation = publicLink.GetRelation<IChildToManyParentsRelation>("AssetToPublicLink");
          if (relation == null)
          {
            MClient.Logger.Error("Unable to create public link: no AssetToPublicLink relation found.");
            return;
          }

          relation.Parents.Add(assetId);

          await MClient.Entities.SaveAsync(publicLink);
        }
    • Create an Action
      • Once the Script is created, let's create the Action for creating the public links.




    • Create Trigger
      • Finally, create the trigger event to create the asset public link.
        Create a Trigger with the Objective set to Entity Creation and Entity Modification.
        Execution Type to In Progress
      • Also, update the condition with the M.Asset definition and set the condition for Final Life Cycle Status to Approved
      • Go to the Action tab and set the post actions to execute the script we have created in "Create a Script" step  DAMSitecorePublicLinks








        Let's import the Media library Excel exported from Sitecore using PowerShell.

      • Go to Sitecore Content Hub and click on Create Menu. Once the page loads, click on the Add button. This will provide 2 options from there, select Import Excel.
      • Upload the Excel sheet; this will take some time to process all the images into Sitecore Content Hub. Once it is done, we can see all our media items created and will be available in the Assets menu. And also, the public link would be created for every asset uploaded from Excel.



Let's learn and grow together, happy programming 😊


Comments

Popular posts from this blog

Sitecore Upgrade from 8.1 XP to 10.4 XM Scaled - Part 1

Custom Item Url and resolving the item in Sitecore - Buckets

Fixing Sitecore Buckets folder path - Items created after 12 AM server time zone