42

I need to add a rendering to all of the pages in my Sitecore tree (i.e., items that have renderings, have a layout set, and live under /sitecore/Content). Content items that don't have renderings or a layout set don't need the rendering. I want to add this rendering to the layoutHeader placeholder on my pages and the rendering does not require a data source.

Is this something that's possible with the Sitecore API or Sitecore PowerShell? If so, how would I go about it? I'm working with Sitecore 8.1 Update-3.

1
  • Is there any reason why you're not doing this through standard values?
    – Chris Berg
    Oct 12, 2016 at 13:49

5 Answers 5

44

You can do this by using the Powershell Extensions module.

$item = get-item master:\content\Demo\Int\Home
$device =Get-Device -Default
$contentDataSource = get-item master:\content\Demo\Int\Home\about-us\employee-stories\adam-najmanowicz
$ImageDataSource = get-item master:\content\Demo\Int\Data\Images\d56cf7e777a2496aa6489a7bffc03539

$rendering = get-item master:\layout\Sublayouts\ZenGarden\Basic\Content
Add-Rendering -Item $item -Device $device -Rendering $rendering -Placeholder main -Parameter @{FieldName ="Title"} -DataSource $contentDataSource
$rendering = get-item master:\layout\Sublayouts\ZenGarden\Basic\Image
Add-Rendering -Item $item -Device $device -Rendering $rendering -Placeholder main -DataSource $ImageDataSource
$rendering = get-item master:\layout\Sublayouts\ZenGarden\Basic\Subtitle
Add-Rendering -Item $item -Device $device -Rendering $rendering -Placeholder main -DataSource $contentDataSource
$rendering = get-item master:\layout\Sublayouts\ZenGarden\Basic\Title
Add-Rendering -Item $item -Device $device -Rendering $rendering -Placeholder main

Source: Adam Najmanowicz Gist.

This should serve as a good starting point. Here is the documentation of the Add-Rendering function:

https://sitecorepowershell.gitbooks.io/sitecore-powershell-extensions/content/appendix/commands/Add-Rendering.html

3
  • 1
    Beat me to it, was just writing an answer! I think it's best to include the PowerShell itself in your answer (though of course can still credit Adam), just so that this answer isn't dependent on a link.
    – Kasaku
    Sep 13, 2016 at 19:36
  • 1
    Pascu was too fast for us :) +1 Sep 13, 2016 at 19:37
  • 1
    Just wanted to add that I did a blog post outlining this process along with any gotchas i ran into along the way. blogs.perficient.com/microsoft/2016/06/…
    – BillCacy
    Sep 19, 2016 at 17:12
23

Another option is to use the Sitecore search bulk update actions.

  1. Start a search at the root of your content tree (e.g. /sitecore/content/home).
  2. Click on the little magnifying glass
  3. Enter a search query to select all the content items you'd like to update (e.g Template: {your-template-guid-here}
  4. Click the little drop-down arrow then Search operations
  5. Then click Apply presentation
  6. This opens the presentation dialog which will allow you to configure the required presentation which will be applied to all results in the search.

However, I'd personally use Sitecore Powershell if it is installed as it is a fantastic module.

2
  • 1
    I was actually unaware of this option. Excellent alternative for situations where installing SPE is not an option :-) Sep 14, 2016 at 9:08
  • I'm not getting where is this located, can you add screenshot for this?
    – Harsh Baid
    Sep 17, 2016 at 18:05
7

Something like this should do it

Write-Host "$([System.DateTime]::Now)"; 

$searchResults = Find-Item `
                    -Index sitecore_master_index `
                    -Criteria   @{Filter = "StartsWith"; Field = "_fullpath"; Value = "/sitecore/content/"} | Initialize-Item

$rendering = Get-Item master:\layout\renderings\sample\foo | New-Rendering
$device = Get-LayoutDevice -Default

$totalItems = $searchResults | measure 
$totalItemsCount = $totalItems.Count 
$currentProgress = 1; 
$searchResults | Foreach-Object { 

    $itemToProcess = $_.name 
    Write-Progress -Id 1 -Activity "Setting presentation details" -PercentComplete ($currentProgress/$totalItemsCount * 100) -Status "$currentProgress / $totalItemsCount - $itemToProcess";

    # check that current item version has a layout specified for a specific device
    $hasLayout = $_ | Get-Layout -Device $device -ErrorAction SilentlyContinue
    if(!$hasLayout){ return }

    # check that current item version has renderings specified for a specific device
    $hasRenderings = $_ | Get-Rendering -Device $device -ErrorAction SilentlyContinue
    if(!$hasRenderings){ return }

    # Add the specified rendering to the specified placeholder
    Add-Rendering -Item $_ -Device $device -Rendering $rendering -Placeholder layoutHeader

    $currentProgress++ 
} 

Write-Host "Done processing" $totalItemsCount "items" 
Write-Host "$([System.DateTime]::Now)";
6

You Can also probably do it as simple as updating each item's Rendering field's XML data.

  1. Maybe just go to the Sitecore and see the rendering you want is getting added on one item (maybe choose an item that did not have much stuff going on in presentation)
  2. And write a code test on one single item first to update an item by using the usual Sitecore item field value update API on item.Fields["__Renderings"].Value
  3. To make it easier, you can probably use the .NET XDocument to parse the value first and add your new rendering node as an XElement r
  4. And update the rendering field value with this new XDocument element's value.

Hope this helps!

0

Here is another code snippet you should be able to use to add a rendering

$Rendering = Get-Item -Path 'master:{<rendering item GUID>}'
$Datasource = '{<datasource item GUID>}'

function Get-FirstPlaceholderIndex() {
    param(
        [Parameter(Mandatory = $true)]
        [Sitecore.Data.Items.Item] $Item)

    $idx = 0
    Get-Rendering -Item $Item | ForEach-Object {
        if ($_.Placeholder -eq '<placeholder name for index>') {
            return $idx
        }

        $idx++
    } | Select-Object -First 1
}


function Add-Component() {
    param(
        [Parameter(Mandatory = $true)]
        [Sitecore.Data.Items.Item] $Item,

        [Parameter(Mandatory = $true)]
        [string] $Placeholder)

    Write-Host "......Adding new component..."
    Add-Rendering `
        -Item $Item `
        -PlaceHolder $Placeholder `
        -DataSource $Datasource `
        -Instance (New-Rendering -Item $Rendering) `
        -Index (Get-FirstPlaceholderIndex -Item $Item)
}

function Get-PagesByTemplateId() {
    param(
        [Parameter(Mandatory = $true)]
        [string] $TemplateId)

    Get-ChildItem -Path 'master:/sitecore/content' -Recurse |
        Where-Object { $_.TemplateID -eq $TemplateId }
}

function Add-Components() {

    Write-Host 'Processing items based on the this template'
    Get-PagesByTemplateId -TemplateId '{<template item GUID to select specific set of items>}' |
        ForEach-Object {
            Add-Component -Item $_ -Placeholder '<placeholder name>'
        }
}

Add-Components
Write-Host 'Done'

Your Answer

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

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