我需要在发布项目之前更新Sitecore中的日期-时间字段。当项目实际发布时,这将类似于"发布日期-时间"。我已经在工作流中成功地实现了这一点,通过添加自定义操作,这对工作流中的项目来说很好。
对于不在工作流中并且应该由发布代理拾取的项目,我打开管道,在PerformAction处理器之前添加了一个处理器。该字段在master数据库中得到了很好的更新,但发布代理从未将其发布到web数据库。在字段更新之前具有所有其他值的项都通过了fine。
我试着调试这个问题,感觉它正在发生,因为更新的项目没有作为发布队列的一部分反映出来。有没有一种方法可以强制更新在同一过程中发布的日期-时间字段,而不必强制发布?
欢迎提出任何建议。
您是对的,更新的项目不在发布队列中。您需要将代码放入publish:itemProcessing事件中。您需要遵循以下步骤:
- 将处理程序类添加到
<event name="publish:itemProcessing" help="Receives an argument of type ItemProcessingEventArgs (namespace: Sitecore.Publishing.Pipelines.PublishItem)"/>
您的发布: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>
- 创建自己的类以在发布时处理项目:
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;
}
}
}
}
根据您将使用此日期的目的,也许使用稍微不同的方法会更好。前面的答案是有效的,可能会很好。但是在发布时更新master数据库,可能会让发布引擎认为master项已经更改,需要重新发布。(EventDisabler等将阻止这种情况,并触发重新索引等…事情可能会变得非常棘手)
或者,也可以将发布日期写入web数据库中的项目。
<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;
}
}
}
约翰·韦斯特在这里有一篇关于这方面的博客文章:
http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2011/08/intercept-item-publishing-with-the-sitecore-aspnet-cms.aspx
将发布日期存储在web数据库中,您可以从那里读取,也可以为master数据库创建一个计算索引字段,其中包含web数据库中的日期。
这可能是一个更健壮的解决方案,但同样,这取决于您使用该字段的目的,以及您是否能够控制读取值的代码。