10

Has anyone got any ideas on how to customise the “choose data source dialog” / pipelines; so that only certain items (by tag or otherwise) are available as the selectable data source?

  • In your scenario, is the user allowed to create a new datasource item, or must they pick from an existing list? – Sergeant Sitecore Oct 24 '16 at 14:17
  • You mean having a custom rendering parameters for the datasource? – Hishaam Namooya Oct 24 '16 at 18:12
7

Prepare for a huge wall of text here which is not tested, but should work in theory and is a perfect blog post material :)

So the easiest way to do this, is to actually act to the unselectable items in the same way that Sitecore reacts to the unselectable templates - i.e. showing a message and telling that this is not a valid choice.

So the first stop should be GetRenderingDataSource Pipeline and GetRenderingDataSourceArgs.

You need to create a Custom GetRenderingDataSourceArgs (inheriting from the existing ones) that will host your custom rules.

After this being applied you need to create a custom processor and plug it in right before <processor type="Sitecore.Pipelines.GetRenderingDatasource.GetDialogUrl, Sitecore.Kernel"/>.

Here you are going to plug your processor that is going to apply your custom rules.

Next step would be to override the GetDialogUrl processor, which is going to spawn the window with the rules applied to it. The problem here is that it uses SelectDatasourceOptions class which is one more point you will need to extend.

So in the Custom SelectDatasourceOptions you need to add a place for your custom rules, override the ToUrlString method and override the Parse Method, so it can parse correct parameters to the window.

After that you need to go back to the GetDialogUrl Processor and pass the new parameter.

Now we hopefully will have the window opened and the custom rules paramaters are going to be passed, so the next stop would be the SelectRenderingDatasourceForm.

Here you will need to have to use your Custom SelectDatasourceOptions as options. In the parse method (which is actually located in the Property for the Options) I am not 100% sure that you will need to do a new override of the SelectItemOptions.Parse<SelectDatasourceOptions>(), but it is most likely the case that you will.

In theory now the data which is passed to the dialog should be handled and you are ready to apply the filtering.

The final thing that needs to happen is for you to override the IsSelectable method in which the actual filtering will happen.

Hope this makes sense !

| improve this answer | |
  • Thanks. Good thorough walkthrough. Should really be a lot simpler than that :-) – Eldblom Oct 25 '16 at 7:50
2

The pipeline that you need to patch is the getRenderingDatasource. Below is the different steps that you will require to implement a custom rendering datasouce:

1. Sublayout

In the sublayout, in the Editor Options Section, there is a field called Datasource Location. In this, you can specify the query you want, below is an example of the query:

query:ancestor-or-self::*[@@templatename='Website']//Catalog Container

Note that the query above needs to have a template called Website then get the Catalog Container.

2. Code

Here, it is where you will insert the logic that you will require to have a custom datasource. As example, the below code will execute and will set the window from where content authors select the item to a specific container. Note that this is dynamic. In other words, let's say you have Site A, B and C and all 3 have a catalog container. The below code will render the datasource and content authors will never be able to select catalog from Site A in Site B or C

public void Process(GetRenderingDatasourceArgs args)
{
    Assert.IsNotNull(args, "args");

    string text = args.RenderingItem["Datasource Location"]; //Get the value from the field  
    if (!string.IsNullOrEmpty(text))
    {
        if (text.StartsWith("query:") && !string.IsNullOrEmpty(args.ContextItemPath))
        {
            var contextItem = args.ContentDatabase.GetItem(args.ContextItemPath);

            if (contextItem != null)
            {
                text = text.Remove(0, 6); //remove the query:  
                var item = contextItem.Axes.SelectSingleItem(text); //Execute the query  

                if (item != null)
                {
                    args.DatasourceRoots.Add(item);
                }
            }
        }
    }
}

To restrict the content authors from selecting other templates, you can set the Datasource Template. This allows content authors to select items which are of the same template as specified in the Datasource Template

3. Config

Now you need to patch the getRenderingDatasource pipeline. Below is how you will need to patch it

<getRenderingDatasource>
    <processor type="YourNamespaceHere, YourAssemblyName"
               patch:before="processor[@type='Sitecore.Pipelines.GetRenderingDatasource.GetDatasourceLocation, Sitecore.Kernel']"/>
</getRenderingDatasource>
| improve this answer | |

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.