4

We have a problem with orphaned rendering in pages.

Content editors are directly removing the parent Components instead of deleting both parent and child rendering in the Experience Editor. This ends up with many orphans (Child) rendering on the page because of deleting only the parent component (Like containers, etc.,).

We need to clean up orphans rendering on the page using PowerShell script. Some of the parent components are having both static and dynamic placeholders as well.

Could you please help with any script reference?

2
  • Out of curiosity, why do you need to do that?
    – MStodd
    Jun 11, 2023 at 1:10
  • 1
    Content authors while editing any page through experience editor, they are not removing unnecessary rendering on the page, this increases the page load and also we use third party translator provider where they will charge based on page word count. these unnecessary data sources are also getting added and increasing our cost. Jun 12, 2023 at 16:09

2 Answers 2

2

You can try out this script that Identifies and Removing Unknown Renderings. I think this would be a good start to what you are looking for and extend it.

The script utilizes the Get-Item command from SPE to retrieve the target item. It then examines the layout definition and iterates through the renderings associated with the item. For each rendering, the script verifies the existence of the referenced Item ID within Sitecore. If an Unknown Rendering is detected, it is removed from the layout definition, preventing broken links and ensuring a consistent rendering experience for end-users.


$itemPath = "<your-path>"
$item = Get-Item -Path $itemPath

#Shared or Final Layout?
$sharedLayout = $true

# Get the layout field
if($sharedLayout) {
    $layoutField = New-Object Sitecore.Data.Fields.LayoutField -ArgumentList $item.Fields[[Sitecore.FieldIDs]::LayoutField]
} else {
    $layoutField = New-Object Sitecore.Data.Fields.LayoutField -ArgumentList $item.Fields[[Sitecore.FieldIDs]::FinalLayoutField]
}

# Parse the layout definition
$layoutDefinition = [Sitecore.Layouts.LayoutDefinition]::Parse($layoutField.Value)

# Get the device definition (in that case the Default)
$ddef = $layoutDefinition.GetDevice("{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}")

# Get the array of all renderings for the target page item
$renderingsArray = $ddef.Renderings | ForEach-Object { [Sitecore.Layouts.RenderingDefinition]$_ }

# Create lists to manipulate the Rendering list
$originalRenderingsList = [System.Collections.Generic.List[Sitecore.Layouts.RenderingDefinition]]($renderingsArray)
$newRenderingsList = [System.Collections.Generic.List[Sitecore.Layouts.RenderingDefinition]]($renderingsArray)

#For each rendering, checks if the item exist ()
$originalRenderingsList | Where { 
    $renderingItem = Get-Item -Path "master:" -ID $_.ItemId -ErrorAction SilentlyContinue
    
    if(!$renderingItem) {
        Write-Host $_.ItemId - "Unknown Rendering Found"
        $newRenderingsList.Remove($_)
    } 
}

# Update the renderings array in the device definition
$ddef.Renderings = $newRenderingsList.ToArray()

# Save the layout changes
$item.Editing.BeginEdit()
$layoutField.Value = $layoutDefinition.ToXml()
$item.Editing.EndEdit()

Credit : Identifying and Removing Unknown Renderings

Hope it helps!

2
  • 1
    I'm looking out to remove orphan rendering which were added in any dynamic placeholder not the unknown renderings. Anyways thanks for your response! Jun 12, 2023 at 16:10
  • Thank you for the credits =) unfortunately, it doesn't do what Sudheer needs. Aug 18, 2023 at 14:56
2

Well, in this case, I think there are only 2 options available: identify these orphans' renderings by placeholder name or by rendering ID or both.

Try this:

$itemPath = "<your-path>"
$item = Get-Item -Path $itemPath

#Shared or Final Layout?
$sharedLayout = $true

# Get the layout field
if($sharedLayout) {
    $layoutField = New-Object Sitecore.Data.Fields.LayoutField -ArgumentList $item.Fields[[Sitecore.FieldIDs]::LayoutField]
} else {
    $layoutField = New-Object Sitecore.Data.Fields.LayoutField -ArgumentList $item.Fields[[Sitecore.FieldIDs]::FinalLayoutField]
}

# Parse the layout definition
$layoutDefinition = [Sitecore.Layouts.LayoutDefinition]::Parse($layoutField.Value)

# Get the device definition (in that case the Default)
$ddef = $layoutDefinition.GetDevice("{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}")

# Get the array of all renderings for the target page item
$renderingsArray = $ddef.Renderings | ForEach-Object { [Sitecore.Layouts.RenderingDefinition]$_ }

# Create lists to manipulate the Rendering list
$originalRenderingsList = [System.Collections.Generic.List[Sitecore.Layouts.RenderingDefinition]]($renderingsArray)
$newRenderingsList = [System.Collections.Generic.List[Sitecore.Layouts.RenderingDefinition]]($renderingsArray)

#For each rendering, checks if the item exist ()
$originalRenderingsList | Where {
    
    #Change here the placeholder name and/or the ItemID - The ItemID means the ID of the rendering
    if($_.Placeholder -eq "main" -or $_.ItemID -eq "{CE4ADCFB-7990-4980-83FB-A00C1E3673DB}") {
        Write-Host $_.ItemId - "Orphan Rendering Found"
        $newRenderingsList.Remove($_)
    } 
}

# Update the renderings array in the device definition
$ddef.Renderings = $newRenderingsList.ToArray()

# Save the layout changes
$item.Editing.BeginEdit()
$layoutField.Value = $layoutDefinition.ToXml()
$item.Editing.EndEdit()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.