Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David F. Hill 122 posts 242 karma points
    Jan 06, 2014 @ 01:06
    David F. Hill
    0

    Custom publishing event handler not firing for subpages

    Hello Umbraco colleagues,

    Here's another question about writing a custom publishing event handler. This one has me stumped:
    I'm using Umbraco ver 6.1.6.

    The event handler I've written fires when a single node gets published...
    How do I get a custom event handler to fire when someone clicks "publish this page and all it's sub-pages"?

    Thanks,
    David Hill

  • Richard Soeteman 4035 posts 12842 karma points MVP
    Jan 07, 2014 @ 17:58
    Richard Soeteman
    0

    Hi David,

    You need the ContentService events in that case. This will give you a list of all the entities in the event arguments. The old API doesn't support that.

    Hope

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jan 07, 2014 @ 17:59
    Jeroen Breuer
    0

    Hello,

    Are you using the new or old events? I think with the new api it should only hit once, but with an IEnumerable of content items.

    Jeroen

  • David F. Hill 122 posts 242 karma points
    Jan 07, 2014 @ 20:27
    David F. Hill
    0

    Jeroen,

    Can't say for sure if I'm using new or old events. (How do find out?) I thought Umbraco.Core was new. Anyway...

    I'm deriving my class from Umbraco.Core.ApplicationEventHandler and then calling this:

    Umbraco.Core.Publishing.PublishingStrategy.Publishing += CustomPublishingEventHandler;

    the CustomPublishingEventHandler is not being hit when the user clicks "publish this page and all it's sub-pages".

    If you have a little snippet of code to show how how to create an event handler to loop through all the child nodes as they're being published - - I would appreciate it.

    Cheers,

    David

  • David F. Hill 122 posts 242 karma points
    Jan 07, 2014 @ 20:58
    David F. Hill
    0

    Update:

    Using code examples similar to: http://our.umbraco.org/documentation/Reference/Events-v6/ContentService-Events
    and
    http://our.umbraco.org/wiki/reference/api-cheatsheet/attaching-document-event-handlers

    The code in the custom event handler is being hit BUT the value being assigned to the property is not saving. Don't know why.

    private void MyEventHandler(IPublishingStrategy sender, PublishEventArgs<IContent> args)
    {
      foreach (var node in args.PublishedEntities)
      {
        if (node.ContentType.Alias == "myAlias")
        {
           node.SetValue("thePropertyAlias", "beemch");         
        }
      }
    }

    Any ideas?

    David

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jan 07, 2014 @ 21:10
    Jeroen Breuer
    1

    Hello,

    That's because with the v6 API of Umbraco things work different (more logical). Your trying to update a value in the publish event, but logically this should happen in the before save event. In v4 it always worked because when you set a property value it was saved to the db directly. In v6 it doesn't work like that anymore and things are only saved to the db before .Save() and it's events are called. A little more info here: 

    http://our.umbraco.org/forum/developers/api-questions/42394-AbstractDataEditor-OnSave-in-Umbraco-61?p=0#comment153854

    http://issues.umbraco.org/issue/U4-1564

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jan 07, 2014 @ 21:20
    Jeroen Breuer
    0

    So it's best to use the before save event, but if you can't do that and need to do it in the publish event you need to call save and publish again while you're in that event. That will trigger the save code again. If you call the save code again you could end in an infinite loop which calls the events again, but when you call the save code there should be a boolean parameter where you can turn of the events to prevent this.

    Jeroen

  • David F. Hill 122 posts 242 karma points
    Jan 08, 2014 @ 02:44
    David F. Hill
    1

    Summary:

    I've created a custom event handler and added it to the Publishing event.

    ContentService.Publishing += CustomPublishingEventHandler;

    I have stepped through my code carefully and CustomPublishingEventHandler method is not getting called when a user right-clicks "publish" then checks "Publish archive and all its subpages". (If "publish subpages" is NOT checked, the event fires just fine.)

    So any code in that method will not get executed. Putting in a call save and publish again wouldn't do anything as far as I can see.

    I don't see any event that gets fired when "Publish archive and all its subpages" is checked. If anyone knows what event I can "tap into" in that scenario, please let me know.

    David

  • Mads Krohn 211 posts 504 karma points c-trib
    Jan 08, 2014 @ 09:28
    Mads Krohn
    1

    I just tested this and I can confirm that when you choose to include children when publishing, the ContentService.Publishing event won't be triggered. However, the ContentService.Published event will be triggered just fine, so clearly, there is a bug somewhere. David, you should open an issue for it.

    In the mean time, can you do what you need to do in the ContentService.Published event instead?

    Cheers

  • Morten Christensen 596 posts 2773 karma points admin hq c-trib
    Jan 08, 2014 @ 09:53
    Morten Christensen
    1

    I can confirm that Mads is right ;-)

    The bulk publishing doesn't fire the Publishing event, but only the Published event. Looking at the code it might be an oversight, so please create an issue for it and point to this thread.

    Ironically though, the legacy Document.BeforePublish is fired, but only includes the Parent (or rather the selected document) for which you are publishing children. So if you decide to use this old event you'll probably have to iterate the children yourself. But as Jeroen mentioned, if you want to update a property before certain documents are published you should be using new Publishing event or the old BeforePublish event. Otherwise you're changes won't actually be published.

    - Morten

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Jan 08, 2014 @ 10:11
    Jeroen Breuer
    0

    @Morten If you try to set a value in the new Publishing event or the old BeforePublish event I think that won't be saved. It might be published, but it's after the save event so if you reopen the node in the backend the value won't be there if I think.

    Jeroen

  • Morten Christensen 596 posts 2773 karma points admin hq c-trib
    Jan 08, 2014 @ 10:18
    Morten Christensen
    0

    Yes, thats true. The newly added value won't show up in the backoffice when you set it in Publishing.

    A note on my previous comment....On second thought I don't think it'll be a good idea to iterate over children in the BeforePublish event, as its the same event that is fired regardless of you publishing a single item or with children. So you could end up iterating for everything on each publish and thats no good. So maybe just consider if using the Saving event won't work equally good for you ;-)

    - Morten

  • David F. Hill 122 posts 242 karma points
    Jan 08, 2014 @ 16:57
    David F. Hill
    0

    It does appear to have several bugs.
    I tested some more with this code:

    public UmbracoStartupHandler()
    {
        ContentService.Saving += TestSavingEventHandler;
        ContentService.Publishing += TestPublishingEventHandler;
    }

    private void TestSavingEventHandler(IContentService sender, SaveEventArgs<IContent> e)
    {
        string docsHit = "";
        foreach (var doc in e.SavedEntities)
        {
            docsHit += doc.Id + ",";
            if (doc.ContentType.Alias == "pageDocType")
            {
                doc.SetValue("message", "saving");
            }
        }
    }

    private void TestPublishingEventHandler(IPublishingStrategy sender, PublishEventArgs<Umbraco.Core.Models.IContent> e)
    {
        string docsHit = "";
        foreach (var doc in e.PublishedEntities)
        {
            docsHit += doc.Id + ",";
            if (doc.ContentType.Alias == "pageDocType")
            {
            }
        }
    }


    There is different behavior depending on which of the following are checked:

    Click ok to publish pages and thereby making it's content publicly available.
      Publish pages and all its subpages
        Include unpublished child pages

    Also there is different behavior depending on whether or not unpublished child pages actually exist.

    Not only that but with "Publish pages and all its subpages", the foreach does not iterate for each sub page. instead the entire event gets triggered for every document.

    The only thing that works reliably is publishing a single page.

  • Sebastiaan Janssen 5044 posts 15475 karma points MVP admin hq
    Jan 08, 2014 @ 17:44
    Sebastiaan Janssen
    1

    Just to explain: foreach (var doc in e.PublishedEntities) will go through all the PublishedEntities. In the case of right-clicking and choosing "Publish pages and all its subpages" you will get just the one page that you right-clicked.

    To work around this problem you will need to manually foreach through the doc.Children and update the properties you want.

    Make sure to do a .SaveAndPublish() on each of those children. The SaveAndPublish method has a optional parameter "raiseEvents" which you can set to false. This will help to prevent it going into an infinite loop. Disclaimer: I didn't look at your requirements in detail but this is the general direction of where it looks like you want to go.

  • Sebastiaan Janssen 5044 posts 15475 karma points MVP admin hq
    Jan 08, 2014 @ 17:49
    Sebastiaan Janssen
    0

    And yes, as Morten says, it might not be a good idea actually: if you do this then for EACH publish on EACH document this event will get fired and all of the Children will be published. I see you're already checking for the content type alias, which is great, but it might not be enough for your needs.

  • Manish 373 posts 932 karma points
    Jul 13, 2017 @ 06:25
    Manish
    0
    using System.Linq;
    using Umbraco.Core;
    using Umbraco.Core.Models.PublishedContent;
    using System;
    using Umbraco.Core.Logging;
    using Umbraco.Web.Routing;
    namespace  YourSite.App_Code
    {
        public class ConfigurePublishedContentModelFactory : ApplicationEventHandler
        {
            protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
    
            }
    
            protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
              Umbraco.Core.Services.ContentService.Published += ContentService_Published;
            }
    
    
    
            void ContentService_Published(Umbraco.Core.Publishing.IPublishingStrategy sender, Umbraco.Core.Events.PublishEventArgs<Umbraco.Core.Models.IContent> e)
            {
                try
                {
                   // Your logic to send email on publishing/unpublishing some node
                }
                catch (Exception ex)
                {
                    LogHelper.Error(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, "Got this error at", ex);  // log exception here
                }
            }
    
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft