1

I have the following transform for my local site that injects a function call into the publish:itemProcessed event:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <sitecore>
    <events timingLevel="custom" xdt:Transform="Insert">
      <event name="publish:itemProcessed">
        <handler type="Website.PublicSite.Web.PublishItemProcessed.PushContentForPublication, Website.PublicSite.Web" method="OnItemProcessed">
          <database>master</database>
          <uniqueIdField>Unique Id</uniqueIdField>
          <clientKeyField>Client Key</clientKeyField>
          <address1FieldName>Address Line 1</address1FieldName>
          <latitudeField>Latitude</latitudeField>
          <longitudeField>Longitude</longitudeField>
        </handler>
      </event>
    </events>
  </sitecore>
</configuration> 

The following method is being called that populates the latitude and longitude values of the item using the item's address field and Google Location Services (this is the call to _service.GetCoordinates(publishedItem)):

public void OnItemProcessed(object sender, EventArgs args) {
            ItemProcessedEventArgs itemProcessedEventArgs = args as ItemProcessedEventArgs;
            PublishItemContext context = itemProcessedEventArgs?.Context;

            if (context?.VersionToPublish == null) {
                return;
            }

            Item publishedItem = context.VersionToPublish;

            if (!CheckIfRunnable(publishedItem)) {
                return;
            }


            if (publishedItem[LatitudeField].Length == 0 || publishedItem[LongitudeField].Length == 0)
            {
                Tuple<string, string> latLong = _service.GetCoordinates(publishedItem);

                var latPos = latLong.Item1;

                var longPos = latLong.Item2;

                if (latPos == null || longPos == null)
                {
                    throw new Exception("Error adding record to coordinates to store item. Location not found by Google Location API.");
                }
                //This will re-fire the saving pipeline
                publishedItem.Editing.BeginEdit();
                publishedItem[LatitudeField] = latPos;
                publishedItem[LongitudeField] = longPos;
                publishedItem.Editing.EndEdit();
            }
        }

The code is working as expected for the most part. The item is updated with the proper lat/long coordinates and is published to Web. However, only the item it the Master database has its latitude and longitude coordinates updated. For the Web database item, both of these fields are blank. My understanding is when I edit the publish item it should refire the publishing pipelines and an updated version of the item should be published to Web but that appears not to be the case. Anyone know how I can get both the Master and the Web database items to show the updated fields? Thanks for the help!

1 Answer 1

2

I believe your code is doing exactly what you instruct it to; updating the field information in master. This will not trigger a re-publish on its own.

And while we could find a way to make it work like you expect; I'd say there is an easier way. Hook into item:saved instead. This triggers every time you update the item and every time the updated item is published. It is saved to "web".

In it's simplest form, it could look like this:

Simple Form

public void OnItemSaved(object sender, EventArgs args) 
{ 
  Sitecore.Events.SitecoreEventArgs eventArgs = args as Sitecore.Events.SitecoreEventArgs; 
  Sitecore.Diagnostics.Assert.IsNotNull(eventArgs, "eventArgs"); 
  Sitecore.Data.Items.Item item = eventArgs.Parameters[0] as Sitecore.Data.Items.Item; 
  Sitecore.Diagnostics.Assert.IsNotNull(item, "item"); 

  item.Editing.BeginEdit();

  // do your lat/long thing. 

  item.Editing.EndEdit();
}

And a handler looking something like:

<event name="item:saved"> 
  <handler type="yourclass, yourassembly" method="OnItemSaved"> 
          <clientKeyField>Client Key</clientKeyField>
          <address1FieldName>Address Line 1</address1FieldName>
          <latitudeField>Latitude</latitudeField>
          <longitudeField>Longitude</longitudeField>
  </handler> 
<event>

Limiting it to specific template

Optionally you need to restrict this code by Template ID or whatever is appropriate for your scenario. Inject it via configuration.

public string TemplateId { get; set; }

And...

<templateid>{your-template-id}</templateid>

Reference: Repost: Intercepting Item Updates with Sitecore

2
  • Thanks for the suggestion! We already had other code injected into the publishing pipeline to push template data to 3rd party service that's why I originally chose it over save pipeline. May need to rethink that and make the switch to a save pipeline for the lat/long coordinates.
    – c-bro
    Commented Feb 2, 2017 at 23:10
  • If you change your database configuration from "master" to "web" in your example; I think that might be all you need. Since you don't really need to calculate lat/long on master as long as it exists correctly in "web". But I still say; item:saved is a better choice of event handler for your scenario.
    – Mark Cassidy
    Commented Feb 2, 2017 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.