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.

16

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/

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

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

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

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.