5

I have created a template with multi list type field. I have create a branch template to enforce child element to this multi list.

I have set data source query:./* to populate children in this multi list field.

My requirement is when I create content from branch template the child element should appear in selected list box (right side box).

How to do this?

  • Do you want every item of this template to have a different default list element selected? If so, you need a custom pipeline processor to do that. But, if it was OK for you to have this default element to be the same for all items, then it's easy to do. Create that item in a separate folder, then modify the Standard Values of your template to include the item in the "selected" part of the list. – Dmytro Shevchenko Nov 28 '16 at 5:50
  • @DmytroShevchenko I think he is creating the child elements using the branch template itself – scFootsteps Nov 28 '16 at 7:00
  • @scFootsteps Yes, that's how I understood it as well. – Dmytro Shevchenko Nov 28 '16 at 7:01
  • yes I am creating child element using branch template. so when I create an item using branch template, there will always be at least one sub item. – Naresh Saini Nov 28 '16 at 8:14
  • @NareshSaini Have you thought about linking all items of this template to the same default list item? – Dmytro Shevchenko Nov 28 '16 at 9:19
6

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.

|improve this answer|||||
0

If I am understanding right you are looking to have the child elements of a specific item preselected when you create the list.

Item    
|_Subitem    
|_Subitem

and your list on item will automatically have both Subitems selected.

The main issue I see with this is that the Item when created would have 0 children and so nothing to preselect.

If you want it to automatically select a subitem when created then you will need to look into a custom pipeline process on item creation.

Something that would check the parent item if it matches a specific template and then add the id of the current item to the field on the parent item.

|improve this answer|||||
  • 1
    The OP has mentioned he's using a branch template, so there will always be at least one subitem. – Dmytro Shevchenko Nov 28 '16 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.