发布前的 Sitecore 更新字段
Sitecore update field just before publish
我需要在发布项目之前更新 Sitecore 中的日期时间字段。当项目实际发布时,这将像 "publish date time" 一样。我已经在工作流中成功实现了这一点,并且通过添加自定义操作可以很好地处理工作流中的项目。
对于不在工作流中但应由发布代理选取的项目,我进入了管道并在 PerformAction 处理器之前添加了一个处理器。该字段在 master 数据库中更新良好,但发布代理从未将其发布到 Web 数据库。在字段更新之前具有所有其他值的项目正常。
我已尝试调试该问题并感觉它正在发生,因为更新的项目未反映为发布队列的一部分。有没有一种方法可以强制更新也在同一进程中发布的日期时间字段,而不必强制它发布?
欢迎提出任何建议。
你是对的,更新的项目不在发布队列中。您需要将代码放入 publish:itemProcessing 事件中。
您需要执行后续步骤:
- 将处理程序 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>
- 创建您自己的 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:
将发布日期存储在网络数据库中,您可以从那里读取它,或者为主数据库创建一个计算索引字段,而不是包含来自网络数据库的日期。
这可能是一个更可靠的解决方案,但同样,这取决于您使用该字段的目的以及您是否可以控制读取该值的代码。
我需要在发布项目之前更新 Sitecore 中的日期时间字段。当项目实际发布时,这将像 "publish date time" 一样。我已经在工作流中成功实现了这一点,并且通过添加自定义操作可以很好地处理工作流中的项目。
对于不在工作流中但应由发布代理选取的项目,我进入了管道并在 PerformAction 处理器之前添加了一个处理器。该字段在 master 数据库中更新良好,但发布代理从未将其发布到 Web 数据库。在字段更新之前具有所有其他值的项目正常。
我已尝试调试该问题并感觉它正在发生,因为更新的项目未反映为发布队列的一部分。有没有一种方法可以强制更新也在同一进程中发布的日期时间字段,而不必强制它发布?
欢迎提出任何建议。
你是对的,更新的项目不在发布队列中。您需要将代码放入 publish:itemProcessing 事件中。 您需要执行后续步骤:
- 将处理程序 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>
- 创建您自己的 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:
将发布日期存储在网络数据库中,您可以从那里读取它,或者为主数据库创建一个计算索引字段,而不是包含来自网络数据库的日期。
这可能是一个更可靠的解决方案,但同样,这取决于您使用该字段的目的以及您是否可以控制读取该值的代码。