发布前的 Sitecore 更新字段

Sitecore update field just before publish

我需要在发布项目之前更新 Sitecore 中的日期时间字段。当项目实际发布时,这将像 "publish date time" 一样。我已经在工作流中成功实现了这一点,并且通过添加自定义操作可以很好地处理工作流中的项目。

对于不在工作流中但应由发布代理选取的项目,我进入了管道并在 PerformAction 处理器之前添加了一个处理器。该字段在 master 数据库中更新良好,但发布代理从未将其发布到 Web 数据库。在字段更新之前具有所有其他值的项目正常。

我已尝试调试该问题并感觉它正在发生,因为更新的项目未反映为发布队列的一部分。有没有一种方法可以强制更新也在同一进程中发布的日期时间字段,而不必强制它发布?

欢迎提出任何建议。

你是对的,更新的项目不在发布队列中。您需要将代码放入 publish:itemProcessing 事件中。 您需要执行后续步骤:

  1. 将处理程序 class 添加到
<event name="publish:itemProcessing" help="Receives an argument of type ItemProcessingEventArgs (namespace: Sitecore.Publishing.Pipelines.PublishItem)"/>

您的 publish:itemProcessing 活动将如下所示

    <event name="publish:itemProcessing" help="Receives an argument of type ItemProcessingEventArgs (namespace: Sitecore.Publishing.Pipelines.PublishItem)">
        <handler type="YourNameSpace.SetPublishDate, YourAssembly" method="UpdatePublishingDate"/>
    </event>
  1. 创建您自己的 class 以在发布时处理项目:
    public class SetPublishDate
    {
    /// <summary>
    /// Gets from date.
    /// </summary>
    /// <value>From date.</value>
    public DateTime FromDate { get; set; }

    /// <summary>
    /// Gets to date.
    /// </summary>
    /// <value>To date.</value>
    public DateTime ToDate { get; set; }

    public void UpdatePublishingDate(object sender, EventArgs args)
    {
        var arguments = args as Sitecore.Publishing.Pipelines.PublishItem.ItemProcessingEventArgs;
        var db = Sitecore.Configuration.Factory.GetDatabase("master");
        Item item = db.GetItem(arguments.Context.ItemId);
        if (item != null)
        {
            using (new Sitecore.Data.Events.EventDisabler())
            {
                using (new EditContext(item))
                {
                    //PublishDateFieldName must be datetime field
                    item["PublishDateFieldName"] = DateTime.Now;
                }
            }
        }
    }

根据您打算将此日期用于什么目的,采用稍微不同的方法可能会更好。以前的答案是有效的,可能会工作得很好。但是在发布时更新主数据库,可能会让发布引擎认为主条目已经改变,需要重新发布。 (EventDisabler 等将阻止这种情况,以及触发重新索引等......事情可能会变得非常棘手)

或者,您可以将发布日期写在网络数据库中的项目上。

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <publishItem>
        <processor type="Sitecore.Publishing.Pipelines.PublishItem.PerformAction, Sitecore.Kernel">
          <patch:attribute name="type">Your.Namespace.PerformAction, Your.Assembly</patch:attribute>
        </processor>
      </publishItem>
    </pipelines>
  </sitecore>
</configuration>

以及类似于此的实现:

public class PerformAction : Sitecore.Publishing.Pipelines.PublishItem.PerformAction
{
    public override void Process(PublishItemContext context)
    {
        base.Process(context);

        if (context.Aborted || context.VersionToPublish == null || context.VersionToPublish.Source == null)
            return;

        var target = context.PublishOptions.TargetDatabase.GetItem(context.VersionToPublish.ID, context.VersionToPublish.Language);

        if (target == null)
            return;

        using (new EditContext(target, false /*updateStatistics*/, true /*silent*/))
        {
            DateField lastPublished = target.Fields["LastPublished"]
            lastPublished.Value = Sitecore.DateUtil.IsoNo;
        }
    }
}

约翰·韦斯特 (John West) 在这里有一个博客 post:

http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2011/08/intercept-item-publishing-with-the-sitecore-aspnet-cms.aspx

将发布日期存储在网络数据库中,您可以从那里读取它,或者为主数据库创建一个计算索引字段,而不是包含来自网络数据库的日期。

这可能是一个更可靠的解决方案,但同样,这取决于您使用该字段的目的以及您是否可以控制读取该值的代码。