Sitecore Fundamentals: Branch Template

What is a Branch Template?
In Sitecore Branch templates are a way to create content or item hierarchies automatically. With the help of branch templates the Content Editor can create an entire content sub-tree automatically with a single click when inserting a page/item in a Sitecore content tree. They can be thought of as a recipe a Content Editor can rely on to quickly build a frequently used content hierarchy which can save a lot of time especially if the hierarchy is complex.

A branch template contains an item that defines the branch template. This item branch template definition item is based on the /sitecore/templates/System/Branches/Branch template and it can contain zero or more item hierarchies. When a branch template is invoked, the items under the branch template definition item are duplicated at the point of insertion. Sitecore also performs token substitution ($name, $id, $date, $parentname, etc.) on item names and field values at the time of duplication.

Creating a Branch Template

Step 1: Select the /Sitecore/Template/Branches node. Right click and click on Insert and you should see an option create a “New Branch”, “Branch Folder”, “Command Template” or “Insert from template”. We’ll focus on the first two options. The “Branch Folder” option just creates Branch which can be used to keep things organized in a multi-site scenario. The New Branch option is what is used to actually create a branch template.

Step 2: Clicking on the New Branch option in Step 1 will open a dialog box to select the template you want to create a branch template for. After selecting the template click on the Create button.

You should now see a new node bearing the same name as the template you chose with another item under it of the chosen template type. In our our example we chose a Category Page Template so we have Category Page and an item of type Category Page with the $name token which will get replaced at the time of branch template use.

Step 3: Now, using branch template to insert a single item is of very little use. Lets add a couple of items under the $name node to create a simple hierarchy as shown in the figure. We created a folder called Local Assets and a component of type ContentBlock under the Local Assets folder. This hierarchy can be anything you like. Another thing to reemphasize is that you are not limited to a single hierarchy but you can have multiple hierarchies if the scenario needs it.

Using a Branch Template
Now comes the fun part. The content editor doesn’t need to do anything explicit to invoke the branch template aspect. They just need to insert the Category Page as usual but this time the content hierarchy gets created for them automatically.

The newly created hierarchy based on the branch template looks like this:

Sitecore Publishing an Item in Multiple Languages

We have a multi-lingual Sitecore site with an inRiver PIM connector. The connector is responsible for adding and updating the PIM entities (products, images, pdfs, category nodes, etc.) in the Sitecore content tree. It does not publish products or images or category nodes after importing data from the PIM by default and relies on scheduled publishing to the Web Database. But the client wanted an automatic publish in certain scenarios so we created a Sitecore publishing helper class that the connector can call when it needs to publish.

I borrowed some code from Brian Pedersen to do this. I had to adapt it a bit to handle multiple languages but after my changes it did not work as I expected. I was trying to create the Publisher and PublishOptions once and change the Language in a loop. But it didn’t work as I expected. It wasn’t publishing my secondary languages. I had to move the Publisher and PublishOptions instantiations within the loop. I wonder if the original Language is somehow held on to by the PublishOptions even after I explicitly set it.

TLDR: premature optimization is the root of all evil

Not Working Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public static class SitecoreHelper
    {
        public static void PublishItem(Item item, bool clearCache = false)
        {
            // The publishOptions determine the source and target database,
            // the publish mode and language, and the publish date
            var webDb = Database.GetDatabase("web");
           
            PublishOptions publishOptions = new PublishOptions(item.Database,
                                                                  webDb,
                                                                  PublishMode.SingleItem,
                                                                  item.Language,
                                                                  System.DateTime.Now);  // Create a publisher with the publishoptions

            Publisher publisher = new Publisher(publishOptions);

            // Choose where to publish from
            publisher.Options.RootItem = item;
       
            // Publish children as well?
            publisher.Options.Deep = true;

            // Publish mode
            publisher.Options.Mode = PublishMode.Full;

            foreach (var lang in item.Languages)
            {
                //set the language
                publisher.Options.Langauge = lang;

                // Do the publish!
                publisher.Publish();
                Utils.LogAction(string.Format("Published item {0} ({1}) to web in {2}", item.ID.Guid.ToString("B"), item.Name, lang.GetDisplayName()), ApiType.Sitecore, "SitecoreHelper.PublishItem");
            }

            if(clearCache)
            {
                ClearSitecoreDatabaseCache(item.Database);
            }
        }

        private static void ClearSitecoreDatabaseCache(Database db)
        {
            db.Caches.ItemCache.Clear();
            db.Caches.DataCache.Clear();

            //Clear prefetch cache
            foreach (var cache in CacheManager.GetAllCaches())
            {
                if (cache.Name.Contains(string.Format("Prefetch data({0})", db.Name)))
                {
                    cache.Clear();
                }
            }
        }

Working Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public static class SitecoreHelper
    {
        public static void PublishItem(Item item, bool clearCache = false)
        {
            // The publishOptions determine the source and target database,
            // the publish mode and language, and the publish date
            var webDb = Database.GetDatabase("web");
           
            foreach (var lang in item.Languages)
            {
                PublishOptions publishOptions = new PublishOptions(item.Database,
                                                                  webDb,
                                                                  PublishMode.SingleItem,
                                                                  lang,
                                                                  System.DateTime.Now);  // Create a publisher with the publishoptions

                Publisher publisher = new Publisher(publishOptions);

                // Choose where to publish from
                publisher.Options.RootItem = item;

                // Publish children as well?
                publisher.Options.Deep = true;

                publisher.Options.Mode = PublishMode.Full;
                publisher.Options.Language = lang;

                // Do the publish!
                publisher.Publish();
                Utils.LogAction(string.Format("Published item {0} ({1}) to web in {2}", item.ID.Guid.ToString("B"), item.Name, lang.GetDisplayName()), ApiType.Sitecore, "SitecoreHelper.PublishItem");
            }
            if(clearCache)
            {
                ClearSitecoreDatabaseCache(item.Database);
            }
        }

        private static void ClearSitecoreDatabaseCache(Database db)
        {
            // clear html cache
           
            db.Caches.ItemCache.Clear();
            db.Caches.DataCache.Clear();

            //Clear prefetch cache
            foreach (var cache in CacheManager.GetAllCaches())
            {
                if (cache.Name.Contains(string.Format("Prefetch data({0})", db.Name)))
                {
                    cache.Clear();
                }
            }
        }