Retrieve page URLs
Pages in the content tree of Xperience websites can have their live site URLs generated by the system through content tree-based routing or entered by marketers as a vanity URL. This allows content editors to create new pages or adjust the URLs of existing ones in the administration interface, without the need to update and redeploy the application. The final URL returned by the application is the one selected as the canonical (system URLs by default).
You may need to get the URLs of retrieved pages in various scenarios, such as rendering navigation menus, other page links, performing redirects, etc.
There are two main ways to retrieve page URLs:
Using the GetUrl extension method
This method is available for generated model classes and in general for objects that implement IWebPageFieldsSource. It returns a WebPageUrl
object containing the relative and absolute URL for a page.
A key advantage of GetUrl()
is that it never results in additional database queries. If the necessary data for URL resolution is missing from the retrieved page object, it terminates with an exception instead. In its internal implementation, the method relies solely on the data prefetched by a content query call. To ensure all necessary data for URL resolution, use the UrlPathColumns()
method when customizing your query’s selected columns.
// Assuming 'articlePage' is an instance of a generated content type class,
// for example, retrieved via IContentQueryExecutor.GetMappedWebPageResult
ArticlePage articlePage =
(await executor.GetMappedWebPageResult<ArticlePage>(builder))
.FirstOrDefault();
if (articlePage != null)
{
// Retrieves URL data for the page
WebPageUrl url = articlePage.GetUrl();
string relativePath = url.RelativePath;
string absoluteUrl = url.AbsoluteUrl;
}
Using the IWebPageUrlRetriever interface
This interface (available in the CMS.Websites
namespace) offers more specialized URL retrieval options, particularly when you only have the page identifier or need to retrieve a URL for a page object that might not have all URL-related data pre-loaded. Unlike GetUrl()
, IWebPageUrlRetriever
may perform additional database queries if the necessary information isn’t available in the provided page object or if only a page identifier is supplied.
URLs resolved using the service respect the URL language behavior set when retrieving the data – it constructs the resulting URLs in the desired language format.
// An instance of IWebPageUrlReriever
// (e.g., obtained via dependency injection)
private readonly IWebPageUrlRetriever webPageUrlRetriever;
// A page retrieved using the content query
ArticlePage article;
// Id of a web page retrieved previously
int webPageItemId;
// Retrieves URL data of a page in a specific language
// using the whole page and language code
WebPageUrl url1 = await webPageUrlRetriever.Retrieve(article, "en");
string url1_relative = url1.RelativePath;
string url1_absolute = url1.AbsoluteUrl;
// Retrieves URL data of a page in a specific language
// using the page id and language code
WebPageUrl url2 = await webPageUrlRetriever.Retrieve(webPageItemId, "en");
string url2_relative = url2.RelativePath;
string url2_absolute = url2.AbsoluteUrl;
URL language behavior
When retrieving URLs in multilingual scenarios, you can control the language of the generated URL path using the UrlLanguageBehavior
enum:
UseRequestedLanguage
– When a page is served in a fallback language, its URL path is generated based on the language originally requested by theInLanguage
method. For instance, if Spanish is requested and an English page is returned as a fallback, the URL path will still be structured as if it were a Spanish page (e.g., using URL prefixes as configured in the Languages application).UseFallbackLanguage
(Default) – When a page is served in a fallback language, its URL path is generated based on the language of the actual fallback content. In the example below, the URL path would be structured as an English page.
You can configure this behavior when building queries using the SetUrlLanguageBehavior method.
// Services obtained via dependency injection
private readonly IContentQueryExecutor executor;
public async Task PageRetrievalWithCustomUrlLanguage()
{
var builder =
new ContentItemQueryBuilder()
.ForContentType(
"My.ArticlePage",
config => config
.ForWebsite(
"MyWebsiteChannel",
PathMatch.Children("/Articles"))
// Configure URL language behavior
.SetUrlLanguageBehavior(
UrlLanguageBehavior.UseRequestedLanguage)
)
// Requesting Spanish content
.InLanguage("spanish");
IEnumerable<ArticlePage> pages =
await executor.GetMappedWebPageResult<ArticlePage>(builder);
foreach(var page in pages)
{
// If a page requested in Spanish uses English content
// due to language fallback, its URL will still use the 'spanish'
// language segments due to 'UrlLanguageBehavior.UseRequestedLanguage'.
//
// For example: '/<spanishLanguageName>/my-page-slug'
WebPageUrl url = page.GetUrl();
}
}
URL formatting and behavior
Retrieved URLs are always returned in lower case without a trailing slash. You can modify some behavior of retrieved URLs using the following options and the .NET options pattern:
WebPageUrlRetrieverOptions
– Allows you to change the cache duration. The URLs are by default cached for 24 hours.UrlResolveOptions
– Allows you to specify whether SSL protocol should be included when retrieving absolute URLs. By default,https
URLs are returned.
var builder = WebApplication.CreateBuilder(args);
// ...
// Sets the cache duration to 60 minutes
builder.Services.Configure<WebPageUrlRetrieverOptions>(
options => options.MaximumUrlCacheDuration = TimeSpan.FromMinutes(60));
// Includes SSL in absolute URLs
builder.Services.Configure<UrlResolveOptions>(
options => options.UseSSL = false);
The relative path to a page returned by the Retrieve
method can be resolved to an application absolute path at runtime (for example, using the UrlHelper.Content method).
@using Microsoft.AspNetCore.Mvc
<!--
Relative URL of the article is passed through
the AricleUrl model property
-->
<a href="@Url.Content(Model.ArticleUrl)">Visit the Article!</a>