I am attempting to hook into the Tridion Event System to insert a component's WebDAV URL into a MetaData field on that component during the save process. I have been led to understand that the WebDAVUrl is the best identifier to use for a Tridion element since it maintains a consistent value across environments when ported (we cannot rely on the Tridion id to be the same when content is ported). Also, since dynamic components are not published with the WebDAV URL as metadata by default like other elements, we must find a way to dynamically insert these values.
The issue I am having is that when hooking into the Save Event of the Event System for components on the EventPhases.Initiated phase, the component WebDAV URL is not reflective of any title changes that have occurred on the component.
Here is my sample custom Event Hook, based on sample code provide here: Performance Counters Example
using System;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.ContentManagement.Fields;
using Tridion.ContentManager.Extensibility;
using Tridion.ContentManager.Extensibility.Events;
namespace com.TridionEvents
{
[TcmExtension("Tridion2011EventSystemRC")] // This needs to be unique per Event System
public class EventSystem : TcmExtension
{
public EventSystem()
{
Subscribe();
}
public void Subscribe()
{
// OnComponentSavePre
EventSystem.Subscribe<Component, SaveEventArgs>(OnComponentSavePre, EventPhases.Initiated);
}
private static void OnComponentSavePre(Component comp, SaveEventArgs args, EventPhases phase)
{
String title = comp.Title; //This is a new title and should be part of the new WebDAV URL
ItemFields metadataFields = new ItemFields(comp.Metadata, comp.Schema);
EmbeddedSchemaField schemaField = (EmbeddedSchemaField)metadataFields["WebDAVPath"];
SingleLineTextField webDavText = (SingleLineTextField) schemaField.Values[0]["WebDAV"];
webDavText.Value = comp.WebDavUrl; // Here the comp.WebDavUrl is not reflective of the new title and what the WebDavUrl actually will become, post save.
comp.Metadata = metadataFields.ToXml();
args.ContextVariables.Add("StartTime", DateTime.Now);
}
}
}
I have configured the custom event system correctly, and I am able to debug, and see that what I am trying to accomplish is actually working, with the exception that the WebDavUrl is not updated.
For example, on a newly created component with the title "Foo", the WebDavUrl at this point will still be something like: "/some/path/New%20Component.xml"
If I go back and change the title of the component to: "Bar", the WebDavUrl at this point will be something like: "/some/path/Foo.xml", reflective of the previous state of the component.
I presume this may have something to do with the fact that component WebDavUrl is not resolved until after the component has been successfully saved.
My questions then are:
- Is there some way of getting the newest WebDAVUrl in the pre-save phase?
- Is there some other event phase that can give me this information and allow me to save it into component metadata?
- Is there some other way outside of the event system that can accomplish the same thing (while still allowing me to query the Content Delivery API for this component by the WebDAV URL)?
The integration scenario being worked through here is highly dynamic in nature, so the options being put forward by user978511 and Nick have already been discounted (not that we would dispute their validity for other scenarios).
Coming back to the question at hand at little further experimentation finds that the updated WebDAV URL for the Component is only available at Processed. (That it is not available at Initiated seems a little counterintuitive - one would not expect to get the old version of the content at Initiated, for example.)
Referring back to Bart's primer on SDL Tridion 2011 .NET events, that seems to suggest that generating the WebDAV URL is part of the magic sauce of the second step in the event life cycle ("CMS action takes place (not a phase)"). Perhaps someone more intimately familiar with the underlying code might be able to confirm this?
Following that line of thinking, I was wondering about the code that generates the WebDAV URL for items in the Content Manager:
- Is the code that generates the URL wrapped up in its own API anywhere?
- If yes, would it be accessible through the Core Service (broadly thinking: GUI extension + some obscure API call = win)?