渲染项目的自定义数据源

Custom Data Source on Rendering Items

我有一个 Sitecore 8 MVC 解决方案,我必须扩展数据源的行为。它与其他人之前对可查询数据源所做的非常相似(例如 http://www.cognifide.com/blogs/sitecore/reduce-multisite-chaos-with-sitecore-queries/ 等),但我已经连接到 <mvc.getXmlBasedLayoutDefinition> 管道。它工作正常,我的自定义数据源在项目或标准值的布局字段中输入时得到解析。

但是,当自定义数据源被指定为渲染项上的默认数据源时,事情就变得有点棘手了。我可以通过相同的管道解决它,但该解决方案看起来不太好。这意味着我必须加载布局中未指定数据源的每个渲染,并从那里进行处理和解析。必须有一种更自然的方式来做到这一点。

有谁知道默认数据源的这种实现逻辑放在哪里? (<resolveRenderingDatasource> 管道看起来很有希望,但在这种情况下没有执行)

据我了解,您可能想要扩展 XmlBasedRenderingParser class。以下是解决问题的步骤:

  1. 创建一个新文件App_Config\include\Sitecore.Mvc.Custom.config:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor
          patch:after="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']"
          type="My.Assembly.Namespace.RegisterCustomXmlBasedRenderingParser, My.Assembly"/>
      </initialize>
    </pipelines>
  </sitecore>
</configuration>
  1. 创建CustomXmlBasedRenderingParserclass:
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Extensions;
using Sitecore.Mvc.Presentation;

namespace My.Assembly.Namespace
{
    public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
    {
        protected override void AddRenderingItemProperties(Rendering rendering)
        {
            RenderingItem renderingItem = rendering.RenderingItem;
            if (renderingItem != null && !rendering.DataSource.ContainsText())
            {
                rendering.DataSource = ResolveRenderingItemDataSource(renderingItem);
            }
            base.AddRenderingItemProperties(rendering);
        }

        private static string ResolveRenderingItemDataSource(RenderingItem renderingItem)
        {
            string dataSource = string.Empty;
            if (renderingItem.DataSource != null && renderingItem.DataSource.StartsWith("query:"))
            {
                string query = renderingItem.DataSource.Substring("query:".Length);
                Item contextItem = Context.Item;
                Item queryItem = contextItem.Axes.SelectSingleItem(query);
                if (queryItem != null)
                {
                    dataSource = queryItem.Paths.FullPath;
                }
            }
            return dataSource;
        }
    }
}
  1. 创建 RegisterCustomXmlBasedRenderingParser class:
using Sitecore.Mvc.Configuration;
using Sitecore.Mvc.Presentation;
using Sitecore.Pipelines;

namespace My.Assembly.Namespace
{
    public class RegisterCustomXmlBasedRenderingParser
    {
        public virtual void Process(PipelineArgs args)
        {
            MvcSettings.RegisterObject<XmlBasedRenderingParser>(() => new CustomXmlBasedRenderingParser());
        }
    }
}

此外,如果您希望您的代码针对渲染和演示详细信息中定义的 DataSource 执行,您应该能够使用以下代码:

using System.Xml.Linq;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;

namespace My.Assembly.Namespace
{
    public class CustomXmlBasedRenderingParser : XmlBasedRenderingParser
    {
        public override Rendering Parse(XElement node, bool parseChildNodes)
        {
            Rendering rendering = base.Parse(node, parseChildNodes);
            ResolveRenderingItemDataSource(rendering);
            return rendering;
        }

        private static void ResolveRenderingItemDataSource(Rendering rendering)
        {
            if (rendering.DataSource != null && rendering.DataSource.StartsWith("query:"))
            {
                string query = rendering.DataSource.Substring("query:".Length);
                Item contextItem = Context.Item;
                Item queryItem = contextItem.Axes.SelectSingleItem(query);
                if (queryItem != null)
                {
                    rendering.DataSource = queryItem.Paths.FullPath;
                }
            }
        }
    }
}

请记住,此代码未经过正确测试,可能无法在您的环境中开箱即用。无论如何,我希望它至少能给你一个很好的指示。