Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Torunn Surnflødt
Mar 21, 2025
  183
(3 votes)

Links in Optimizely Cms: A guide

In Optimizely CMS there are several ways to link to internal or external content using different property types, and there are several ways to render these properties. This can be confusing, so here is an overview to hopefully make it easier to choose the best option
We will also take a look at the "on page edit" functionality in this matter, and make sure the links are properly localized..

This article is based on Optimizely Cms 12 with razor views, and the Alloy solution is used for demonstration.

Choose the correct property type

First, we will map out the different property types available.

Link to pages

There are two options when creating a property for linking to other pages:
 

  • ContentReference:  A good option if there is no need for linking to external content. You can also limit which pagetype should be allowed, using annotation.
     
    public virtual ContentReference Link1 { get; set; }
  • Url: If you want a simple property for linking both internally and externally.

    public virtual Url Link2 { get; set; }

 

Images

  • Url with UIHint.Image: If you want a property for choosing an image, you can use the Url property with a UIHint.

    [UIHint(UIHint.Image)]
    public virtual Url Link3 { get; set; }
    The UIHint can also be used for the ContentReference type.

General links

  • LinkItem: If you want a property for adding a link to either internal or external content, the best option is LinkItem. This will give you some extra attributes, which is described later on.

    public virtual LinkItem Link5 { get; set; }
  • LinkItemCollection: If you want the possibility to add multiple links, like a link list, you can use LinkItemCollection:

    public virtual LinkItemCollection Link4 { get; set; }

 

Choose how to render the property

Now, when you have chosen the preferred property type, the next step is to choose the correct way to render the property.

Unformatted

The Url property can be rendered directly, with no formatting, but this will not give you a friendly url.

  • Url:
    <a href="@Model.CurrentPage.Link2">Link</a>

    Result:
    <a href="/link/fdac9c5f86b64223b4a6397fe72483f9.aspx">Link</a>

     
  • Url with UIHint for image:
    <img src="@Model.CurrentPage.Link3" width="50"/>

    Result:
    <img src="/link/6f97d70164be4681975690d8f8c05379.aspx" width="50">

 

Friendly urls and localization

To make sure you get a url which takes into account localization and gives you a user friendly url, you should use the UrlResolver in backend and the UrlHelper in the views. Here is how to do this for the different property types:

 

Razor views:

  • ContentReference:
    <a href="@Url.ContentUrl(Model.CurrentPage.Link1)">Link</a>

    Result: 
    <a href="/no/alloy-plan/">Link</a>

     
  • Url:
    <a href="@Url.ContentUrl(Model.CurrentPage.Link2.Uri.ToString())">Link</a>

    Result: 
    <a href="/en/alloy-plan/">Link</a>
     

  • Url with UIHint for image:
    <img src="@Url.ContentUrl(Model.CurrentPage.Link3.Uri.ToString())" width="50" />

    Result:
    <img src="/globalassets/pexels-binoculars.jpg" width="50">

     
  • LinkItem:
    <a href="@Url.ContentUrl(Model.CurrentPage.Link5.Href)">Link</a>

    Result:
    <a href="/en/alloy-plan/">Link</a>

 

  • LinkItemColleciton:

    You will have to loop through the items in the LinkitemCollection to render each item the same way as the LinkItem above

    <ul>
    @foreach (var link in Model.CurrentPage.Link4)
    {
     <li><a href="@Url.ContentUrl(link.Href)">Link</a></li>
    }
    </ul>

    Result:
    <ul>
    <li><a href="/en/alloy-plan/">Link</a></li>
    <li><a href="/en/alloy-track/">Link</a></li>
    </ul>

 

Backend:

  • For backend it will be similar, just use an instance of the urlResolver instead.

    UrlResolver _urlResolver;
    (…)
    var url = _urlResolver.GetUrl(startPage);

 

LinkItem

Let's take a closer look at the LinkItem property. Previously, it was only available as part of the LinkItemCollection and could not be used independently. It is now available as a standalone property type, which is very convenient. The Url property gives you a simple way to add a url, whereas the LinkItem lets you store information such as text, target and link attributes. It also provides these methods:

 

  • GetMappedHref():

    /link/fdac9c5f86b64223b4a6397fe72483f9.aspx

     
  • ToMappedLink():

    <a title="Link to Alloy Plan" href="/link/fdac9c5f86b64223b4a6397fe72483f9.aspx">Read more about Alloy Plan</a>

     
  • ToPermanentLink():

    <a title="Link to Alloy Plan" href="~/link/fdac9c5f86b64223b4a6397fe72483f9.aspx">Read more about Alloy Plan</a>

