I'm creating a branch where my home item has three drop link fields for navigation. I'm also creating the starting point for the three navigation paths in my branch. However, pre-setting the drop link fields to these navigation paths doesn't work correctly, because when the branch is created, it's referencing the original branch item, not the solution item. I'm looking for a way to properly replace these datasources at branch creation time.
2 Answers
There isn't an OOTB way to achieve this.
But. I always use Alen Pelin's SmartCommands. Included in this package is "Smart Create From Branch" which does what you need.
Having this branch template
my branch $name: linkField -> branchChild branchChild: linkField -> $name
by default, the item created from this branch template becomes
createdItem: linkField -> branchChild createdChild: linkField -> $name
With smart link replacement it becomes expected:
createdItem: linkField -> createdChild createdChild -> createdItem
-
This looks cool; I've never used it. Does it really break Item Buckets? Is there any way to use some of it without breaking bucketing? Commented Oct 15, 2018 at 14:43
-
1Well I run my own customised set of these commands. I think Alen originally only made these to solve some issues around Item Cloning - and as extra commands. But I patch these commands in to replace the default item:copy and item:duplicate commands and have never had an issue. If indeed they do mess with buckets, it would be very little code to just abort if item.IsBucket or whatever that property is.– Mark Cassidy ♦Commented Oct 15, 2018 at 14:53
There are two possible solutions:
Not great: change the fields' type to Drop List
This will work because the names of the items underneath the relative navigation paths will be the same.
Disclaimer: This has a bad code smell. The home item no longer relates directly to an item with ID. If the selected item is moved or has its name changed, the reference is lost. (It's also more expensive to get the related item because you have to get the parent and then find the child by a specific name, vs just getting the item by ID for a Drop Link.)
Better: update the home item with code after it's created
You can attach to the item:created
event and add your own code to set your field values.
Create a custom class to perform the reference updates:
public class SetHomeItemNavigationItems : EventBase { public void ItemCreated(object sender, EventArgs args) { var itemCreatedArgs = Event.ExtractParameter(args, 0) as ItemCreatedEventArgs; Assert.IsNotNull(itemCreatedArgs, nameof(itemCreatedArgs)); if (itemCreatedArgs?.Item == null) return; // If this item is being created in a different database (e.g. "web" because it's being published), ignore it if (!"master".Equals(itemCreatedArgs.Item?.Database?.Name, StringComparison.OrdinalIgnoreCase)) return; using (new DatabaseSwitcher(itemCreatedArgs.Item.Database)) { if (itemCreatedArgs.Item.TemplateID == new ID("{home-page-id}")) { itemCreatedArgs.Item.Editing.BeginEdit(); itemCreatedArgs.Item.Fields["Navigation Field 1"].Value = // get navigation item 1 itemCreatedArgs.Item.Fields["Navigation Field 2"].Value = // get navigation item 2 itemCreatedArgs.Item.Fields["Navigation Field 3"].Value = // get navigation item 3 itemCreatedArgs.Item.Editing.EndEdit(); } } } }
Add a patch config file to enable your event handler:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <events> <event name="item:created"> <handler type="Custom.Events.ItemCreated.SetHomeItemNavigationItems,Custom" method="ItemCreated" /> </event> </events> </sitecore> </configuration>