2

I have a doubt regarding the change of datasource template of a sublayout. Now, there are two sublayouts: Sub1 and Sub2 which are having Template1 as their datasource template. Until the time I discovered that i need a different datasource template for Sub1, i had already created many items of sublayouts Sub1 and Sub2.

Template2 will now replace Template1 as datasource template for sublayout Sub1. Now, i have to change the template of all those items that were created with sublayout as Sub1.

The problem is I have to manually change each item's template via content editor--> Configure-->Change Template technique, which is very cumbersome. Is there any other way to change the template of all those items at once ?

nsgocev
  • 4,390
  • 28
  • 37

3 Answers3

5

I suggest you to install Sitecore PowerShell Extensions and to change the template using the Sitecore PowerShell Console.

$master = [Sitecore.Configuration.Factory]::GetDatabase("master");
$entryTemplate = $master.Templates["your path to template Sub2"];
cd master:\Content\Home\Sub1FolderItems\;
//path to sub1 folder items
Get-ChildItem -recurse | ForEach-Object { if ($_.TemplateName -eq "Sub1") {  $_.ChangeTemplate($entryTemplate) } };
Dmytro Shevchenko
  • 33,431
  • 6
  • 51
  • 67
Vlad Iobagiu
  • 4,118
  • 3
  • 13
  • 22
3

As @SitecoreClimber suggested, the best approach to do this is to install Sitecore PowerShell Extensions and fix this with PowerShell. If you don't have admin access or you are not allowed to install PowerShell extensions to your machine, you can use the following .NET code to achieve what you want. Just replace the values of ID variables with the IDs of your templates and sublayouts:

// replace with the first template's ID
ID template1ID = new ID("{A0F73C76-DD4D-4037-90D4-48B616397F5D}");

// replace with the second template's ID
ID template2ID = new ID("{43A1EBB0-CABB-4682-9F5B-7765D7FB0E29}");

// replace with your sublayout's ID
ID sublayout2ID = new ID("{1C6094FA-4539-48E4-A24A-104787641A88}");
Database masterDatabase = Factory.GetDatabase("master");

TemplateItem template2Item = masterDatabase.GetTemplate(template2ID);

// Set to your RootItem
Item rootItem = masterDatabase.GetItem("{756B23C8-1C0F-41AC-9273-B18FDA047925}");

using (new SecurityDisabler())
{
    foreach (Item child in rootItem.Axes.GetDescendants())
    {
        RenderingReference[] renderings = child.Visualization.GetRenderings(Sitecore.Context.Device, true);

        IEnumerable<RenderingReference> sublayout2Renderings =
            renderings.Where(x => x.RenderingID == sublayout2ID);

        foreach (RenderingReference rendering in sublayout2Renderings)
        {
            if (!string.IsNullOrEmpty(rendering.Settings.DataSource))
            {
                Item datasourceItem = masterDatabase.GetItem(rendering.Settings.DataSource);

                if (datasourceItem != null)
                {
                    if (datasourceItem.TemplateID == template1ID)
                    {
                        datasourceItem.ChangeTemplate(template2Item);
                    }
                }
            }
        }
    }
}
Community
  • 1
  • 1
nsgocev
  • 4,390
  • 28
  • 37
  • Yes. I dont want to install Power shell so i am going to try this. One questions though: Template2 is duplicate of Template1, but with one extra field. So i guess the data will not be affected when i replace the template. Am i right ? – Prathamesh dhanawade Dec 02 '15 at 09:28
  • @Prathameshdhanawade Duplicate or Inherited ? – nsgocev Dec 02 '15 at 09:49
  • Template1 and Template inherit from BaseTemplate. I did not want Template1 to have that extra field. So, I Duplicated Template2 from Template1 and added the needed extra field. – Prathamesh dhanawade Dec 02 '15 at 11:19
  • Also, the code you provide need to run only once when template change is required right ? – Prathamesh dhanawade Dec 02 '15 at 11:22
  • @Prathameshdhanawade Should work but give it a test drive on a small subset first. Also it will run and it will change the template only if it was not changed already. If you want to be sure. Just create a backup of the database first before you execute it. – nsgocev Dec 02 '15 at 11:23
  • Ok. Cool. Will try and let you know. – Prathamesh dhanawade Dec 02 '15 at 11:25
  • Just came to my mind that instead of changing template, is there a way to just hide the extra field for sublayout2 (keeping template same for both sublayouts) ?? – Prathamesh dhanawade Dec 02 '15 at 13:17
  • @Prathameshdhanawade define hide the field ? You can just not evaluate it on the frontend :) – nsgocev Dec 02 '15 at 13:20
  • Hiding here means not showing the field for items created with sublayout2. Just curious if we can code through this. Like if the item has sublayout2, then hide the Field !! :-P – Prathamesh dhanawade Dec 02 '15 at 13:35
  • You will invest more time in writing that custom rule than just using an architecture with 2 templates :D – nsgocev Dec 02 '15 at 13:37
3

There is another way - if you have Sitecore Rocks installed, you can multi-select all the items, right click and select Change Template - no code, and pretty quick unless your content items are in many different places.

Richard Seal
  • 4,248
  • 14
  • 29