29

We are refactoring our project and are trying to clean up the usages of templates throughout the project. There are a number of templates that are very similar that could all be using the same data template, which would also mean we can better utilize the "Compatible Renderings" functionality in Sitecore making it easier for editors to change components.

The problem is we have existing content and it would be a pain have to re-create all the datasources and copy across the data manually.

For example, given the following data templates:

Template A

Title1        Single-Line Text
SubText1      Multi-Line Text
Body1         Rich Text
Image1        Image

Template B

Title2        Single-Line Text
SubText2      Rich Text
Body2         Rich Text

How can we change all items which use Template B to instead use Template A and still retain all existing data?

1

6 Answers 6

24

You can do this with Sitecore PowerShell Extensions.

PowerShell Extensions 4.5 or Higher

Use the Set-ItemTemplate commandlet with the -FieldsToCopy parameter.

$rootItem = Get-Item master:/content;
$sourceTemplate = Get-Item "Template-B-Path-Or-Guid-Here";
$targetTemplate = Get-Item "Template-A-Path-Or-Guid-Here";

Get-ChildItem $rootItem.FullPath -recurse | Where-Object { $_.TemplateName -eq $sourceTemplate.Name } | ForEach-Object {
    Set-ItemTemplate -Item $_ -TemplateItem $targetTemplate `
        -FieldsToCopy @{ Title2 = "Title1"; SubText2 = "SubText1"; Body2 = "Body1" }
}

The value you pass to the -FieldsToCopy parameter takes the following form: @{ OldField1 = "NewField1"; OldField2 = "NewField2"; OldField3 = "NewField3" }.

PowerShell Extensions 4.4.1 or Lower

$rootItem = Get-Item master:/content;
$sourceTemplate = Get-Item "Template-B-Path-Or-Guid-Here";
$targetTemplate = Get-Item "Template-A-Path-Or-Guid-Here";

Get-ChildItem $rootItem.FullPath -recurse | Where-Object { $_.TemplateName -eq $sourceTemplate.Name } | ForEach-Object {
    $title2 = $_.Title2;
    $subText2 = $_.SubText2;
    $body2 = $_.Body2;

    $_.ChangeTemplate($targetTemplate);
    $updatedItem = Get-Item $_.ID;

    $updatedItem.Title1 = $title2;
    $updatedItem.SubText1 = $subText2;
    $updatedItem.Body1 = $body2;
}

With PowerShell Extensions 4.4.1 or lower, be careful that you do the following or you may experience data loss:

  1. Store the source field value into a variable before you change the item’s template.
  2. Get the updated item out of the database before you set the target field.
18

You can rename Title2 to match name of Title1 and then simply change the template.

Sitecore will preserve data if the names of the fields match.

Template A

Title1        Single-Line Text
SubText1      Multi-Line Text
Body1         Rich Text
Image1        Image

Template B

Title2 -> Title1        Single-Line Text
SubText2 ->SubText1      Rich Text
Body2 -> Body1         Rich Text

After changes in Template B, you can change Template B to Template A and Sitecore will preserve the data

6
  • 1
    This is wrong. Sitecore does not remap fields.
    – Mark Cassidy
    Commented Oct 11, 2016 at 1:07
  • Hmmm, are you sure? I checked that before posting. When the names of fields are different I am getting a warning that data migh get lost but when I change the name of the field to match original template Sitecore allows to change without warnings and the data stays. Commented Oct 11, 2016 at 6:00
  • Are you sure it's not because you're testing on templates that inherit common base templates? Data will stay if Field IDs stay the same.
    – Mark Cassidy
    Commented Oct 11, 2016 at 7:13
  • 4
    @MarkCassidy: The fields come from different templates (both inherit from Standard Template). You might want to check GetTemplateChangeList method from the Sitecore.Data.Templates.Template class - you can see that if the IDs of the fields are different Sitecore matches fields by name (object created there is then further passed to ChangeTemplate method). Commented Oct 11, 2016 at 8:01
  • 1
    This worked for me on sitecore 8.1 update 3, SPE had the advantage of also being able to change template types of existing items
    – jammykam
    Commented Oct 12, 2016 at 23:59
5

You can try to execute SQL script which will do the trick for you and update all the items which use particular template.

First you need to replace the field ids used in your original template with field ids used in the new template and then change the template of the item itself.

I haven't tested the script so make sure you have backups.

UPDATE VersionedFields SET [FieldId] = 'NEW_FIELD_ID' WHERE [FieldId] = 'OLD_FIELD_ID';
UPDATE UnversionedFields SET [FieldId] = 'NEW_FIELD_ID' WHERE [FieldId] = 'OLD_FIELD_ID';
UPDATE SharedFields SET [FieldId] = 'NEW_FIELD_ID' WHERE [FieldId] = 'OLD_FIELD_ID';
UPDATE Items SET [TemplateID] = 'NEW_TEMPLATE_ID' WHERE [TemplateID] = 'OLD_TEMPLATE_ID';

After the script is finished, restart the application and republished the site.

2
  • Seems like you will lose your data if swtiching field types (versioned/unversioned/shared). Like if you're converting from the Unversioned/PDF to Versioned/PDF... the data will not have moved from one table to another
    – MStodd
    Commented Apr 27, 2020 at 17:51
  • @MStodd that's obvious. You cannot change type of the field like that.
    – Marek Musielak
    Commented Apr 28, 2020 at 11:00
5

The Sitecore Rocks extension for VS allows you to select multiple items at once and change their template.

enter image description here

This is useful if all of the items, you want to change the template of, are in the same place.

UPDATE:

If the field names of the templates are different, you can change them on the new template to match the old one's, change the template of the items, and then change the field names back to the original ones.

2
  • 1
    This is only useful for local or instances which we can connect to using Rocks. Just changing the template means we will lose data.
    – jammykam
    Commented Oct 10, 2016 at 10:24
  • 1
    That's true. You could however change the field names of the new template to match the old one's, change the template of the items, and then change the field names back to the original ones. Commented Oct 12, 2016 at 14:22
1

I solved it using TDS(hopefully it's applicable with a unicorn & other serialization). This is a local instance approach. Similar to "adragomanov" answer.

Steps involved below, (Before do this exercise have a back up of template/content items involved here)

  1. Sync all template & content items in TDS.

  2. In Sitecore: Inherit a new-template(Template B) to the existing item template. So the current item will have all the fields from new-template(Template B) & old-template(Template A).

  3. In TDS yaml: Replace your old-template fieldname/Id with new-template fieldname/ID. I used VS code IDE for replace, Its preferred on your own. (If your field names are same in old & new templates. Update only ID.)

  4. Sync the items from TDS, Update to Sitecore. This will copy all your old-template fields to new-template fields.

  5. In Sitecore: Remove the old template inheritance.

Finally , You will have the result of template change & all fields values are copied.

0

Changing the template through content editor or api will retain data where possible.

Scenario 1: Both old and new templates inherit the same base template. The data in the base template fields is retained implicitly.

Scenerio 2: Both old and new template have fields of the same field name. When ChangeTemplate() is invoked, a ChangeList is generated which captures any fields in the target template that that have the same field name as the current template.

The call to Sitecore.Data.DataProviders.Sql.SqlDataProvider.ChangeTemplate(ItemDefinition, TemplateChangeList, CallContext) acts upon the changelist and remaps the existing item fieldIds to the new fieldIds, thus retaining the data in those fields.

enter image description here

enter image description here

You can either change the target template fields to match and perhaps change the display name to what they currently are, or temporarily change the field names, change the item template, then change the template fields back to whatever they were.

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.