Sitecore Links with LinkManager and MediaManager

This article describes how Sitecore handles internal and external links, how you can resolve the correct URL to an item, and what you should know about links when building multisite and multilanguage websites.

UPDATE 2019-11-12: This article is still valid for Sitecore 9.x

To render a corrent URL you use the LinkManager:

public string GetUrl(Sitecore.Data.Items.Item item)
{
  return Sitecore.Links.LinkManager.GetItemUrl(item);
}

If the Sitecore Item you are linking to is a Media Item, you cannot use the LinkManager as this will return the Url to the Sitecore item, not the actual media. Instead use the MediaManager:

public string GetUrl(Sitecore.Data.Items.Item item)
{
  return Sitecore.Resources.Media.MediaManager.GetMediaUrl(item);
}

If you have a Linkfield (which can link to Internal items, Media Items, external pages, anchors, email and javascript) you can use a function like this to automatically get the correct URL:

Sitecore.Data.Fields.LinkField lf = Sitecore.Context.Item.Fields["Link"];
switch (lf.LinkType.ToLower())
{
  case "internal":
    // Use LinkMananger for internal links, if link is not empty
    return lf.TargetItem != null ? Sitecore.Links.LinkManager.GetItemUrl(lf.TargetItem) : string.Empty;
  case "media":
    // Use MediaManager for media links, if link is not empty
    return lf.TargetItem != null ? Sitecore.Resources.Media.MediaManager.GetMediaUrl(lf.TargetItem) : string.Empty;
  case "external":
    // Just return external links
    return lf.Url;
  case "anchor":
    // Prefix anchor link with # if link if not empty
    return !string.IsNullOrEmpty(lf.Anchor) ? "#" + lf.Anchor : string.Empty;
  case "mailto":
    // Just return mailto link
    return lf.Url;
  case "javascript":
    // Just return javascript
    return lf.Url;
  default:
    // Just please the compiler, this
    // condition will never be met
    return lf.Url;
}

WHAT ELSE IS THERE TO KNOW?

Well, all internal links in Sitecore starts as a GUID. The GUID represents the internal item you link to. By using GUIDs internally, Sitecore allows you to move pages without worrying about links being invalid.

It is first when you render the page that the GUID is converted into a valid URL. Links in Rich Text Fields does it automatically (actually they use the ExpandLinks processor in the renderField pipeline), Link fields and lookup fields need help from you.

CAN I CONTROL HOW THE URL LOOKS?

Yes you can. You control the URLs with the linkManager settings in web.config:

<linkManager defaultProvider="sitecore">
  <providers>
    <clear />
    <add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" shortenUrls="true" useDisplayName="false" />
  </providers>
</linkManager>

Read the comments in the web.config on how to use the attributes. You can also replace the LinkProvider completely.

HOW ABOUT LINKS IN MULTISITE SOLUTIONS?

Multisite solutions are solutions where the same Sitecore installation contains more than one website, each site with its own unique domain name.

When creating multisite websites, you must remember to:

  • Set the Rendering.SiteResolving setting in web.config to true.
  • Set the targetHostName property to a unique domain for each website in the sites section in web.config.

This allows Sitecore to identify each site and add the correct domain name to links between sites.

BUT FOR NO APPARENT REASON Sitecore has chosen to render links made in the Rich Text Editor and links rendered by the LinkManager differently. Links in the Rich Text Editor use the Rendering.SiteResolving setting, while the LinkManager does not.

So you have to set it when using the LinkManager, using UrlOptions():

Sitecore.Links.UrlOptions urlOptions = new Sitecore.Links.UrlOptions();
urlOptions.SiteResolving = true;
Sitecore.Links.LinkManager.GetItemUrl(someSitecoreItem, urlOptions)

A clever developer will might do as Paul is doing in this blog post and modify the LinkProvider so the option is always set.

Sitecore have also made a free LinkProvider that does the same and more. You can get it here:

http://trac.sitecore.net/LinkProvider#

HOW ABOUT NESTED MULTISITES?

When nesting sites (a new site begins below the URL of an existing site) it becomes more tricky. Forunately Sitecore allows us to replace their LinkProvider, as my colleague Uli has done here: http://reasoncodeexample.com/2012/08/09/sitecore-cross-site-links/

HOW ABOUT MULTILANGUAGE SOLUTIONS?

Multilanguage solutions are solutions where the same site exist in several language versions, each language having a unique URL.

From Sitecore 6.4, Update 6, Sitecore introcuced to more settings called Rendering.SiteResolvingMatchCurrentSite and Rendering.SiteResolvingMatchCurrentLanguage. These settings allow URL’s to guestimate the correct domain and langauge and create the correct URL accordingly.

Read more about it here: https://briancaos.wordpress.com/2012/03/29/sitecore-cross-site-and-cross-language-links-resolved-in-6-4-1-release-120113/

Unfortunately, these settings are also only supported by the Rich Text Editor, not by the LinkManager.

MORE TO READ:

 

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in .net, c#, Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 and tagged , , , , . Bookmark the permalink.

9 Responses to Sitecore Links with LinkManager and MediaManager

  1. Pingback: Sitecore.Links.LinkManager and the context | Brian Pedersen's Sitecore and .NET Blog

  2. HI Brain,
    How we can make link manager behave differently based on context site,like if the context site is SiteA then set languageEmbedding=”true” & for SiteB set this to false?

    -Vikram

    Like

  3. Shafaqat Ali says:

    In content editor I want to add a link to a pdf file, I used “Add a Link” option from the tool bar, I went to “search” tab which I believe is new in this version of sitecore, I searched my item and inserted a link, sitecore uses following format o insert the link “Policing” but the ID generated by the search function is not correct, it does not exist in the site core database, If I manually edit the ID to the valid ID, it works, Why search function gives me a wrong ID?

    Like

  4. briancaos says:

    The latest version of Sitecore uses the Lucene index to search for Sitecore ID’s. Your index might me out of date, so the index contains ID’s of deleted items.
    Try updating the index, and see if that helps.

    Like

  5. Pingback: Which of my old Sitecore posts are still valid in Sitecore 9? | Brian Pedersen's Sitecore and .NET Blog

  6. Pingback: GeneralLink in Sitecore – inneka.com

  7. Pingback: Sitecore LinkField TargetItem is NULL – what’s wrong? | Brian Pedersen's Sitecore and .NET Blog

  8. Pingback: Sitecore Create Fully Qualified Url | Brian Pedersen's Sitecore and .NET Blog

  9. Pingback: GeneralLink in Sitecore – w3toppers.com

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.