即使在 InDesign 中编辑,Sitecore PXM/APS 中使用的内容能否受工作流控制?
Can content used in Sitecore PXM/APS be controlled by workflow even when edited in InDesign?
背景
我在 Sitecore Print Experience Manager (PXM*) 项目中使用由工作流控制的内容。 PXM 的一项重要功能是能够在从 InDesign 查看流式内容时将内容更改保存回 Sitecore。
问题
不幸的是,当将内容项保存回 Sitecore 时,它保存了数据,但没有参与该项目的工作流程。
问题
有没有办法将工作流程与 Sitecore PXM InDesign 连接器结合起来?
*以前称为 Adaptive Print Studio,或 APS
PXM 不支持开箱即用。但是,在 Mark Demeny at Sitecore, I was able to create a workable solution. I made a video demonstrating how it works.
的帮助下
item:saving 事件
我向 Sitecore 的 item:saving 事件添加了一个事件处理程序,该事件处理程序拦截来自 InDesign 的对处于最终工作流状态的内容项的保存,添加新版本,将更改应用到该版本,保存该版本, 并取消原来的存档。
SaveProcessor.cs
public class SaveProcessor
{
private Template _StandardTemplate;
private const string PRINT_STUDIO_SITE_NAME = "printstudio";
private static readonly List<Guid> _ActiveItemIds = new List<Guid>();
public void OnItemSaving(object sender, EventArgs args)
{
// Only intercept updates from PXM
if (Context.Site.Name.Equals(PRINT_STUDIO_SITE_NAME))
{
var sitecoreEventArgs = args as SitecoreEventArgs;
var updatedItem = sitecoreEventArgs?.Parameters[0] as Item;
if (updatedItem != null)
{
// If we're already working with this item, allow this save to continue normally (prevents infinite recursion)
if (!_ActiveItemIds.Contains(updatedItem.ID.Guid))
{
var originalItem = Context.Database.GetItem(updatedItem.ID);
if (originalItem != null)
{
var workflow = Context.Database.WorkflowProvider.GetWorkflow(originalItem);
var workflowState = workflow?.GetState(originalItem);
// If the current item is not in workflow, or it is in workflow but the current state is not final, allow the save to continue normally
if (workflowState != null && workflowState.FinalState)
{
var differences = new Dictionary<string, string>();
foreach (Field field in updatedItem.Fields)
{
var updatedItemField = updatedItem.Fields[field.ID];
var originalItemField = originalItem.Fields[field.ID];
// Find all the differences that are not standard fields
if (updatedItemField != null &&
!IsStandardField(updatedItemField) &&
originalItemField != null &&
!updatedItemField.Value.Equals(originalItemField.Value))
{
differences.Add(field.Name, updatedItemField.Value);
}
}
// If there are no differences, allow the save to continue normally
if (differences.Count > 0)
{
// Add this item ID to the list of currently-processing item IDs
_ActiveItemIds.Add(updatedItem.ID.Guid);
try
{
originalItem.Editing.BeginEdit();
var newVersion = originalItem.Versions.AddVersion();
newVersion.Editing.BeginEdit();
foreach (var difference in differences)
{
newVersion[difference.Key] = difference.Value;
}
newVersion.Editing.EndEdit();
originalItem.Editing.EndEdit();
}
finally
{
// Remove this item ID from the list of currently-processing item IDs
_ActiveItemIds.Remove(updatedItem.ID.Guid);
}
sitecoreEventArgs.Result.Cancel = true;
}
}
}
}
}
}
}
public bool IsStandardField(Field field)
{
if (_StandardTemplate == null)
_StandardTemplate = TemplateManager.GetTemplate(Sitecore.Configuration.Settings.DefaultBaseTemplate, field.Database);
return _StandardTemplate.ContainsField(field.ID);
}
}
您还需要修补 web.config 文件才能使用新的事件处理程序。
App_Config\Include\SaveProcessor.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="item:saving">
<handler type="TestPxm.Pxm.SaveProcessor,TestPxm" method="OnItemSaving" patch:before="handler[@type='Sitecore.Tasks.ItemEventHandler, Sitecore.Kernel']"/>
</event>
</events>
</sitecore>
</configuration>
背景
我在 Sitecore Print Experience Manager (PXM*) 项目中使用由工作流控制的内容。 PXM 的一项重要功能是能够在从 InDesign 查看流式内容时将内容更改保存回 Sitecore。
问题
不幸的是,当将内容项保存回 Sitecore 时,它保存了数据,但没有参与该项目的工作流程。
问题
有没有办法将工作流程与 Sitecore PXM InDesign 连接器结合起来?
*以前称为 Adaptive Print Studio,或 APS
PXM 不支持开箱即用。但是,在 Mark Demeny at Sitecore, I was able to create a workable solution. I made a video demonstrating how it works.
的帮助下item:saving 事件
我向 Sitecore 的 item:saving 事件添加了一个事件处理程序,该事件处理程序拦截来自 InDesign 的对处于最终工作流状态的内容项的保存,添加新版本,将更改应用到该版本,保存该版本, 并取消原来的存档。
SaveProcessor.cs
public class SaveProcessor
{
private Template _StandardTemplate;
private const string PRINT_STUDIO_SITE_NAME = "printstudio";
private static readonly List<Guid> _ActiveItemIds = new List<Guid>();
public void OnItemSaving(object sender, EventArgs args)
{
// Only intercept updates from PXM
if (Context.Site.Name.Equals(PRINT_STUDIO_SITE_NAME))
{
var sitecoreEventArgs = args as SitecoreEventArgs;
var updatedItem = sitecoreEventArgs?.Parameters[0] as Item;
if (updatedItem != null)
{
// If we're already working with this item, allow this save to continue normally (prevents infinite recursion)
if (!_ActiveItemIds.Contains(updatedItem.ID.Guid))
{
var originalItem = Context.Database.GetItem(updatedItem.ID);
if (originalItem != null)
{
var workflow = Context.Database.WorkflowProvider.GetWorkflow(originalItem);
var workflowState = workflow?.GetState(originalItem);
// If the current item is not in workflow, or it is in workflow but the current state is not final, allow the save to continue normally
if (workflowState != null && workflowState.FinalState)
{
var differences = new Dictionary<string, string>();
foreach (Field field in updatedItem.Fields)
{
var updatedItemField = updatedItem.Fields[field.ID];
var originalItemField = originalItem.Fields[field.ID];
// Find all the differences that are not standard fields
if (updatedItemField != null &&
!IsStandardField(updatedItemField) &&
originalItemField != null &&
!updatedItemField.Value.Equals(originalItemField.Value))
{
differences.Add(field.Name, updatedItemField.Value);
}
}
// If there are no differences, allow the save to continue normally
if (differences.Count > 0)
{
// Add this item ID to the list of currently-processing item IDs
_ActiveItemIds.Add(updatedItem.ID.Guid);
try
{
originalItem.Editing.BeginEdit();
var newVersion = originalItem.Versions.AddVersion();
newVersion.Editing.BeginEdit();
foreach (var difference in differences)
{
newVersion[difference.Key] = difference.Value;
}
newVersion.Editing.EndEdit();
originalItem.Editing.EndEdit();
}
finally
{
// Remove this item ID from the list of currently-processing item IDs
_ActiveItemIds.Remove(updatedItem.ID.Guid);
}
sitecoreEventArgs.Result.Cancel = true;
}
}
}
}
}
}
}
public bool IsStandardField(Field field)
{
if (_StandardTemplate == null)
_StandardTemplate = TemplateManager.GetTemplate(Sitecore.Configuration.Settings.DefaultBaseTemplate, field.Database);
return _StandardTemplate.ContainsField(field.ID);
}
}
您还需要修补 web.config 文件才能使用新的事件处理程序。
App_Config\Include\SaveProcessor.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="item:saving">
<handler type="TestPxm.Pxm.SaveProcessor,TestPxm" method="OnItemSaving" patch:before="handler[@type='Sitecore.Tasks.ItemEventHandler, Sitecore.Kernel']"/>
</event>
</events>
</sitecore>
</configuration>