5

I'm attempting to use Sitecore Powershell Extensions to automate Step 2 of the following upgrade guide for a Sitecore accelerator known as SCORE:

https://brainjocks.atlassian.net/wiki/spaces/SDD/pages/390594792/Add+New+Placeholder+Settings

In the step, a variety of new placeholder settings are added to the Presentation Details of each page's __Standard Values on the Sitecore installation. I've found several resources on how to add a rendering definition item to a layout but no resources on how to add a placeholder. Here is a snippet of what I have so far:

#define placeholders to add
$facetPlaceholder = "<p uid=`"{1E5FCA45-4AF1-40AB-9479-FE9AE4172DB5}`" key=`"Facets`" md=`"$tenantCopyPath/Facets`" />"
$searchResultViewsPlaceholder = "<p uid=`"{5137EC9B-4DC0-464B-A522-6FB1EE5362E9}`" key=`"Search Result Views`" md=`"$tenantCopyPath/Search Result Views`" />"
$slickSliderPlaceholder = "<p uid=`"{F2B4B648-5BCF-4556-9630-467F2A710B98}`" key=`"Slick Slider`" md=`"$tenantCopyPath/Slick Slider`" />"

if ($pageTemplatesExist) {
    $children = Get-ChildItem -Path $pageTemplatePath
    foreach ($child in $children) {
        $childPath = $child.Paths.Path
        $standardValues = Get-ChildItem -Path $childPath
        if ($standardValues.length -ne 0) {
            $renderingsField = $standardValues.Fields["__Renderings"].ToString()
            $testXML = [xml]$renderingsField
            if (-not ($renderingsField -contains 'Facets')) {
                $standardValues.Editing.BeginEdit()
                $standardValues.Editing.EndEdit()
            }
            else {
                Write-Host "Placeholder setting already exists for Facets at item: $($standardValues.Paths.Path) "
            }
            if (-not ($renderingsField -contains 'Search Result Views')) {
                $standardValues.Editing.BeginEdit()
                $standardValues.Editing.EndEdit()
            }
            else {
                Write-Host "Placeholder setting already exists for Search Result Views at item: $($standardValues.Paths.Path) "
            }
            if (-not ($renderingsField -contains 'Slick Slider')) {
                $standardValues.Editing.BeginEdit()
                $standardValues.Editing.EndEdit()
            }
            else {
                Write-Host "Placeholder setting already exists for Slick Slider at item: $($standardValues.Paths.Path) "
            }
        }
        else {
            Write-Host "No standard values template for page at path: $childPath"
        }
    }
}
else {
    Write-Host "No page templates found for $tenant found at path: $pageTemplatePath"
}

My current idea is to manually modify the __Renderings standard field. I was going to grab the string version of the __Renderings field, inject my new placeholder markup where needed(possibly first converting this string to XML to make my modifications easier although I was having trouble getting the __Renderings read into an xml variable), then reassigning the original __Renderings field value to my new modified version. Is there a more straightforward way to accomplish this task without manually manipulating the __Renderings field? Thanks for the assistance!

  • 4
    There are commands included in SPE to manage Renderings. Have you tried those first? doc.sitecorepowershell.com/working-with-items/item-renderings – Michael West Dec 19 '18 at 21:47
  • Yes I’ve taken a look at those. Those methods allow you to interact with rendering items on the layout. I’m specifically trying to interact with Placeholder Settings. – c-bro Dec 19 '18 at 23:25
  • 2
    There has been a PR submitted for Placeholder commands. Perhaps you can have a look to see if these will do what you need? github.com/SitecorePowerShell/Console/pull/951 – Michael West Dec 19 '18 at 23:31
  • Yeah, this is exactly what I'm looking for. I'm going to try to borrow some of the logic here to see if I can create a solution that works for us. – c-bro Dec 20 '18 at 15:11
1

Definitely not the prettiest thing in the world but I came up with a solution using the pull request @Michael West linked to. The big key for me was finding out that you could create a DeviceDefinition item which has an AddPlaceholder method:

