11

Our content authors, makes a lot of mistake when whey work in Experience Editor. Quite often they do some changes on final layout, but expect to have it on shared layout.

Is is any tool exist that could handle this case and clear final layout after it ? For simplicity copy only latest version in a one language.

0

4 Answers 4

17

I wrote a PowerShell cmldet for merging Final Renderings back into Shared Renderings.

function Merge-Layout {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true,Position = 0,ValueFromPipeline = $true)]
        [item]$Item
    )

    process {
        $layoutField = New-Object "Sitecore.Data.Fields.LayoutField" -ArgumentList ($Item.Fields[[Sitecore.FieldIDs]::LayoutField]);
        $finalLayoutField = New-Object -TypeName "Sitecore.Data.Fields.LayoutField" -ArgumentList $Item.Fields[[Sitecore.FieldIDs]::FinalLayoutField]

        if ($layoutField -eq $null) {
            Write-Error "Couldn't find layout on: $($Item.Name)"
        }

        if ($finalLayoutField -eq $null) {
            Write-Error "Couldn't find final layout on: $($Item.Name)"
        }

        if ($finalLayoutField.Value -eq $null -or $finalLayoutField.Value -eq "") {
            return;
        }

        $finalLayoutDefinition = [Sitecore.Layouts.LayoutDefinition]::Parse($finalLayoutField.Value)

        $Item."__Renderings" = $finalLayoutDefinition.ToXml();
        Reset-ItemField -Item $Item -Name "__Final Renderings" -IncludeStandardFields
    }
}

Code is available on my gist: https://gist.github.com/alan-null/a7dd2cd01d9d851b39a6ec5fca96ac0b

If you want C# code, here is a source from where I got this approach: http://www.rockpapersitecore.com/2016/07/07/merging-final-renderings-back-down-into-shared-renderings/

3
  • good job dude, I like it ... I will back to you if find any issue. Commented Feb 27, 2017 at 14:57
  • 3
    This has been implemented as a cmdlet as seen here: github.com/SitecorePowerShell/Console/issues/669 Commented Aug 15, 2017 at 1:44
  • Hell all,After executing the given ps script, i don't see any components copied to final to shared layout.
    – PVM
    Commented Feb 6, 2018 at 3:10
7

SPE now has the Merge-Layout function (similar to the one Alan Płócieniak wrote here) available out of the box. I think it's existed for about 2 years now: https://doc.sitecorepowershell.com/appendix/presentation/merge-layout.

The Merge-Layout command takes all the layout information stored in the FinalLayout field and merges into the SharedLayout field. The FinalLayout field is reset after the merge completes.

You can use it like so:

Get-Item master:"/sitecore/content/MySite/My Test Page" | Merge-Layout  

or for a number of items at once:

Get-ChildItem master:\content\Showcase\int -Recurse | Merge-Layout 

Also if you wish to copy back the final renderings to the page template standard values renderings field instead so then I wrote this script to do it:

function Copy-Page-FinalLayout-To-Template([string]$pagePath,[switch]$ResetLayout){
    #get the page item
    $item = Get-Item -Path "master:$pagePath"

    #get the final layout from the page
    $finalLayoutField = New-Object -TypeName "Sitecore.Data.Fields.LayoutField" -ArgumentList $Item.Fields[[Sitecore.FieldIDs]::FinalLayoutField]

    if ($finalLayoutField -eq $null) {
        Write-Error "Couldn't find final layout on: $($Item.Name)"
    }
    if ($finalLayoutField.Value -eq $null -or $finalLayoutField.Value -eq "") {
        return;
    }

    #get the items template and standard values on the template
    $template = Get-ItemTemplate -ID $item.ID 
    $templateItem = Get-Item -Path "master:$($template.ID)"
    $templateStandardValuesPath = "$($templateItem.Paths.FullPath)/__Standard values";
    $standardValuesItem = Get-Item -Path "$($templateItem.Paths.FullPath)/__Standard values"

    #copy the final layout details back to the the renderings field on the standard values
    $finalLayoutDefinition = [Sitecore.Layouts.LayoutDefinition]::Parse($finalLayoutField.Value)
    $standardValuesItem.Editing.BeginEdit()
    $standardValuesItem["__Renderings"] = $finalLayoutDefinition.ToXml();
    $standardValuesItem.Editing.EndEdit()

    Write-Host "Template Standard Values Updated: $($templateItem.Name)"

    #reset the page final renderings back to the page templates standard values
    if($ResetLayout){
        Reset-ItemField -Item $Item -Name "__Final Renderings" -IncludeStandardFields
        Write-Host "Page Final Renderings Reset To Standard Values: $($item.Name)"
    }
}

more info here: http://www.flux-digital.com/blog/copying-final-renderings-back-standard-values-page-templates-spe/

0

if you need to reset only some specific Components on the Final Layout, you can use this Sitecore Module "Layout Modes Comparer": https://marketplace.sitecore.net/Modules/L/Layout_Modes_Comparer.aspx

the Module also highlights the Components, created/updated/deleted on the Final Layout. That can be realy helpfull in your case:

enter image description here

-2

You can use default "Reset Layout" functionality to reset layout fields.

enter image description here

6
  • I don't need to reset, we keep users from double work...this is why I need to have some tool Commented Feb 27, 2017 at 13:04
  • @Arbejdsglæde can you clarify the requirement bit more. seems i haven't understand the requirement correctly. Commented Feb 27, 2017 at 13:30
  • I need to have tool that could created shared layout based on finial layout. Commented Feb 27, 2017 at 13:48
  • This will reset final layout but OP has asked to copy final layout to shared layout. Commented Sep 9, 2019 at 9:44
  • @SuryaGahlot I think question was edited from its initial version Commented Sep 9, 2019 at 22:20

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.