The Problem
You cannot. Not out of the box at least.
What happens is; your branch template looks like this:
Branch Root (ID1)
|_Subitem (ID 2)
|_Subitem (ID 3)
And on the Branch Item, you select 1 or more of the Subitems. This means, on Branch Item, the Multilist field holds ID 2
and ID 3
as value.
Now you go and create content based on this Branch. Your new content will get created, and look like this:
Concrete Item (ID4)
|_Subitem (ID 5)
|_Subitem (ID 6)
But - and here's the kicker - The Multilist field will still hold ID 2
and ID 3
as value.
Sitecore does not remap internal references on this field (or any) when creating the branch.
The Sitecore "out of the box" story ends here.
The Solution
To solve it, you need a job that replaces references when creating items based off of Branch Templates. And you only want references replaced, when the items being referenced are within scope of the Branch Template items themselves.
Fortunately, this is what Alen Pelin's SmartCommands does (reference: https://bitbucket.org/sitecore/sitecore-smart-commands) - except these only work for Copy, Clone and Duplicate. They can be extended however.
Set it up
Create a file, BranchCommand.config
and place it in App_Config\Include
.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="item:added">
<handler type="Website.Events.ItemAdded.UpdateLinks, Website" method="OnItemAdded">
<param desc="async">false</param>
</handler>
</event>
</events>
</sitecore>
</configuration>
Then some code to bind this event into SmartCommands (you must have the SmartCommand code in your project as well, download from above).
UpdateLinks.cs
public class UpdateLinks
{
private readonly bool isAsync;
public UpdateLinks()
{
isAsync = false;
}
public UpdateLinks([NotNull] string async)
{
Assert.ArgumentNotNull(async, "async");
isAsync = string.Equals(async, "true", StringComparison.OrdinalIgnoreCase);
}
[UsedImplicitly]
public void OnItemAdded([CanBeNull] object sender, [NotNull] EventArgs args)
{
Assert.ArgumentNotNull(args, "args");
var contentItem = Event.ExtractParameter(args, 0) as Item;
Assert.IsNotNull(contentItem, "targetItem");
var branchItem = contentItem.Branch;
if (branchItem == null)
{
return;
}
var item = branchItem.InnerItem;
Assert.IsTrue(item.Children.Count == 1, "branch item structure is corrupted: {0}".FormatWith(AuditFormatter.FormatItem(item)));
var branch = item.Children[0];
if (isAsync)
{
ReferenceReplacementJob.StartAsync(branch, contentItem);
}
else
{
ReferenceReplacementJob.Start(branch, contentItem);
}
}
}
And from here, the SmartCommands ReferenceReplacementJob
takes care of the rest. The code for that and the rest of SmartCommands would be too extensive to include here. Source for ReferenceReplacementJob.
I've used exactly this approach on a number of production solutions - it is tested and it does work as expected - but it will require some elbow grease to get working in your solution.