Custom routing using URL patterns

In the custom routing mode MVC sites respond to incoming requests using standard ASP.NET routing. Page URLs are determined by the routes that you register into your MVC application’s routing table.

Setting up custom routing

Under custom routing the project’s entire routing configuration is fully within your control. You can implement the entire routing scheme using nothing but conventional routing provided by ASP.NET. Xperience offers the following supporting features you can incorporate into your project depending on your requirements:

  1. Page type URL patterns – URL patterns map pages in the content tree to actual URLs under which the pages are accessible via the MVC application. They ensure that the administration application knows the live site URLs of pages. This is for example necessary when using the page builder feature – the administration application needs to access and display a page served by the MVC application. Furthermore, URL patterns are necessary to generate correct page links when using the text editor.
  2. Preview mode support – preview mode provides a way to view the latest version of pages before they are published. The Xperience administration application uses URLs generated by the preview mode to: preview unpublished versions of pages, enable editing via the page builder feature, and generate preview links for external users.
  3. Page data context – page data context holds information about the currently requested page. The system uses the initialized context to enable the page builder feature and its functionality. Additionally, certain extension methods require an initialized data context to function.

Setting page type URL patterns

Page type URL patterns serve to inform the Xperience administration application about the correct live site URLs of pages. URL patterns need to match your MVC application’s route templates.

You will usually only want to specify the property for page types that are used to represent distinct pages on the MVC site. Pages that only store content used when aggregated on a different page may not need their own URL pattern. For example, such pages could represent individual branches/offices/cafes of a company that you aggregate on a page that displays all the branches/offices/cafes in one catalog.

  1. Make sure your site’s Presentation URL is configured correctly.

  2. Open the Page types application.

  3. Edit () the corresponding page type.

  4. Fill in the URL pattern under which you want the page to be accessible from the administration UI. You can use simple macro expressions for accessing data of the current page in the pattern, such as {%NodeGUID%}{%DocumentModifiedWhen.Month%}, or {%NodeAlias%}. The {%NodeAlias%} macro retrieves a page alias that allows you to create more SEO-friendly URLs. For example:

    /{%DocumentCulture%}/Articles/{%NodeAlias%}

    resolves into URL ’ http://www.example.com/en-US/Articles/On- Roasts’ for a page in the ‘en-US’ culture with Node alias ‘On Roasts’. Your MVC application needs to expose such pages under an identical URL (i.e., have a corresponding route template registered in its routing table). For example:

    
    
    
     routes.MapRoute(
         name: "Articles",
         url: "{culture}/Articles/{pageAlias}"
     );
    
    
     

    Notes:

    • Complex macro expressions including macro methods are not available in the URL pattern.
    • We do not recommend using query string parameters in URL patterns. The system removes any parameters when generating Preview URLs for pages based on the pattern.
  5. Click Save.

Editors can now access the pages of this type from the administration interface using the Live site button. They can also insert links to other pages in the text editor, and work with page builder widgets on the Page tab.

To give content editors more control over the resulting URL, augment URL patterns (and their corresponding routes) with parameters configurable via the Pages application. See Identifying pages based on URL parameters.

Initializing the page data context

Page data context holds information about the currently requested page. The system uses the context to:

  • Initialize the page builder feature for the current page.
  • Initialize a corresponding page template without you needing to provide information about the page object to the TemplateResult constructor.
  • Provide page URL resolution from within views.

You need to initialize the data context whenever you wish to use one of these features. The initialization must occur within the scope of the request serving the given page.

To initialize the data context for the current request, get an instance of the IPageDataContextInitializer interface (we recommend using dependency injection) and call its Initialize method. Specify the given page (TreeNode object) or its DocumentID as the parameter of the Initialize method. For example, you can initialize the page data context within the controller action that displays the page.




        private readonly IPageRetriever pageRetriever;
        private readonly IPageDataContextInitializer pageDataContextInitializer;

        // Gets instances of required services using dependency injection
        public PageDataContextInitialization(IPageRetriever pageRetriever,
                                             IPageDataContextInitializer pageDataContextInitializer)
        {
            this.pageRetriever = pageRetriever;
            this.pageDataContextInitializer = pageDataContextInitializer;
        }

        public ActionResult Home()
        {
            // Retrieves a page from the Xperience database with the '/Home' node alias path
            TreeNode page = pageRetriever.Retrieve<TreeNode>(query => query
                                .Path("/Home", PathTypeEnum.Single))
                                .FirstOrDefault();

            // Responds with the HTTP 404 error when the page is not found
            if (page == null)
            {
                return HttpNotFound();
            }

            // Initializes the page data context using the retrieved page
            pageDataContextInitializer.Initialize(page);

            return View();
        }