Handling incorrect link propagation in Site Variations in SharePoint 2010

When we have Site Variation setup in SharePoint 2010 we can run into an issue with the Links on the content pages in Pages Library not pointing to the right location on Target Label.

Consider the following scenario.

“EN” is the Source Variation Label and we setup a Target Variation Label “EN-UK”. On the Source Label (EN) there is a page “Page1.aspx” having content in a Publishing HTML Field which contains a link to “Page2.aspx” on Source Label itself. When these pages are approved, published and propagated to the Target Label (EN-UK) the link on “Page1.aspx” is supposed to take to the “Page2.aspx” on the Target Label. However the Publishing HTML Field does not resolve them correctly and still points to “Page2.aspx” on Source Label “EN”. This situation is depicted in the picture below.

 

Solution: This situation can be handled by having a ListItem Event Receiver on the Pages Library of “EN-UK” for ItemAdded and ItemUpdated events. The following code in ItemUpdated shows how to handle such a situation

  public override void ItemUpdated(SPItemEventProperties properties)
 {
 if (SPImportContext.Current.IsRunning)
 {
 this.EventFiringEnabled = false;
 FixLinks(properties);
 this.EventFiringEnabled = true;
 }
 base.ItemUpdated(properties);
 }

The FixLinks method is here

  private void FixLinks(SPItemEventProperties properties)
 {
 ArrayList links = new ArrayList();
 // Copy the required SPLink items to a seperate ArrayList so that we do not get the Enumerator modified exception.
 foreach (SPLink item in properties.ListItem.ForwardLinks)
 {
 if (item != null && item.ServerRelativeUrl != null && item.ServerRelativeUrl.ToLower().Contains(@"/en/"))
 {
 links.Add(item);
 }
 }
 
 foreach (var link in links)
 {
 var vLink = link as SPLink;
 if (vLink != null)
 {
 properties.ListItem.ReplaceLink(vLink.ServerRelativeUrl, vLink.ServerRelativeUrl.ToLower().Replace(@"/en/", @"/EN-UK/"));
 }
 }
 }
 

There are few points to note in the above code.

  1. We need to ensure that the links are fixed when the pages are updated/added only in the context of the Variation Page Propagation Job. This is done by using the SPImportContext.Current.IsRunning property. Refer to Stefan Goßner's blog post for more details
  2. We need to make sure that the Event Handler for "after" events like the one in the example above is marked as Synchronous. More info on this here. Otherwise the Event Handler may run asynchronously and SPImportContext.Current.IsRunning property will be false.
  3. Turn off any recursive firing of events by turning off the EnableEventFiring flag just before fixing the links and turning it on once the links are fixed.

How it works

Once the pages are approved on the Source Label the “Variation Propagate Page Job” gets kicked off as scheduled. This job updates/adds the pages to the Target Label as needed. While the pages are propagated to target the Event Receiver on Pages Library gets triggered and updates the links on the pages accordingly.

Hope that helps

-Vamsi KR

Comments

  • Anonymous
    March 23, 2012
    Great article!