The problem with Sitecore.Context.Site
:
Sitecore performs publishing on the publisher
site, and as you noted, the publish:end
is an event and is called without a request, so there isn't even a URL to work from.
Based on the above, hypothetically, if we assume that Sitecore is going to resolve a site (we don't know which yet) to put in the Sitecore.Context
then the website
(or custom site) that you're looking for isn't even a candidate.
Working towards getting the site:
Every item in Sitecore is site-specific, in that it's path should only ever live within a single site. The publish:end
event just so happens to have a handy little Publisher
object as a parameter, that holds the RootItem
that was published. You can access this item and the Site
it belongs to by doing the following in your event handler:
...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;
if (scArgs == null)
{
return;
}
var publisher = scArgs.Parameters[0] as Publisher;
if (publisher == null)
{
return;
}
var rootItem = publisher.Options.RootItem;
var site = Sitecore.Configuration.Factory.GetSiteInfoList()
.FirstOrDefault(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));
...
But wait! What about multi-site publishes?
What if you published more than one site? Now you will match the first one, when you should probably return both or return null
. On the flip side, what if you published the full solution and have only one site, or else you published the full solution and now you want to get all sites that you published? The above will give you null
in these cases, but maybe that's not what you want.
Getting the site with multi-site publishing support:
In order to support multi-site and situations where you may have published the full solution, update the above to the following:
...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;
if (scArgs == null)
{
return;
}
var publisher = scArgs.Parameters[0] as Publisher;
if (publisher == null)
{
return;
}
var rootItem = publisher.Options.RootItem;
var publishedSites = Sitecore.Configuration.Factory.GetSiteInfoList()
.Where(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));
...
We aren't done yet, however. You still don't have the URL of the site.
Solution: Getting the URL of the published site(s)
The site-definition nodes have the nifty little optional attributes targetHostName
and scheme
. Assuming that you have specified a value for those attributes, you can then retrieve the URLs of the sites of the sites you published by updating the above to the following:
...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;
if (scArgs == null)
{
return;
}
var publisher = scArgs.Parameters[0] as Publisher;
if (publisher == null)
{
return;
}
var rootItem = publisher.Options.RootItem;
var publishedSites = Sitecore.Configuration.Factory.GetSiteInfoList()
.Where(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));
var publishedHosts = publishedSites
.Select(site => site.Properties["scheme"] + @":\\" + site.Properties["targetHostName"]);
...