Generate URLs per country code?

Vote:
 

Hi,

I have an episerver website offered in two languages: en and en-ca.  Both languages share the same content hierarchy.  I have configured en-ca language to fall back to en.

My site configuration looks like this:

  • Name: mysite
  • URL: https://mysite.com
  • Host Names:
    • First:
      • Host Name: mysite.com
      • Culture: en
      • Type: primary
      • Scheme: https
    • Second:
      • Host Name: mysite.ca
      • Culture: en-ca
      • Type: primary
      • Scheme: https

Everything appears to be fine, and when I navigate to a page on mysite.ca I see content offered in en-ca and falling back to en.  I am noticing, however, that certain URLs are being generated back to mysite.com. 

Most URLs are being generated as relative, and these are working as expected.  For some URLs, however, I want to include the hostname within the URL.  Canonical links, Open Graph links, sitemap links, etc- we want to all have hostnames associated with them.  What is the proper mechanism for generating a URL with the hostname inside of it while taking language into account? 

@Url.ContentUrl appears to be strictly relative.

#229100
Oct 07, 2020 15:00
Vote:
 
PM> Install-Package Geta.EPi.Extensions

and

@Model.CurrentPage.SomeContentLink.GetFriendlyUrl(includeHost: true, language: "{your-language-code}")
#229126
Oct 08, 2020 5:24
Vote:
 

There's an even easier way to generate absolute URLs nowadays: 

ServiceLocator.Current.GetInstance<UrlResolver>(contentReference, new VirtualPathArguments { ForceAbsolute = true });

But please don't use the service locator ;) If you want to use this in a view you could easily create an extension method with above code or just use it in the code were you construct your view model.

#229151
Edited, Oct 08, 2020 9:04
Vote:
 

Oh this is nice. I didn't know that you added this feature to the product.

#229153
Oct 08, 2020 9:18
Vote:
 

Finally, right? :)

#229155
Oct 08, 2020 9:25
Vote:
 

Nice. Which version of the EPiServer.Cms.AspNet package was ForceAbsolute introduced in, Johan? The release notes for that package are not that great..

#229160
Oct 08, 2020 10:19
Vote:
 

We could definiately improve our release information. Not all features have public work items and some features are sometimes delivered as part of others. This was released back in May in EPiServer.CMS.Core 11.15.1 https://world.episerver.com/documentation/Release-Notes/?versionFilter=11.15.1&packageFilter=EPiServer.CMS.Core&typeFilter=All.

Absolute URL support was added since it was needed in Content Delivery API, so there might be release notes in that package regarding this.

#229162
Edited, Oct 08, 2020 11:07
Vote:
 

Thanks.  I used @Johan Petersson's method to create the following extension:

        public static Uri AbsoluteUri(this ContentReference contentReference, CultureInfo language = null)
        {
            var lang = language == null ? EPiServer.Globalization.ContentLanguage.PreferredCulture : language;

            var urlString = UrlResolver.Current.GetUrl(contentReference, lang.Name, new VirtualPathArguments { ForceAbsolute = true });

            // Format and check to make sure the URI is absolute.
            // If it is, return it, if it's not, force it to be
            var uri = new Uri(urlString, UriKind.RelativeOrAbsolute);
            if (uri.IsAbsoluteUri) 
                return uri;

            // force an absolute URI based on lang
            return new Uri(GetPrimaryHostname(language), uri); 
        }

        private static Uri GetPrimaryHostname(CultureInfo language = null)
        {
            Uri retVal = null;
            var lang = language ?? System.Threading.Thread.CurrentThread.CurrentCulture;

            foreach (var host in SiteDefinition.Current.Hosts)
            {
                if (host.Type == HostDefinitionType.Primary && host.Language.Equals(lang))
                {
                    retVal = host.Url;
                    break;
                }
            }

            if (retVal == null)
                retVal = SiteDefinition.Current.Hosts.FirstOrDefault(x => x.Type == HostDefinitionType.Primary)?.Url;

            return retVal;
        }
#229169
Oct 08, 2020 12:31
Vote:
 

create an extension on UrlResolver instead, that would allow you to avoid UrlResolver.Current accessor - which is basically what Johan said - don't use ServiceLocator. I absolutely have no idea why he mentioned this in thread where I'm commenting :D

#229181
Oct 08, 2020 13:45
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.