5

When a component is added to the page in the Experience Editor, its data source field is empty. The content editor then needs to manually create or select a data source in the "Select the Associated Content" dialog.

To simplify this process, Sitecore allows to show the dialog automatically when a component is added to the page.

I want to take this one step further.

In our solution, data sources are normally stored under every page item. It would be convenient for our content editors if a data source was created automatically for every new component, without even showing the "Select the Associated Content" dialog.

How can this be achieved?

3

2 Answers 2

4

What you actually need to do are two things:

  • Create the datasource item
  • Prevent the dialog from appearing

Creating the datasource is done in the getRenderingDatasource pipeline. Add a processor before the CheckDialogState. In that processor you can put some logic to determine that you actually want to create an item. Once you determined you want to create an item, do so using the Sitecore api (you might need a security disabler and a site switcher). Add the parent to the args.DatasourceRoots. Once the item is created, you have to set it's path in the arguments: args.CurrentDatasource = datasourceItem.Paths.FullPath; (args being the GetRenderingDatasourceArgs).

If you would stop here, the datasource is created and would be shown in the dialog as a prefilled value. It is not filled in

The dialog is a tricky one. Like mentioned in the comments I wrote a blog post on it. What you need to do is override (copy) the command AddRendering (Sitecore.Shell.Applications.WebEdit.Commands.AddRendering). In the run method, before the code where the dialog is opened (ShowModalDialog), you need to adapt the code (if-statement to determine whether to show the dialog or not) and send a WebEditResponse:

WebEditResponse.Eval(FormattableString.Invariant(
    $"Sitecore.PageModes.ChromeManager.handleMessage('chrome:placeholder:controladded', 
        {{ id: '{itemNotNull.ID.Guid.ToString("N").ToUpperInvariant()}', 
           openProperties: {flag.ToString().ToLowerInvariant()}, 
           dataSource: '{datasourceItem.ID.Guid.ToString("B").ToUpperInvariant()}' }});"));

This way the dialog won't open and the Sitecore editor is still notified that a rendering was added (with the datasource). Without that notification, the rendering will not be added.

ps: it is probably also possible to include the item creation in the addrendering command - didn't test that

Update: links to github repo and marketplace module containing this:

1
4

Just to add to the discussion, in SXA they only use getRenderingDatasource to create the Page data folder and adding the global and page data items to the DatasourceRoots object.

SXA creates the datasource item automatically in the Add rendering command. You can find the code in the assembly Sitecore.XA.Foundation.Editing in the function Sitecore.XA.Foundation.Editing.Commands.AddRendering.

The line where they actually create the item, after several if statements is

Item item4 = getRenderingDatasourceArgs.Prototype.InheritsFrom(TemplateIDs.BranchTemplate) ? Context.Workflow.AddItem(text2, getRenderingDatasourceArgs.Prototype, item3) : Context.Workflow.AddItem(text2, getRenderingDatasourceArgs.Prototype, item3);

then the event to assign it to the datasource and handle the page event.

string fullPath = item4.Paths.FullPath;
string arg = fullPath.StartsWith(getRenderingDatasourceArgs.ContextItemPath) ? ("local:" + fullPath.Substring(getRenderingDatasourceArgs.ContextItemPath.Length)) : item4.ID.ToString();
this.HandleResponse("'chrome:placeholder:controladded'", string.Format("{{ id: '{0}', openProperties: {1}, dataSource: '{2}' }}", itemNotNull.ID.ToShortID(), flag7.ToString().ToLowerInvariant(), arg), flag);

The command config is here.

<command name="webedit:addrendering" type="Sitecore.XA.Foundation.Editing.Commands.AddRendering, Sitecore.XA.Foundation.Editing" patch:source="Sitecore.XA.Foundation.Editing.config"/>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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