Using Umbraco 6.1.3. I am trying to use the Published EventHandler to update an external file based on the content published. I am able grab property values from the content and write to this external file, but I need to get the url of the published page as well. To do this, I am using:
This works, as long as the document has been published before, but if it is a new document, apparently it isn't in the cache yet because I get a null reference. Anyone know how to grab the url of a newly published item? I only see 'Publishing' and 'Published' as options and I've tried both. What am I doing wrong?
The same thing happens when using Umbraco.Core.Services.ContentService.Published. I cannot get the url of a piece of content that has just been published if it wasn't previously in the cache prior to publishing. Do I need to refresh the umbraco cache? Is there a non-deprecated method to refresh the cache?
And this works unless the item was not previously in the umbraco cache. So it seems like it is behaving as if the cache hasn't refreshed yet to reflect the published content.
I tried NiceUrl and it gives me a '#' for the url the first time the content is published. Once it is published in the cache, if I publish again, the url is correct. So it lookes like the same issue. For some reason the cache isn't updated when my method fires (I think?).
I just did a test on an almost-vanilla 6.1.3 and I'm not seeing the issue you've described.
Using the code below, I get the correct url every time on first publish of a newly created node.
ContentService.Published += (sender, args) =>
{
foreach (var content in args.PublishedEntities)
{
var helper = new UmbracoHelper(UmbracoContext.Current);
var publishedContent = helper.TypedContent(content.Id);
var strUrl = publishedContent.Url;
}
};
Just a quick thought, are publishing through scheduled publishing?
using Umbraco.Core.Services.ContentService.Published I still get a null reference the first time the page is published. Below is how I implemented the code you sent:
public class SearchTable : ApplicationEventHandler { public SearchTable() { Umbraco.Core.Services.ContentService.Published += (sender, args) => { foreach (var content in args.PublishedEntities) { var helper = new UmbracoHelper(UmbracoContext.Current); var publishedContent = helper.TypedContent(content.Id);
var strUrl = publishedContent.Url; HttpContext.Current.Response.Write("url: " + strUrl); }
};
} }
My original code looked like this:
public class SearchTable : ApplicationEventHandler { public SearchTable() {
I'm curious as to how that code even works :)
I believe the right way to hook your evens is in the ApplicationStarted method on the ApplicationEventHandler.
Could you try the code in this gist?
I did a quick test with the code you submitted on Git and it works perfectly. It also makes much more sense to me! Thanks!
As for my original code working, Visual Studio didn't complain, so I went with it! :)
Actually, I thought the way I was doing it was the correct way for Umbraco 6, but reading the description of Umbraco.Core.Publishing.PublishingStrategy, it says it is 'currently an interconnection between the new public api and legacy api for publishing.' So I was wondering if this is in place for compatibility with version 4... either way, it is firing too soon for the umbraco cache to reflect publishing changes.
One thing you do have to be careful about though is this line:
var helper = new UmbracoHelper(UmbracoContext.Current);
The problem is, that if you are doing delayed publishing, by setting a publish date, the UmbracoContext.Current will be null at publish time, which will cause stuff to fail. Unfortunately, AFAIK, everything involving creating a new UmbracoContext is internal at the moment, so your only option to work around this, I think, is through reflection which is pretty nasty.
I would love for the Core team to get a solution in place for this, but hopefully for the time being, it won't affect you too much.
Thanks for the post which has been very helpful to me. I have a client that's doing dalayed publishing and I need a nice url for the node I'm publishing so I can add it to a table and send notices to members. Is there any way around UmbracoContext.Current being null at publish time?
Great, that makes everything it a lot easier since the internal methods for creating an UmbracoContext have been made public. What I normally do is wrap everything in saved/published/etc events in a using statement like this (gist). This way, I'm making sure that the HttpContext and UmbracoContext are never null.
I updated my gist. There might be a better way around the API, but the idea here is basically to get all domains for the given published item and then just generate url's from that and the item's url that we also got. Hope it makes sense. I haven't tested the code, but it compiles and *should* work :)
This code vardomains=Domain.GetDomainsById(content.Id); is returning an empty array. I checked umbracoDomains and it's empty although I have
hostnames on my language nodes. So maybe umbraco 6.1.6 is storing them somewhere else. What I did was replace you hardcoded url in HttpContextEnsurer's constructor
with the hostname for the Danish site and then I could get the url for items with delayed publishing. But what if you have a multisite in one umbraco instance?
Seems that you need the actual root node where the domains are declared. You could get it by traversing the content item ancestors, as I did in the gist now. Just replace "LanguageNode" with whatever your document type is called.
That's not exactly what I meant :)
Any particular reason you decided to implement it like that? Did it work out for you? If yes, then that's just great :)
The reason I implemented it in that way is that I need to know the domain / hostname for the node before I try to ensure I have a Umbraco Context object and I need to substitute it in place of "http://tempuri.org" for it work. I'm I missing something?
And yes, it worked for me. But I need to do look into if it's an optimal solution.
Why do you need to know the domain / hostname for the node before trying to ensure that you have an UmbracoContext?
As I see it, you need the relative url of your content item and then you need to concatenate it with the different domains from your root content item. Did you try and follow my gist? Did it cause you trouble?
I must have misunderstood you. Anyway I tried your solution and it looks like it works.
However in some cases I experience that helper.TypedContent(content.Id) returns null on publishing and delayed publishing which doesn't really make sense.
Also I found out that I didn't need find the domain because varstrUrl=publishedContent.Url was already given med the full url.
Yes, you probably see this whenever you publish a content item for the first time, and the item is not yet in the xml cache. See my comments on this issue.
And yes, var strUrl = publishedContent.Url will give you a full url, the domains are only necessary if you need url's for multiple domains at the same time, which is what I thought you wanted :)
Published EventHandler not populating url?
Using Umbraco 6.1.3. I am trying to use the Published EventHandler to update an external file based on the content published. I am able grab property values from the content and write to this external file, but I need to get the url of the published page as well. To do this, I am using:
This works, as long as the document has been published before, but if it is a new document, apparently it isn't in the cache yet because I get a null reference. Anyone know how to grab the url of a newly published item? I only see 'Publishing' and 'Published' as options and I've tried both. What am I doing wrong?
The same thing happens when using Umbraco.Core.Services.ContentService.Published. I cannot get the url of a piece of content that has just been published if it wasn't previously in the cache prior to publishing. Do I need to refresh the umbraco cache? Is there a non-deprecated method to refresh the cache?
Hi Tyler
Just to make sure I understand your problem, did you try to get a url like this:
Or how did you try to get to the url?
Cheers
- Mads
I'm using:
And this works unless the item was not previously in the umbraco cache. So it seems like it is behaving as if the cache hasn't refreshed yet to reflect the published content.
Thanks!
Tyler
Hi Tyler
Did you get any progress on this one? Just checking before I commit any more time to it :P
Cheers
Hi Mads,
Unfortunately, no... there has to be a way to get the url of newly published content, right? just haven't found it yet :)
Hi Tyler
Did you try to use the NiceUrl method I posted, I'm curious to hear if that could solve the issue.
I tried NiceUrl and it gives me a '#' for the url the first time the content is published. Once it is published in the cache, if I publish again, the url is correct. So it lookes like the same issue. For some reason the cache isn't updated when my method fires (I think?).
Tyler
Hi Tyler
I just did a test on an almost-vanilla 6.1.3 and I'm not seeing the issue you've described.
Using the code below, I get the correct url every time on first publish of a newly created node.
Just a quick thought, are publishing through scheduled publishing?
Cheers
- Mads
Mads,
using Umbraco.Core.Services.ContentService.Published I still get a null reference the first time the page is published. Below is how I implemented the code you sent:
My original code looked like this:
So Before I was using Umbraco.Core.Publishing.PublishingStrategy.
Tyler
Hi Tyler
I'm curious as to how that code even works :)
I believe the right way to hook your evens is in the
ApplicationStarted
method on theApplicationEventHandler
.Could you try the code in this gist?
Mads,
I did a quick test with the code you submitted on Git and it works perfectly. It also makes much more sense to me! Thanks!
As for my original code working, Visual Studio didn't complain, so I went with it! :)
Actually, I thought the way I was doing it was the correct way for Umbraco 6, but reading the description of Umbraco.Core.Publishing.PublishingStrategy, it says it is 'currently an interconnection between the new public api and legacy api for publishing.' So I was wondering if this is in place for compatibility with version 4... either way, it is firing too soon for the umbraco cache to reflect publishing changes.
Tyler
Hi Tyler
That's awesome! :)
One thing you do have to be careful about though is this line:
The problem is, that if you are doing delayed publishing, by setting a publish date, the UmbracoContext.Current will be null at publish time, which will cause stuff to fail. Unfortunately, AFAIK, everything involving creating a new UmbracoContext is internal at the moment, so your only option to work around this, I think, is through reflection which is pretty nasty.
I would love for the Core team to get a solution in place for this, but hopefully for the time being, it won't affect you too much.
Cheers
- Mads
Thanks for the heads-up. Definitely something to keep in mind!
Tyler
Hello,
Thanks for the post which has been very helpful to me. I have a client that's doing dalayed publishing and I need a nice url for the node I'm publishing so I can add it to a table and send notices to members. Is there any way around UmbracoContext.Current being null at publish time?
Thanks in advance.
/Bilal
Hey Bilal
Firstly, which Umbraco version are you using?
Cheers - Mads
Hey Mads,
I'm using version 6.1.6.
/Bilal
Hi Bilal
Great, that makes everything it a lot easier since the internal methods for creating an UmbracoContext have been made public. What I normally do is wrap everything in saved/published/etc events in a using statement like this (gist). This way, I'm making sure that the HttpContext and UmbracoContext are never null.
Let me know if it works for you.
Cheers
- Mads
Hi Mads,
It worked like magic. Thank you.
/Bilal
Hi again Mads
Do you have some suggestions to how you could extend the solution to the case you have a multi site setup with more than one hostname?
/Bilal
Hi Bilal
I updated my gist. There might be a better way around the API, but the idea here is basically to get all domains for the given published item and then just generate url's from that and the item's url that we also got. Hope it makes sense. I haven't tested the code, but it compiles and *should* work :)
Cheers
- Mads
Hello Mads
This code vardomains=Domain.GetDomainsById(content.Id); is returning an empty array. I checked umbracoDomains and it's empty although I have
hostnames on my language nodes. So maybe umbraco 6.1.6 is storing them somewhere else. What I did was replace you hardcoded url in HttpContextEnsurer's constructor
with the hostname for the Danish site and then I could get the url for items with delayed publishing. But what if you have a multisite in one umbraco instance?
Ok, another gist update.
Seems that you need the actual root node where the domains are declared. You could get it by traversing the content item ancestors, as I did in the gist now. Just replace "LanguageNode" with whatever your document type is called.
Any luck with that?
Hi Mads
Thanks for your feedback. I did something like this:
Hi Bilal
That's not exactly what I meant :)
Any particular reason you decided to implement it like that? Did it work out for you? If yes, then that's just great :)
Cheers
Hi Mads,
The reason I implemented it in that way is that I need to know the domain / hostname for the node before I try to ensure I have a Umbraco Context object and I need to substitute it in place of "http://tempuri.org" for it work. I'm I missing something?
And yes, it worked for me. But I need to do look into if it's an optimal solution.
/Bilal
Hi Bilal
Why do you need to know the domain / hostname for the node before trying to ensure that you have an UmbracoContext?
As I see it, you need the relative url of your content item and then you need to concatenate it with the different domains from your root content item. Did you try and follow my gist? Did it cause you trouble?
Cheers
Hello Mads,
I must have misunderstood you. Anyway I tried your solution and it looks like it works.
However in some cases I experience that helper.TypedContent(content.Id) returns null on publishing and delayed publishing which doesn't really make sense.
Also I found out that I didn't need find the domain because varstrUrl=publishedContent.Url was already given med the full url.
/Bilal
Yes, you probably see this whenever you publish a content item for the first time, and the item is not yet in the xml cache. See my comments on this issue.
And yes,
var strUrl = publishedContent.Url
will give you a full url, the domains are only necessary if you need url's for multiple domains at the same time, which is what I thought you wanted :)Cheers
Hi Mads
I ended up using umbraco.content.AfterUpdateDocumentCache. Thanks for your help.
/Bilal
Hi Bilal
No problem, hope everything turned out alright :)
Cheers
- Mads
how do i get the Url (i.e. Ipc) of a newly published item during the ContentService.published event?
Hej Andrew
This is a very old topic. Did you not find anything useful in it? If not, please be a bit more specific about your problem.
Cheers Mads
is working on a reply...