Swapping & Deleting Renderings with Sitecore Powershell Extensions

file-swap-pngrepo-comI’ve been working a lot with SPE recently as have been working on a project where I needed to switch out a number of global components on all pages for new ones and update the data sources as well (e.g header / navigation etc). SPE was a great fit for this.

There isn’t a Swap-Rendering method in SPE as such but there is the Set-Rendering function which I could use as a basis to do this.

As I needed to update every page in the Site (well multiple Sites actually) I needed to write my script to update the page templates and swap out the standard values (so the changes would propagate to all pages using them). However I also wanted to make it work for page items too in case I wanted to update specific pages as well.

Show Me The Script

So after a lot of testing and trial and error the following is what I ended up with:

Update Pages Script

This is the main script that loops over the templates or pages and then the renderings within them. I’ve commented all the variables you can configure but here are a few key ones to note:

  • $templateMode – set to False to update pages instead of templates (usually you will want to update template standard values)
  • $checkForLayout – set to True to skip items with no layout (use only for updating pages and not templates)
  • $updateDataSourcesOnly – set to True to only update datasources and not swap or delete renderings
  • $reportMode – set to True to just output info on renderings to be swapped/deleted/updated
  • $placeholder – update to use the placeholder your renderings exist in
  • $renderingIdToSwap – update to the rendering id you wish to swap out
  • $renderingIdToAdd – update to the rendering id you wish to swap in
  • $renderingDataSourceToAdd – update to the datasource you wish to use for your rendering (set to $null to skip updating a datasource)
  • $renderingIdToRemove – update to a rendering id you wish to remove

Swap-Rendering Function

Swap-Datasource Function

Potential Improvements

Since I wrote the above scripts I have added quite a lot of functionality to them to do the following:

  • Add Renderings at a relative position to existing renderings
  • Update Cache Settings for Renderings
  • Update a rendering Position
  • Support different source and destination placeholders when swapping renderings
  • Add more logging and error handling

I have not included this above as I think it adds complexity which others might not need but feel free to contact me on Twitter if you’d like me to share some of the above improvements.

An SPE Bug I Found & Big Thanks to Micheal West

DoygP1aV4AAFrTKLastly I need to say a huge thanks to Micheal West for his help and dedication to the SPE module. The support I had from him was awesome.
Whilst working on this I found that on some of my Templates my ‘Default’ device layout wasn’t updated on some pages and I couldn’t get my scripts to update layouts for other Devices on some Templates.

I reported this in Slack and Michael West very quickly responded to me to confirm it was an bug in SPE with Set-Rendering not honouring the Device passed to the rendering instance and instead using the first matching rendering it finds in any layout for any Device.

Michael set about fixing it for me and I woke up the next day to find he had even created me an release of the module with the fix in place (support for -Device Parameter on the Set-Rendering  function) so I could continue with my project work!.
I believe the fix will be in a later release of SPE but this is the issue in Github if you are interested. So if you have multiple Device layouts then you will need to wait for this version for the fix.

Hopefully some of these scripts are useful for future projects.

Published by

Adam Seabridge

I am a Freelance Sitecore Developer and 6x Sitecore Technology MVP (2023 - 2018). I have been working with Sitecore since 2013. You can reach me on twitter @billyjava or comment below if you have any questions or feedback.

7 thoughts on “Swapping & Deleting Renderings with Sitecore Powershell Extensions”

  1. It seems that “The term ‘Update-Page-Renderings’ is not recognized as the name of a cmdlet, function, script file, or operable program.” what is the fix to this, google brings back nothing of any help.

    1. My mistake, I’d neglected to include the functions below the main thread thinking they were optional. Clearly need to put my glasses back on and read the script fully before making such an assumption again in the future.

      Thanks for this extremely useful script! 🙂

  2. $rootItem = Get-Item -Path “/sitecore/templates/Project/Pearson/Page types/Kiosk/Transportation page” #update to the path with your page templates
    $deviceLayout = Get-LayoutDevice “Default” #update to device layout you wish to target
    $templateMode = $False #set to False to update pages instead of templates (usually you will want to update template standard values)
    $useFinalLayout = $False #set to True to use FinalRenderings instead of Renderings field
    $checkForLayout = $False #set to True to skip items with no layout (use only for updating pages and not templates)
    $modeType = “”
    $placeholder = “main” #update to use the placeholder your renderings exist in
    $renderingIdToSwap = “{5FBA0635-D7EB-4893-AB71-0B0DA5B97342}” #update to the rendering id you wish to swap out
    $renderingIdToAdd = “{D71F3CFF-C8C8-425F-9B39-42EB8612493E}” #update to the rendering id you wish to swap in
    $renderingDataSourceToAdd = $null #update to the datasource you wish to use for your rendering (set to $null to skip updating a datasource)

    if($templateMode){
    $modeType = “Template”
    }
    else{
    $modeType = “Page”
    }

    Get-ChildItem -Item $rootItem -Recurse | Where-Object {$_.TemplateName -ne “__Standard Values”} | ForEach-Object {

    #template mode
    if($templateMode){
    $templateToUpdate = $_
    if(Test-Path -Path “master:$($templateToUpdate.FullPath)/__Standard Values”){
    $templateStandardValues = Get-Item -Path “master:$($templateToUpdate.FullPath)/__Standard Values”
    Update-Page-Renderings -parentItem $templateToUpdate -item $templateStandardValues
    }
    }
    #page mode
    else{
    $pageToUpdate = $_
    Update-Page-Renderings -parentItem null -item $pageToUpdate
    }
    }

    function Update-Page-Renderings($parentItem, $item, $checkForLayout){

    if ((Get-Layout $item) -or !$checkForLayout)
    {
    $renderings = Get-Rendering -Item $item -Placeholder ($placeholder) -Device $deviceLayout -FinalLayout:$useFinalLayout

    foreach ($rendering in $renderings)
    {
    $renderingItem = Get-Item -Path $rendering.ItemID

    $swapRendering = $renderingIdToSwap -eq $rendering.ItemID

    if($swapRendering){

    Swap-Rendering -item $item -renderingToSwapOut $rendering -placeholder $placeholder `
    -renderingIdToAdd $renderingIdToAdd -renderingDataSourceIdToAdd $renderingDataSourceToAdd -useFinalLayout $useFinalLayout

    }
    }
    }
    }
    function Swap-Rendering ($item, $renderingToSwapOut, $placeholder, $renderingIdToAdd, $renderingDataSourceIdToAdd, $useFinalLayout) {
    $renderingItem = Get-Item -Path $renderingToSwapOut.ItemID
    Write-Host “Swaping Rendering: $($renderingToSwapOut.UniqueID) – ‘$($renderingItem.Name)’ in Placeholder: $($placeholder) to: $($renderingIdToAdd) – ‘$($renderingToAdd.Name)’ for Item: $($item.Name)”
    $renderingToSwapOut.ItemID = $renderingIdToAdd
    if($renderingDataSourceToAdd){
    $renderingToSwapOut.Datasource = $renderingDataSourceToAdd
    }
    Set-Rendering -Item $item -Instance $renderingToSwapOut -FinalLayout:$useFinalLayout
    }

    I added this but it is not working.please help

      1. I need PowerShell script to update renderings ID in both English and French language based on template name.
        Please help me with the working script

Leave a Reply

Your email address will not be published. Required fields are marked *