1

I'm copying a rendering from one item to another using Sitecore Powershell Extensions.

All is working well, except that the personalization rules for the rendering aren't copied over.

I can get/set the rules on a rendering definition item without any error, but both Add-Rendering and Set-Rendering seem to ignore any rules on the rendering definition.

Example code that I've tried without success:

$sourceRendering = Get-Rendering -Item $Source -FinalLayout | Where-Object{$_.uniqueid -eq "{a unique id}"}

This works to get the rules, and the output has content:

 $sourceRenderingRules = $sourceRendering.Rules

Add the rendering to a different item:

Add-Rendering -Item $TargetItem -Instance $sourceRendering -PlaceHolder $sourceRendering.placeholder -FinalLayout

Retrieve the new rendering (it will have a new uinique ID, so get the right one in code not shown or use a different way of selecting it)

$CopiedRendering = Get-Rendering -Item $Target -FinalLayout | Where-Object{$_.uniqueid -eq "{a unique id}"}

No error, but the Rules are empty

$CopiedRenderingRules = $CopiedRendering.Rules

Copy rules to the copied rendering, no error

$CopiedRendering.Rules = $sourceRenderingRules

Copied rendering now has rules, output has content

$CopiedRenderingRules = $CopiedRendering.Rules

Update the rendering

Set-Rendering -Item $TargetItem -Instance $CopiedRendering -PlaceHolder $CopiedRendering.placeholder -FinalLayout

When I then go back and get the rendering from the target, the rules are empty.

Have I missed something? Or will I have to work with the XML in the final layout field directly?

1 Answer 1

2

I wasn't able to find any way to work with the rendering rules directly in Sitecore Powershell Extensions, so I went driectly to the final renderings field and used the XML.

The end result is this function (basic, no error handling etc):

 Function CopyRenderingRules{
        [CmdletBinding()]
        param ( 
            [Parameter(Mandatory=$true,position=0)]
            [Sitecore.Data.Items.Item]$SourceItem,
            [Parameter(Mandatory=$true,position=1)]
            $SourceRenderingGUID,
            [Parameter(Mandatory=$true,position=2)]
            [Sitecore.Data.Items.Item]$TargetItem,
            [Parameter(Mandatory=$true,position=3)]
            $TargetRenderingGUID
            )

            <# Get the rules as an XML Element #>
            [xml]$sourceRenderingsXML = New-Object -TypeName XML
            $sourceRenderingsXML.loadxml($SourceItem."__Final Renderings") 
            $sourceXpathQ = "r/d/r[@uid='$($SourceRenderingGUID)']/rls"
            $sourceRuleElement = $sourceRenderingsXML.SelectSingleNode($sourceXpathQ)


            <# Get the target rendering as an XML Element #>           
            [xml]$targetRenderingsXML = New-Object -TypeName XML
            $targetRenderingsXML.loadxml($TargetItem."__Final Renderings")
            $targetXpathQ = "r/d/r[@uid='$($TargetRenderingGUID)']"
            $TargetRendering = $targetRenderingsXML.SelectSingleNode($targetXpathQ)

            <#Append the rules element to the target rendering element  #>         
            $TargetRendering.AppendChild($targetRenderingsXML.ImportNode($sourceRuleElement,$true)) > $null

            <# Output the Renderings XML to the final renderings field on the target #>          
            $TargetItem.Editing.BeginEdit()
            $TargetItem."__Final Renderings" = $targetRenderingsXML.OuterXML
            $TargetItem.Editing.EndEdit() > $null

    }

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.