None of these gives you a friendly or localized url though.

 

On page edit

The on page edit is a useful mode for the editor, so you should put in some effort to make it function properly.

There are three different ways to add this functionality:

 

  1. The good old "@Html.PropertyFor"
     
  2. The newer version "epi-property"
     
  3. And the helpful "@Html.EditAttributes" which can come into rescue where the above mentioned is not sufficient

 


All of them gives the same on page edit functionality. Example of the three options used with the Url property:

 

  1. @Html.PropertyFor(x => Model.CurrentPage.Link2)
  2. <a href="@Model.CurrentPage.Link2" epi-property="@Model.CurrentPage.Link2">Link</a> 
  3. <a href="@Model.CurrentPage.Link2" @Html.EditAttributes(x => Model.CurrentPage.Link2)>Link</a>


Now, there are some differences to the rendered markup. Number 2 and 3 will give you a simple link:


<a href="/link/fdac9c5f86b64223b4a6397fe72483f9.aspx">Link</a>

 

But number 1 will gives you significantly more out of the box. It provides a friendly url, automatically uses the page name as the link text, and ensures the link is properly localized for the correct culture.

<a href="/en/alloy-plan/">Alloy Plan</a>


Lets check out another example - the LinkItemCollection. As you remember from earlier, you had to manually loop through the items and render them one by one. If you want a simpler solution, you can use the Html.PropertyFor.


@Html.PropertyFor(x => Model.CurrentPage.Link4)


This will create the following markup:

<ul>
<li>
<a href="/en/alloy-plan/" title="Link to Alloy Plan">Read more about Alloy Plan</a>
</li>
<li>
<a href="/en/alloy-track/" title="Link to Alloy Track">Read more about Alloy Track</a>
</li>
</ul>

 

So the Html.PropertyFor gives you a full markup with on page edit and properly localized urls. Pretty nice - but there is one drawback. You don't have any control of the markup, regarding e.g. adding css classes.

 

Absolute Url

Often, you will need an absolute url, not just a relative one.  To achieve this, you can combine the relative url you have obtained using one of the methods mentioned earlier, with the site url:

 

var siteUrl = SiteDefinition.Current.SiteUrl.AbsoluteUri.TrimEnd('/');
var absoluteUrl = string.Concat(siteUrl, url);

 

This gives you an absolute url: https://localhost:5080/en/alloy-plan/

 

Summary

We have looked at different property types for creating link properties in Optimizely Cms 12:
 

  • The ContentReference is for linking to an internal page
  • The Url and the LinkItem can be used for linking internally or externally, where the latter lets you apply attributes like text, title and target
  • The Url with a UIHint annotation will let you link to media
  • The LinkItemCollection is convenient when you need multiple links

 

We looked at different ways to render each property type:

  • Unformatted: works for the Url property
  • Friendly, localized url: obtained using the UrlHelper for frontend and UrlResolver for backend
  • On page edit: different ways of rendering while maintaining the on page edit functionality


Finally, we looked at different ways to maintain the on page edit functionality for these property types.

  • @Html.PropertyFor
  • epi-property
  • @Html.EditAttributes

 

I hope this was helpful! Please let me know if you have any feedback.

Mar 21, 2025

Comments

Please login to comment.
Latest blogs
A Free Course for Building Headless Applications with Next.js and Optimizely SaaS CMS

I am excited to announce the transformation of Optimizely Headless CMS webinar into a comprehensive, completely free self-paced course that's...

Szymon Uryga | Mar 24, 2025

Managed Identity for Connecting your Optimizely site to a Database in Azure

Are you using a connection string with username and password to connect to your Azure database? Use managed identity instead!

Tomas Hensrud Gulla | Mar 24, 2025 |

A day in the life of an Optimizely Developer - Creating a Cloudflare Turnstile Form Element Block

Hello and welcome to another installment of a day in the life of an Optimizely developer. Today I am going to show how to create a Cloudflare...

Graham Carr | Mar 24, 2025

What is ConstructorParameterResolver?

A few weeks ago I stumbled on a little-known feature and searching for it didn't reveal much about it. I managed to figure out how it's supposed to...

Daniel Ekeblad | Mar 21, 2025