How to use sitecore query in datasource location? (dynamic datasource)
Asked Answered
P

1

5

Is it possible to set the datasource location (not the datasource) to be a sitecore query?

What I'm trying to do is to have the sublayout set its datasource location to a folder under the item containing it (current item).

The sublayout datasource location should point to a folder under the current item. So I tried setting the datasource location to query:./Items/* but that did not work.

Predictor answered 6/10, 2011 at 18:7 Comment(0)
W
10

You don't need the query -- the sublayout datasource location can simply use a relative path. e.g.

./Items

Obviously though, that folder needs to exist already. I've been meaning to blog this code, and it may be overkill but I'll post here since it may help you. The following can be added to the getRenderingDatasource pipeline to create a relative path datasource location if it doesn't exist already. Add it before the GetDatasourceLocation processor.

On the sublayout, you'll want to add a parameter contentFolderTemplate=[GUID] to specify the template of the item that gets created.

public class CreateContentFolder
{
    protected const string CONTENT_FOLDER_TEMPLATE_PARAM = "contentFolderTemplate";

    public void Process(GetRenderingDatasourceArgs args)
    {
        Assert.IsNotNull(args, "args");
        Sitecore.Data.Items.RenderingItem rendering = new Sitecore.Data.Items.RenderingItem(args.RenderingItem);
        UrlString urlString = new UrlString(rendering.Parameters);
        var contentFolder = urlString.Parameters[CONTENT_FOLDER_TEMPLATE_PARAM];
        if (string.IsNullOrEmpty(contentFolder))
        {
            return;
        }
        if (!ID.IsID(contentFolder))
        {
            Log.Warn(string.Format("{0} for Rendering {1} contains improperly formatted ID: {2}", CONTENT_FOLDER_TEMPLATE_PARAM, args.RenderingItem.Name, contentFolder), this);
            return;
        }

        string text = args.RenderingItem["Datasource Location"];
        if (!string.IsNullOrEmpty(text))
        {
            if (text.StartsWith("./") && !string.IsNullOrEmpty(args.ContextItemPath))
            {
                var itemPath = args.ContextItemPath + text.Remove(0, 1);
                var item = args.ContentDatabase.GetItem(itemPath);
                var contextItem = args.ContentDatabase.GetItem(args.ContextItemPath);
                if (item == null && contextItem != null)
                {
                    string itemName = text.Remove(0, 2);
                    //if we create an item in the current site context, the WebEditRibbonForm will see an ItemSaved event and think it needs to reload the page
                    using (new SiteContextSwitcher(SiteContextFactory.GetSiteContext("system")))
                    {
                        contextItem.Add(itemName, new TemplateID(ID.Parse(contentFolder)));
                    }
                }
            }
        }
    }
}
Wittgenstein answered 6/10, 2011 at 23:27 Comment(2)
@techphoria414 What version of Sitecore were you using to support the relative pathing on the sublayout datasource? This is something I've been wanting to do for a few projects...Riverine
6.4.1, though this is on the Datasource Location of the sublayout, which is used by the Page Editor. After the item is chosen, it's still an absolute path (which we change to a GUID in an item:saving handler). If you wanted to support relative paths in a datasource in general, you could customize the SublayoutParamHelper utility class (or your version of it) to do a Sitecore Query instead of a GetItem.Wittgenstein

© 2022 - 2024 — McMap. All rights reserved.