Friday, February 6, 2015

Working with Renderings in Sitecore Powershell

In the last few weeks I've been using the very useful Sitecore Powershell Extensions to perform a large amount content transfer operations.  The scenario is a pretty common one when using Sitecore and developing websites. Given a set of data create, load, and prepare hundreds or thousands of items into Sitecore. Yesterday.

This can be an incredibly time consuming operation and daunting operation. Especially if those items contain sub items which need images which need to link to other items, etc, etc. Lots of manual content entry which is costly, prone to error, and lacks any sort of verification or re-usability.

So enter Powershell. This is the kind of scenario Powershell really shines at. Fast (to write) scripts for one or few time use with the ability to load your content into Sitecore in the proverbial blink of an eye. Thankfully, the folks at cognifide made us a Sitecore powershell extension to help out.

One of the tasks that is surely familiar to any Sitecore admin is attaching controls to objects. While going through the UI works it is incredibly slow.  Not something you want to do dozens, much less hundreds of times.

Well, it turns out it isn't that super hard. We're going to use Powershell Here Strings  to store a generic Sitecore rendering XML and create/replace the GUIDs we need to. You can see the Sitecore specific way of doing this using their API via John West's blog on the subject.


The script is below, we have a group of pages and a group of controls. Our controls that we need to add are named the same as our pages. We simply find them, retrieve their sitecore ID and create a new GUID for the actual control object.

There are 3 attributes at play here in the XML we care about. The first is the ID, that is the actual Sitecore item we are setting. The second is the UID , this is a GUID unique to this instance of the rendering, hence why we generated a new GUID. The second is the s:ds attribute, which is our datasource for our Sitecore component. The fourth, you may notice, is the s:ph which is the placeholder attribute.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024


$pages= gci -Path "master:\path\to\our\pages" -Recurse
$controls = gci -Path "master:\content\data\ourcontrols" -Recurse | Where-Object {$_.templateName -eq "ourtemplatename"}

$replaceRenderersText  = @"
<r xmlns:p="p" xmlns:s="s" p:p="1" s:xsd="http://www.w3.org/2001/XMLSchema">
<d id="{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}">
<r uid="NEWGUIDHERE" s:cnd="" s:ds="REPLACEME" s:id="{474D8968-D54C-4C78-8DDB-2BBF31C22B16}" s:par="" s:ph="/main/components" />
</d></r>
"@

foreach($page in $pages){
    $control = $controls | Where-Object {$_.name -eq $page.name}
    $newUnique = [guid]::NewGuid()
    $specificRendering = $replaceRenderersText.Replace("REPLACEME",$control.id.guid.Tostring("B")).Replace("NEWGUIDHERE",$newUnique.ToString("B"))
    if($category.__Renderings -ne $categoryRender){
        $category.BeginEdit()
        $category.__Renderings = $specificRendering
        [void]$category.EndEdit()
   }

You might be wondering where we got the the XML in the first place. I "cheated" by pulling the data from the Sitecore objects .__Renderings field.

 Ta-Da! Hours saved from mainly attaching many, many controls.

No comments:

Post a Comment