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"?
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.
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.
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:
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.
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.
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?
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 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.
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 ;-)
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.
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.
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.
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
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
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
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:
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
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.
Any ideas?
David
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
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
Summary:
I've created a custom event handler and added it to the Publishing event.
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
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, theContentService.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
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
@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
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
It does appear to have several bugs.
I tested some more with this code:
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.
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.
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.
is working on a reply...