if ($pageTemplatesExist) {
    $children = Get-ChildItem -Path $pageTemplatePath
    foreach ($child in $children) {
        $childPath = $child.Paths.Path
        $standardValues = Get-ChildItem -Path $childPath
        if ($standardValues.length -ne 0) {
            $layoutField = [Sitecore.FieldIDs]::LayoutField
            $layout = $standardValues[$layoutField].ToString()
            $layoutDefinition = [Sitecore.Layouts.LayoutDefinition]::Parse($layout);
            $layoutUpdated = $false
            foreach ($device in $layoutDefinition.Devices) {
                $deviceDefinition = [Sitecore.Layouts.DeviceDefinition]$device

                $facetPlaceholderExists = $false
                $searchResultViewsPlaceholderExists = $false
                $slickSliderfacetPlaceholderExists = $false

                foreach ($currPlaceholder in $deviceDefinition.Placeholders) {

                    $currPlaceholderDefinition = [Sitecore.Layouts.PlaceholderDefinition]$currPlaceholder

                    if ($currPlaceholderDefinition.Key -eq $facetPlaceholderKey -and $currPlaceholderDefinition.MetaDataItemId -eq $facetPlaceholderMD) {
                        $facetPlaceholderExists = $true
                    }

                    if ($currPlaceholderDefinition.Key -eq $searchResultViewsPlaceholderKey -and $currPlaceholderDefinition.MetaDataItemId -eq $searchResultViewsPlaceholderMD) {
                        $searchResultViewsPlaceholderExists = $true
                    }

                    if ($currPlaceholderDefinition.Key -eq $slickSliderPlaceholderKey -and $currPlaceholderDefinition.MetaDataItemId -eq $slickSliderPlaceholderMD) {
                        $slickSliderfacetPlaceholderExists = $true
                    }
                }

                #add facet placeholder to all device definitions
                if (-not ($facetPlaceholderExists)) {
                    $placeholder = New-Object Sitecore.Layouts.PlaceholderDefinition
                    $placeholder.UniqueId = $facetPlaceholderUID
                    $placeholder.Key = $facetPlaceholderKey
                    $placeholder.MetaDataItemId = $facetPlaceholderMD
                    $deviceDefinition.AddPlaceholder($placeholder)
                    $layoutUpdated = $true
                }
                else {
                    Write-Host "Placeholder setting already exists for Facets at item: $($standardValues.Paths.Path) "
                }

                #add search result views placeholder to all device definitions
                if (-not ($searchResultViewsPlaceholderExists)) {
                    $placeholder = New-Object Sitecore.Layouts.PlaceholderDefinition
                    $placeholder.UniqueId = $searchResultViewsPlaceholderUID
                    $placeholder.Key = $searchResultViewsPlaceholderKey
                    $placeholder.MetaDataItemId = $searchResultViewsPlaceholderMD
                    $deviceDefinition.AddPlaceholder($placeholder)
                    $layoutUpdated = $true
                }
                else {
                    Write-Host "Placeholder setting already exists for Search Result Views at item: $($standardValues.Paths.Path) "
                }

                #add slick slider placeholder to all device definitions
                if (-not ($slickSliderfacetPlaceholderExists)) {
                    $placeholder = New-Object Sitecore.Layouts.PlaceholderDefinition
                    $placeholder.UniqueId = $slickSliderPlaceholderUID
                    $placeholder.Key = $slickSliderPlaceholderKey
                    $placeholder.MetaDataItemId = $slickSliderPlaceholderMD
                    $deviceDefinition.AddPlaceholder($placeholder)
                    $layoutUpdated = $true
                }
                else {
                    Write-Host "Placeholder setting already exists for Slick Slider at item: $($standardValues.Paths.Path) "
                }
            }

            if($layoutUpdated){
                $standardValues.Editing.BeginEdit()
                $standardValues[$layoutField] = $layoutDefinition.ToXml()
                $standardValues.Editing.EndEdit()
            }

        }
        else {
            Write-Host "No standard values template for page at path: $childPath"
        }
    }
}
else {
    Write-Host "No page templates found for $tenant found at path: $pageTemplatePath"
}

Thanks for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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