I have task to get content's url when smth is changed on website. It like CRUD operation logging (In my case i am logging that urls to other system to further processing). It should work on version 6 and higher.
When i started it seems pretty simple subscribe to event then take item and generate url for it. I subscribed to two events publish:itemProcessing (because only here item is not yet removed from web database), publish:itemProcessed (for add and update).
This events give me object of time Item, so it seems to get url pretty simple like that
var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
options.SiteResolving = true;
var url = LinkManager.GetItemUrl(item, options);
And here my problem starts. First i need to have right url and the same way as it is generated on website but here url returns me smth like "http://domain/sitecore/content/Home.aspx".
So I added new methods to find right site from site definitions
private List<KeyValuePair<string, SiteContext>> GetSites()
{
return SiteManager.GetSites()
.Where(
s =>
!string.IsNullOrEmpty(s.Properties["rootPath"]) &&
!string.IsNullOrEmpty(s.Properties["startItem"]))
.Select(
d => new KeyValuePair<string, SiteContext>($"{d.Properties["rootPath"]}{d.Properties["startItem"]}",
new SiteContext(new SiteInfo(d.Properties))))
.ToList();
}
public virtual SiteContext GetSiteContext(Item item)
{
var site = _sites.LastOrDefault(s => item.Paths.FullPath.ToLower().StartsWith(s.Key.ToLower()));
return site.Value;
}
options.Site = GetSiteContext(Item item);
Again issue is not solved because sitecore returns "http://127.0.0.1/en.aspx"
Then i continue reading and understood that site definition should have targetHostName (it actually make sense since one site can have multiple domains) but when i add targetHostName now it returns me other link "://targetHostName/en.aspx" so http|https is missing. Second problem is that it returns me EN.aspx which means that this page can be accessible throw http://targetHostName/en.aspx and http://targetHostName
Now i have following site definitions
<sites>
<site name="shell" virtualFolder="/sitecore/shell" physicalFolder="/sitecore/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" loginPage="/sitecore/login" content="master" contentStartItem="/Home" enableWorkflow="true" enableAnalytics="false" analyticsDefinitions="content" xmlControlPage="/sitecore/shell/default.aspx" browserTitle="Sitecore" htmlCacheSize="2MB" registryCacheSize="3MB" viewStateCacheSize="200KB" xslCacheSize="5MB" />
<site name="login" virtualFolder="/sitecore/login" physicalFolder="/sitecore/login" enableAnalytics="false" database="core" domain="sitecore" disableXmlControls="true" />
<site name="admin" virtualFolder="/sitecore/admin" physicalFolder="/sitecore/admin" enableAnalytics="false" enableWorkflow="true" domain="sitecore" loginPage="/sitecore/admin/login.aspx" />
<site name="service" virtualFolder="/sitecore/service" physicalFolder="/sitecore/service" />
<site name="modules_shell" virtualFolder="/sitecore modules/shell" physicalFolder="/sitecore modules/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" content="master" enableAnalytics="false" enableWorkflow="true" />
<site name="modules_website" virtualFolder="/sitecore modules/web" physicalFolder="/sitecore modules/web" rootPath="/sitecore/content" startItem="/home" language="en" database="web" domain="extranet" allowDebug="true" cacheHtml="true" />
<site name="website" hostName="sitecore6.target|sitecore6.local" targetHostName="sitecore6.target" schema="http" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
<site name="scheduler" enableAnalytics="false" domain="sitecore" />
<site name="system" enableAnalytics="false" domain="sitecore" />
<site name="publisher" domain="sitecore" enableAnalytics="false" enableWorkflow="true" />
</sites>
And link manager settings
<linkManager defaultProvider="sitecore">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" lowercaseUrls="false" shortenUrls="true" useDisplayName="false" />
</providers>
</linkManager>
The problem is occurring because of where you are generating the link. When you have the AlwaysIncludeServerUrl
option set to true, Sitecore will use the current Sitecore.Context.Site
information to work out the server Url.
To set the http or https section, you need to add an attribute called scheme
to your site definition - I think you just have a typo as you had one called schema
:
<sites>
<site name="website" hostName="sitecore6.target|sitecore6.local" targetHostName="sitecore6.target" scheme="http" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
</sites>
During a publish event, that Context.Site
will be the shell
website. So it will not pickup the targetHostName
for your website
definition.
To force that, you need to use a SiteContextSwitcher
var website = Sitecore.Configuration.Factory.GetSite("website");
using (new SiteContextSwitcher(website))
{
var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
options.SiteResolving = true;
var url = LinkManager.GetItemUrl(item, options);
}
Then the Url will be generated using the website's targetHostName
and should generate how you are expecting.
Just one last note - best practice would be to patch the new Site definition via an include file rather than edit the main Sitecore config. Check out your include folder, there should be a SiteDefinition.config.example
file in there. It shows you how to do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With