Change Base Templates in Sitecore and Maintain Field Values

Author

Brandon Bruno

Published

September 22, 2020

Tags

Change Base Templates in Sitecore and Maintain Field Values

Changing an item's template in Sitecore is generally a trivial process - there's a ribbon button for it in the Content Editor, after all.

Changing one or more base templates on items, however, can be trickier depending on whether or not the items in question already have content stored in data fields.

How Sitecore Changes Templates

When an item's template is changed in the Content Editor, Sitecore attempts to preserve the content stored in fields by doing one of two things (in order):

  • match field IDs between the old and new templates, or
  • match fields by their name and data type

If one of the two conditions are true, Sitecore keep fields values on the item when the template is changed. The first condition will almost never be met: if you're changing to a new data template, the IDs of individual fields will likely be different than the old template.

If you are changing one or more inherited base templates, however, you may have some templates with the same field IDs somewhere in the inheritance chain.

To be safe and prevent potential confusion, when changing base templates, Sitecore simply clears all data/content from fields. It provides a big, scary warning for this too:

Sitecore's warning about removing base templates.

PowerShell to the Rescue

If you need to change an item's template or base templates and preserve all the data/content values, Sitecore PowerShell Extensions saves the day. The process is pretty simple:

  • Store the values for all fields on an item
  • Change the template(s)
  • Populate the stored values back into the item's fields

The following script will update the base templates of items in the content tree. You can easily modify this to update just top-level data template as well.

# Items for the template update - use a Where-Object cmdlet to filter this if needed
$items = Get-ChildItem -Path 'master:/sitecore/content/mysite' -Recurse

# A hashtable (of item IDs) that stores hashtables of fields & values
$storage = @{}

#
# 1) Store existing fields
#

foreach ($item in $items)
{
    # Populate existing field values for this item
    $fields = @{}
    
    foreach ($field in $item.Fields)
    {
        $fields[$field.Name] = $item[$Field.Name]
    }
    
    $storage[$item.ID] = $fields
    
}

#
# 2) Update base templates
#

$itemTemplate = Get-Item -Path 'master:' -ID 'B3B7C30F-415E-4FBD-A88D-BFDD4A4A31F7'

# This example updates the base templates of an item
$itemTemplate.Editing.BeginEdit()
$itemTemplate["__Base template"] = '296B04C0-02E0-4758-8F03-7E6ABB561D44|5BF8C439-F7E7-458C-9520-DFC7FF816ECF'
$itemTemplate.Editing.EndEdit()

#
# 3) Write values back to items
#

foreach ($item in $items)
{
    $fields = $storage[$item.ID]
    
    $item.Editing.BeginEdit()
    
    foreach ($field in $item.Fields)
    {
        $item[$Field.Name] = $fields[$field.Name]
    }
    
    $item.Editing.EndEdit()
}

Do you have questions, comments, or corrections for this post? Find me on Twitter: @BrandonMBruno