Data URL Routing

Make individual data items accessible via URLs

Starting from version 5.0, you can quickly build a list-to-details view for a data type by creating a CMS Function with a parameter of the RoutedData<T> type.

Both a list of data items and a single item view will be accessible from the same page on your website.

@inherits RazorFunction
@functions {
    public RoutedData<IMediaFile> MediaData { get; set; }
}

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
    @if (MediaData.IsList)
    {
        <h1>List view</h1>
        <ul>
            @foreach (IMediaFile media in MediaData.List.Take(25))
            {
                <li><a href="@MediaData.ItemUrl(media)">@media.Title</a></li>
            }
        </ul>
    }
    else
    {
        <h1>Item view: @MediaData.Item.Title</h1>
    }
</body>
</html>

Note. If you are using MVC functions, please also see "Data Routing for MVC Functions".

Using RoutedData<DataType>

By adding a parameter of the type RoutedDate<DataType> to a CMS Function (where DataType is the name of your data type), you will enable data URL handling for that specific function.

In your global data types or page data folders - both dynamic and static - you can select which fields to include in data URLs (for example, Id and Name in your IProduct data type). (Please refer to "Using Fields in Data URLs" and "Data URLs in Static Data Types" for information about selecting fields for data URLs in dynamic and static data types respectively.)

When you insert such a CMS Function with a parameter of the type RoutedData<IProduct> on a page “/Products”, all the requests to URLs like “/Products/{Id}/{Name}”, for example:

/Products/PJhziHtG/T-Shirt

will not generate a 404 response. The page will be rendered, and the requested data item (of the  IProduct type in this case), will be available via the parameter's value.

If no fields are selected for data URLs in the data type,  the ID field will be used:

/Products/PJhziHtG

Implementing data URL routing

You can implement the data URL routing in these types of CMS Functions:

  • Razor functions (recommended)
  • User control functions
  • C# functions

The following code sample is given for a Razor function.

To implement the data URL routing in a CMS Function:

  1. Define a parameter of the type RoutedData<DataType> Model.
  2. In the function's body check whether the request is for:
    1. an item view (IsItem)  - a product page is requested, or
    2. a list view (IsList) - a page with the function requested
  3. For the item view, use:
    1. Model.Item property to get the data.
  4. For the list view, use:
    1. the Model.List property to get the IQueryable with all the products to be listed, and
    2. the Model.ItemUrl(…) method for building links to the detailed view for specific items.
@inherits RazorFunction
@functions {
    [FunctionParameter]
    public RoutedData<IProduct> product { get; set; }
}
<html xmlns="http://www.w3.org/1999/xhtml" 
	  xmlns:f="http://www.composite.net/ns/function/1.0">
<head>
</head>
<body>
    @* Checking if it a data item URLs or it is a URL to a page*@
    @if (product.IsItem)
    {

        <h1>
            @product.Item.Name
        </h1>
        <div>
            @product.Item.Description
        </div>
        <div>
            @product.Item.DateAdded
        </div>

        <br />
        <a href="@product.ListUrl">Back to list</a>
    }
    else
    {
        <h1>List of Products: </h1>

        foreach (var item in product.List)
        {
        <div>
            <a href="@product.ItemUrl(item)">
                @item.Name
            </a>
        </div>
        }
    }
</body>
</html>

As mentioned above, the most common usage is to have list/details view functions where requesting a page should list items of some data type (products, references, etc.), but every data item has to have a specific page with a friendly URL on which the details for this specific item are shown.

Overloading the URL pattern via code

In some cases, instead of using RoutedData<DataType>, you can make use of a parameter of the following types:

  • RoutedData.ById<DataType>
  • RoutedData.ByLabel<DataType>
  • RoutedData.ByIdAndLabel<DataType>

As each data type includes a key field (named "Id" by default), you can thus use  RoutedData.ById<DataType>.

To make use of RoutedData.ByLabel<DataType> and RoutedData.ByIdAndLabel<DataType>, you need to have a field named "Label" in your data type.

These different parameter types allow using one of the predefined URL schemes:

  • ById<DataType>: “/{Page URL}/{Data Id}” – gives the best performance and short URLs (when random strings as IDs are used)
  • ByLabel<DataType>: “/{Page URL}/{Data Label}” – is the most user-friendly, but might have poor performance when used with big data sets
  • ByIdAndLabel<DataType >: “/{Page URL}/{Data Id}/{Data Label}” – combines both good performance and user-friendly labels, but leads to longer URLs.

Using shorter ID strings

By default all the data types use a GUID as a key field type, so the ById<DataType> scheme would generate quite long URLs.

To make ID strings shorter, you can use the key field type other than GUID  - a “random string”. For detailed information on random strings, please see "Random Strings as IDs".

Random strings are either 4 or 8 characters long. You can select this type of the key field when creating a data type.

Using random strings instead of GUIDs will produce YouTube-like URLs, for example:

http://contoso.com/Products/pZSx/My-super-product

Requirements:

C1 CMS version 5.0 or later