🌐 Website Implementation
Links References
📖 Docs

Links and References - Optimizely CMS 12

Exam Area: Area 3 – Website Implementation & Delivery (25%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/links-and-references


1. ContentReference

// ContentReference is the fundamental type for referencing content
var link = new ContentReference(123);          // By ID
var withVersion = new ContentReference(123, 456);  // ID + Version
var withProvider = new ContentReference(123, 0, "myProvider");  // Custom provider

// Properties
link.ID            // int: content ID
link.WorkID        // int: version ID (0 = published)
link.ProviderName  // string: content provider name

// Utilities
ContentReference.IsNullOrEmpty(link)          // null check
link == ContentReference.EmptyReference       // empty check

// Convert to URL (via IUrlResolver)
var url = urlResolver.GetUrl(link);

2. IUrlResolver

using EPiServer.Web.Routing;

public class LinkService
{
    private readonly IUrlResolver _urlResolver;

    public LinkService(IUrlResolver urlResolver)
    {
        _urlResolver = urlResolver;
    }

    // ContentReference → URL string
    public string GetUrl(ContentReference link)
    {
        return _urlResolver.GetUrl(link);
    }

    // ContentReference → URL with language
    public string GetUrlInLanguage(ContentReference link, string language)
    {
        var args = new VirtualPathArguments
        {
            ContextMode = ContextMode.Default
        };
        return _urlResolver.GetUrl(link, language, args);
    }

    // URL string → ContentReference
    public ContentReference ResolveUrl(string url)
    {
        return _urlResolver.Route(new UrlBuilder(url))?.ContentLink;
    }
}

3. Url Helper in Views

@inject IUrlResolver UrlResolver

@* Use URL helper *@
<a href="@Url.ContentUrl(Model.CurrentPage.ContentLink)">Home</a>

@* Render ContentReference as link *@
<a href="@UrlResolver.GetUrl(Model.CurrentPage.RelatedPage)">Related</a>

@* Image URL *@
<img src="@Url.ContentUrl(Model.CurrentPage.HeroImage)" alt="Hero" />

4. ContentArea - Links in Blocks

// Block containing links
public class NavigationBlock : BlockData
{
    [Display(Name = "Links")]
    public virtual LinkItemCollection Links { get; set; }
}

// Render in View
@foreach (var link in Model.CurrentBlock.Links ?? new LinkItemCollection())
{
    <a href="@link.Href" target="@link.Target">@link.Text</a>
}

5. Permanent Links (GUID-based)

// Permanent link – stable even when the URL changes
// Format: /link/{GUID}

// Get permanent link
public string GetPermanentLink(ContentReference link)
{
    var page = _contentLoader.Get<PageData>(link);
    return $"/link/{page.ContentGuid}";
}

// PermanentLinkMapper
public class PermanentLinkService
{
    private readonly IPermanentLinkMapper _permanentLinkMapper;

    public ContentReference ResolveGuid(Guid contentGuid)
    {
        var map = _permanentLinkMapper.Find(contentGuid);
        return map?.ContentReference;
    }
}

6. Internal vs External Links

// ContentReference for internal links
public virtual ContentReference InternalLink { get; set; }

// Url type for external links
public virtual Url ExternalLink { get; set; }

// LinkItemCollection – mix of internal/external
public virtual LinkItemCollection MixedLinks { get; set; }

7. Relative vs Absolute URLs

// Relative URL (default)
var relativeUrl = _urlResolver.GetUrl(link);  // /my-page/

// Absolute URL (for email, sitemap, etc.)
var baseUrl = SiteDefinition.Current.SiteUrl;
var absoluteUrl = baseUrl + relativeUrl.TrimStart('/');

// Or use the ForceAbsolute argument
var externalUrl = _urlResolver.GetUrl(
    link, 
    null,
    new VirtualPathArguments { ForceAbsolute = true });

8. PageShortcutType - Redirect Pages

// Create a redirect page
var shortcutPage = _contentRepository.GetDefault<PageData>(parentLink);
shortcutPage.Name = "Old URL";
shortcutPage.LinkType = PageShortcutType.External;
shortcutPage.ExternalURL = "https://new-site.com/new-page";

_contentRepository.Save(shortcutPage, SaveAction.Publish);

// Shortcut to an internal page
shortcutPage.LinkType = PageShortcutType.Shortcut;
shortcutPage.ShortcutLink = new ContentReference(targetPageId);

Review Questions

  1. What does IUrlResolver.GetUrl(link) return? (A relative URL string for the content)
  2. What does a permanent link use to identify content? (Content GUID – stable even if the URL changes)
  3. ContentReference vs Url property type – when should each be used? (ContentReference: internal CMS pages; Url: external URLs)
  4. What is PageShortcutType.External used for? (Redirecting a page to an external URL)
  5. How do you get an absolute URL? (ForceAbsolute = true or concatenate SiteUrl + relative path)