Continuing Sitecore development on an already live site can bring about new challenges that did not exist prior to go-live. For example, if a particular component is already being used by content authors, you do not want to introduce changes to said component that would break pre-existing uses of it on various pages.
The Problem
You may end up needing to change an SXA Placeholder Key in which a component is inserted in. This can prove quite difficult to do if a component is used on hundreds of pages on a live site because the presentation details for that inserted component do not get automatically updated when you change the SXA Placeholder Key. You should not go in and manually update the component’s placeholder key to match the newer one. That takes too long, and the component would be hidden on the page until its placeholder is updated. With a large site, this can cause serious issues. The solution to this problem? Using Sitecore PSE to do the work site-wide. Below is a script you can use to do the heavy-lifting:
The Script
$contentPath = "master:/sitecore/content/home" $deviceLayout = Get-LayoutDevice "Default" $useFinalLayout = $True $oldPlaceholderRegEx = "/placeholder-entries-\d{1,}" Write-Host "Looking for Pages under Home..." $items = Get-ChildItem -Path $contentPath -Recurse foreach($item in $items){ $renderings = Get-Rendering -Item $item -Device $deviceLayout -FinalLayout:$useFinalLayout foreach($rendering in $renderings){ if ($rendering.Placeholder -match $oldPlaceholderRegEx){ $dynamicPlaceholderNumber = $Matches.0 -replace '\D+(\d+)','$1' $oldPlaceholder = $rendering.Placeholder $newPlaceholder = $rendering.Placeholder -replace $Matches.0 $newPlaceholder = $newPlaceholder + "/placeholder-1-" + $dynamicPlaceholderNumber $rendering.Placeholder = $rendering.Placeholder -replace $oldPlaceholder, $newPlaceholder Set-Rendering -Item $item -Instance $rendering -FinalLayout:$useFinalLayout Write-Host $rendering.Placeholder } } } Write-Host "Done"
The Trickiness of an SXA Placeholder Key
The tricky part about updating SXA placeholder keys on a particular component’s presentation details is that you do not know the dynamic numbers being used to make that placeholder because they are not universal. For example, Component A can be in SXA placeholder “/placeholder-entries-1” on one page and at “/content/placeholder-entries-2” on another. You need to appropriately grab these different numbers to update the SXA placeholder key appropriately. That is what the above script does.
Walking through the Script
Let’s walk through the script above with an example. This script will loop through all page items found under “/sitecore/content/home”. Let’s suppose Component A on one of these pages lives in placeholder “/trophies/placeholder-entries-4”, and the SXA placeholder key is “placeholder-entries”. We have decided to change the SXA placeholder key to “placeholder”.
The if block inside the foreach loop will check to see if the placeholder contains the old placeholder (“placeholder-entries-“) by using RegEx. Since we have found a match for Component A’s placeholder in the presentation details, we will first retrieve the dynamic number at the end of the placeholder, 4.
We will then begin constructing the new placeholder key for Component A. We will use the -replace RegEx command to get rid of the “placeholder-entries-4” substring in the “/trophies/placeholder-entries-4” placeholder key. We will then replace it with the new SXA placeholder key to generate “/trophies/placeholder-4”. After that, we simply update the rendering on the Final Layout of the page.
What about Nested Components underneath the new SXA Placeholder Key?
Great news! The script takes care of that! Using the example above, you may have components inserted at “/trophies/placeholder-entries-4/my-other-placeholder-1”. The script will exclusively rip out the old SXA Placeholder Key you are trying to replace and generate “/trophies/placeholder-4/my-other-placeholder-1”.
How do you update this script for your SXA Placeholder Keys?
Update the content path to match the parent item you want to recurse through. Simply replace the $oldPlaceholderRegEx variable value with your SXA Placeholder Key and update the line assigning the new SXA Placeholder Key to the $newPlaceholder. For example, if your old SXA Placeholder Key was “my-items” and your new SXA Placeholder Key was “my-items-placeholder”, you would update these three lines in the script as highlighted below:
$contentPath = "master:/sitecore/content/home" $deviceLayout = Get-LayoutDevice "Default" $useFinalLayout = $True $oldPlaceholderRegEx = "/my-items-\d{1,}" Write-Host "Looking for Pages under Home..." $items = Get-ChildItem -Path $contentPath -Recurse foreach($item in $items){ $renderings = Get-Rendering -Item $item -Device $deviceLayout -FinalLayout:$useFinalLayout foreach($rendering in $renderings){ if ($rendering.Placeholder -match $oldPlaceholderRegEx){ $dynamicPlaceholderNumber = $Matches.0 -replace '\D+(\d+)','$1' $oldPlaceholder = $rendering.Placeholder $newPlaceholder = $rendering.Placeholder -replace $Matches.0 $newPlaceholder = $newPlaceholder + "/my-items-placeholder-1-" + $dynamicPlaceholderNumber $rendering.Placeholder = $rendering.Placeholder -replace $oldPlaceholder, $newPlaceholder Set-Rendering -Item $item -Instance $rendering -FinalLayout:$useFinalLayout Write-Host $rendering.Placeholder } } } Write-Host "Done"
Conclusion
Updating SXA placeholders after the components have already been inserted into pages can be risky business. This script will save you from the issues that arise from this change. Cheers!