---
title: UniView
related:
  - https://docs.kentico.com/k82/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/using-hierarchical-transformations.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

The UniView is a templated listing control that supports displaying of hierarchical data from grouped data sources.

> **Info:** **Grouped data sources**
>
> Grouped data sources are represented by the _GroupedDataSource_ class. A grouped data source takes a standard data source, such as a DataSet, and categorizes the data items into hierarchy levels according to the values of specified columns.

You can use the UniView with any bindable data source — not only Kentico data and objects.

> **Tip:** **Tip**: If you want to display pages from Kentico, you can use the [CMSUniView](https://docs.kentico.com/k82/references/kentico-controls/cms-controls/cms-controls-listings-and-viewers/cmsuniview.md) control, which has built-in support for loading pages.

## Getting started

The following is a step-by-step tutorial that shows how to display all pages (_CMS.MenuItem_ pages) from the sample Corporate Site using the UniView control:

1. Create a new **Web form** in your web project.
2. Drag the **UniView** control from the toolbox onto the form.
3. Add the following code marked by the **UniView templates** comments between the __ tags:

   ```html

   <cms:UniView ID="UniView1" runat="server">

       <%-- UniView templates ----------------------------------------------------------------- --%>

       <ItemTemplate>
           <li>
               <%# HTMLHelper.HTMLEncode(Convert.ToString(Eval("NodeName"))) %>
           </li>
       </ItemTemplate>

       <AlternatingItemTemplate>
           <li>
               <font color="#999999">
                   <%# HTMLHelper.HTMLEncode(Convert.ToString(Eval("NodeName"))) %>
               </font>
           </li>
       </AlternatingItemTemplate>

       <HeaderTemplate>
           <ul>
       </HeaderTemplate>

       <FooterTemplate>
           </ul>
       </FooterTemplate>

       <%-- UniView templates ------------------------------------------------------------------ --%>

   </cms:UniView>

   ```

   > **Info:** This sets the templates used when displaying the menu items. The control dynamically replaces the __ inline code with values of the currently displayed record. This is then repeated for every record in the data source.
4. Add the following references to the beginning of the web form's code behind:

   ```csharp

   using System.Data;

   using CMS.DocumentEngine;
   using CMS.Helpers;


   ```
5. Add the following code to the **Page\_Load** method:

   ```csharp

   // Creates a DataSet containing all menu item pages in the system
   DataSet ds = DocumentHelper.GetDocuments("CMS.MenuItem").Path("/", PathTypeEnum.Children).OrderBy("NodeLevel, NodeOrder");

   // Checks that the DataSet isn't empty
   if (!DataHelper.DataSourceIsEmpty(ds))
   {
       // Binds the DataSet to the UniView control
       this.UniView1.DataSource = ds;
       this.UniView1.DataBind();
   }

   ```

   > **Info:** This code reads pages from the database and provides them to the UniView control as a DataSet.
6. Save the changes to the web form and its code behind file.
7. Right-click the web form in the Solution explorer and select **View in Browser**.

The control displays all _page (menu item)_ pages in the system.

![](https://docs.kentico.com/docsassets/k82/uniview/UniView_Flat.png)

### Using grouped data sources

A flat list is not ideal for displaying pages that are actually organized in a hierarchy. The following steps show how to set up the UniView to display a hierarchical structure:

1. Add another reference to the beginning of the web form's code behind:

   ```csharp

   using CMS.Base;

   ```
2. Modify the code of the **Page\_Load** method according to the following:

   ```csharp

   // Creates a DataSet containing all menu item pages in the system
   DataSet ds = DocumentHelper.GetDocuments("CMS.MenuItem").Path("/", PathTypeEnum.Children).OrderBy("NodeLevel, NodeOrder");

   // Checks that the DataSet isn't empty
   if (!DataHelper.DataSourceIsEmpty(ds))
   {
       // Creates a GroupedDataSource from the DataSet
       // You need to specify the columns that the data uses to identify parent items, and each item's level in the hierarchy
       GroupedDataSource gpd = new GroupedDataSource(ds, "NodeParentID", "NodeLevel");

       // Specifies the column that the data uses as an identifier (to determine parent-child relationships)
       this.UniView1.RelationColumnID = "NodeID";

       // Binds the DataSet to the UniView control
       this.UniView1.DataSource = gpd;
       this.UniView1.DataBind();
   }

   ```

   > **Info:** This code takes the DataSet containing the pages, groups them according to the **NodeID** of their parent page and determines their level in the hierarchy according to their **NodeLevel**.
3. Switch to the web form's markup, and add the **SubLevelPlaceHolder** control into the UniView's **ItemTemplate** and **AlternatingItemTemplate**:

   ```html

   <ItemTemplate>
       <li>
           <%# HTMLHelper.HTMLEncode(Convert.ToString(Eval("NodeName"))) %>
           <cms:SubLevelPlaceHolder runat="server" ID="plcSub" />
       </li>
   </ItemTemplate>

   <AlternatingItemTemplate>
       <li>
           <font color="#999999">
               <%# HTMLHelper.HTMLEncode(Convert.ToString(Eval("NodeName"))) %>
           </font>
           <cms:SubLevelPlaceHolder runat="server" ID="plcSub" />
       </li>
   </AlternatingItemTemplate>


   ```

   > **Info:** The **SubLevelPlaceHolder** specifies where exactly the control inserts child levels in the output code. For items that have descendants in the hierarchy, the control renders the child level instead of the placeholder (including the header and footer template for the new level).
4. Save the changes.

When you refresh the web form's output, the control displays the pages in a hierarchical structure:

![](https://docs.kentico.com/docsassets/k82/uniview/UniView_Hierarchy.png)

## Configuration

You can set the following properties for the UniView control:

| Property name                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Sample value                     |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| AlternatingRange                 | Indicates how often the **AlternatingItemTemplate** should be used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                  |
| AlternatingStartPosition         | Indicates the item number from which the **AlternatingItemTemplate** should start being used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                  |
| DataSource                       | The object from which the list of data items is retrieved.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                  |
| HideHeaderAndFooterForSingleItem | If enabled, the UniView does not render the content of the **HeaderTemplate** and **FooterTemplate** for levels that only contain a single item.                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                  |
| HierarchicalDisplayMode          | Sets the hierarchical display mode. _Inner_ generates sub-levels inside the level above, _Separate_ generates sub-levels outside of the upper levels.                                                                                                                                                                                                                                                                                                                                                                                                                                                                | "Inner"<br>"Separate"            |
| OuterData                        | Sets the data generated in the **HeaderTemplate** and **FooterTemplate**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                  |
| PagerDataItem                    | Gets or sets the pager data item object.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                  |
| PagerForceNumberOfResults        | If set, the DataSet containing paged items is not modified by the pager, but the pager itself behaves as if the amount of paged items were identical to this value. The value must be set to _-1_ for the property to be disabled.                                                                                                                                                                                                                                                                                                                                                                                   |                                  |
| RelationColumnID                 | Specifies the name of the column that the source data uses as an identifier (to determine parent-child relationships).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | "NodeID"                         |
| SelectedItemColumnName           | The name of the column that should be used for to find out which item is currently selected.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | "DocumentID"                     |
| SelectedItemValue                | The item whose column specified by the **SelectedItemColumn** property matches the value of this property will be designated as the currently selected item.<br>Typically, you will need to insert a [Macro expression](https://docs.kentico.com/k82/macro-expressions.md) in order to dynamically retrieve the appropriate value from the current context.                                                                                                                                                                                                                                                          | "{%currentpageinfo.documentid%}" |
| Transformations                  | Allows you to assign a **HierarchicalTransformations** object representing a [hierarchical transformation](https://docs.kentico.com/k82/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/using-hierarchical-transformations.md). The UniView renders the source data according to the hierarchical transformation (instead of the ItemTemplates).<br>**Note**: To use a hierarchical transformation, you need to set the _Transformations_ property before calling the UniView's **DataBind** method.<br>See also: [UniView](#displaying-data-using-hierarchical-transformations) |                                  |
| UseNearestItemForHeaderAndFooter | Indicates whether the control provides data to the item templates (or transformations) that display the header and footer content. You can work with the data inside the code of the templates.<br>Header templates use the data of the first item on the given hierarchy level.<br>Footer templates use the data of the last item on the given hierarchy level.<br>The control ignores this property if the **OuterData** property is set.                                                                                                                                                                          |                                  |

## Appearance and styling

You can use two different approaches to define the output format of the UniView control:

- Item templates
- A [hierarchical transformation](https://docs.kentico.com/k82/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/using-hierarchical-transformations.md) assigned through the **Transformations** property in the API (see the [UniView](#displaying-data-using-hierarchical-transformations) section)

You can define the following item templates within the UniView tags:

| Template name           | Description                                                                                                                                                                         | Sample value                                                                                                                |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| AlternatingItemTemplate | Template used for alternating items.                                                                                                                                                | ` <li> <font color="#999999">
<%# Eval("NodeName") %> </font> <cms:SubLevelPlaceHolder runat="server" ID="plcSub" /> </li>` |
| FirstItemTemplate       | Template for the first item on every level in the hierarchy. Only applied to levels that contain more than one item.                                                                |                                                                                                                             |
| FooterTemplate          | Template rendered at the end of every level (after the last item on the level). Can be used to close encapsulating elements from the **HeaderTemplate**.                            | ` </ul>`                                                                                                                    |
| HeaderTemplate          | Template rendered at the beginning of every level (before the first item on the level). Allows you to visually separate or style individual levels.                                 | ` <ul>`                                                                                                                     |
| ItemTemplate            | Template used for all standard items, that are not covered by a specialized template (e.g. alternating items, first items).                                                         | ` <li>
<%# Eval("NodeName") %> <cms:SubLevelPlaceHolder runat="server" ID="plcSub" /> </li>`                                |
| LastItemTemplate        | Template for the last item on every level in the hierarchy. Only applied to levels that contain more than one item.                                                                 |                                                                                                                             |
| SeparatorTemplate       | Template rendered between items on the same level. The UniView does not place the separator between items on different hierarchy levels (i.e. between a parent item and its child). |                                                                                                                             |
| SingleItemTemplate      | Template applied in cases where there is only one item on a level in the hierarchy.                                                                                                 |                                                                                                                             |

### Setting the location of sublevels

When displaying hierarchical data, you can add a placeholder that specifies the position of sublevels inside the code of item templates:

```text

<cms:SubLevelPlaceHolder runat="server" ID="plcSub" />
```

For items that have descendants in the hierarchy, the placeholder is replaced by the child level under the given item (including the header and footer for the new level). If you do not add the sublevel placeholder, the system automatically renders child levels after the code of parent items.

You can add the placeholder into any type of item template (Item, AlternatingItem, FirstItem, LastItem, SingleItem).

**Note**: To use the sublevel placeholder, the **HierarchicalDisplayMode** property of the control must be set to **Inner** (this is the default state).

## Displaying data using hierarchical transformations

The following example demonstrates how to use [hierarchical transformations](https://docs.kentico.com/k82/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/using-hierarchical-transformations.md) with the UniView control. The sample scenario displays a hierarchy of [forum posts](https://docs.kentico.com/k82/community-features/forums.md) from the Kentico database, based on the forum thread structure. You can use the same approach for any type of hierarchical data.

> **Tip:** **Tip**: The [CMSUniView](https://docs.kentico.com/k82/references/kentico-controls/cms-controls/cms-controls-listings-and-viewers/cmsuniview.md) and [QueryUniView](https://docs.kentico.com/k82/references/kentico-controls/cms-controls/cms-controls-listings-and-viewers-with-custom-queries/queryuniview.md) controls allow you to use hierarchical transformations without writing custom code. However, the CMS controls can only display pages or other hierarchical Kentico data. The approach described below is primarily intended for displaying:
>
> - External hierarchical data
> - Customized or composite Kentico data sources

1. Create a new **Web form** in your web project.
2. Add the **UniView** control onto the form:

   ```html

   <cms:UniView ID="UniViewForumPosts" runat="server" />

   ```
3. Switch to the web form's code behind file and add the following references:

   ```csharp

   using System.Data;

   using CMS.Forums;
   using CMS.Helpers;
   using CMS.Base;
   using CMS.Controls;
   using CMS.PortalEngine;

   ```
4. Set up the UniView control in the web form's **Page\_Load** method:

   ```csharp

   protected void Page_Load(object sender, EventArgs e)
   {
       // Loads a DataSet containing all forum posts, ordered according to the PostLevel and PostTime
       DataSet forumPosts = ForumPostInfoProvider.GetForumPosts().OrderBy("PostLevel, PostTime").Columns("PostID, PostForumID, PostParentID, PostIDPath, PostLevel, PostSubject, PostText, PostTime");

       // Checks that the DataSet isn't empty
       if (!DataHelper.DataSourceIsEmpty(forumPosts))
       {
           // Creates a GroupedDataSource from the forumPosts DataSet
           GroupedDataSource groupedForumPosts = new GroupedDataSource(forumPosts, "PostParentID", "PostLevel");

           // Assigns the grouped data source to the UniView
           UniViewForumPosts.DataSource = groupedForumPosts;

           // Sets the display mode of the UniView
           UniViewForumPosts.HierarchicalDisplayMode = HierarchicalDisplayModeEnum.Inner;

           // Specifies the column that the data uses as an identifier (to determine parent-child relationships)
           UniViewForumPosts.RelationColumnID = "PostID";

           // Gets the hierarchical transformation from the system
           TransformationInfo ti = TransformationInfoProvider.GetTransformation("CMS.Root.ForumPosts");

           // Checks that the transformation exists
           if (ti != null)
           {
               // Checks that the transformation is hierarchical
               if (ti.TransformationIsHierarchical)
               {
                   // Stores the structure of the hierarchical transformation into a HierarchicalTransformations object
                   HierarchicalTransformations transformation = new HierarchicalTransformations("PostID");
                   transformation.LoadFromXML(ti.TransformationHierarchicalXMLDocument);

                   // Assigns the hierarchical transformation to the UniView control
                   UniViewForumPosts.Transformations = transformation;
               }
           }

           // Binds the UniView's data
           UniViewForumPosts.DataBind();
       }                                     
   }

   ```
5. Save the changes to the web form and its code behind file.
6. Define the [hierarchical transformation](https://docs.kentico.com/k82/developing-websites/loading-and-displaying-data-on-websites/writing-transformations/using-hierarchical-transformations.md) in the Kentico administration interface (named _CMS.Root.ForumPosts_).

   > **Info:** **Creating the hierarchical transformation**
   >
   > For example, you can create the following transformation for this scenario:
   >
   > 1. Open the **Page types** application.
   > 2. Edit the **Root** page type.
   > 3. Open the **Transformations** tab.
   > 4. Click **New hierarchical transformation**.
   > 5. Name the transformation _ForumPosts_.
   > 6. Click **Save**.
   >
   > Add 4 sub-transformations:
   >
   > - **Transformation type**: Item transformation
   > - **Page types**: All (empty)
   > - **Level**: 0
   > - ASCX transformation code:
   >
   >   ```xml
   >
   >   <div style="background-color:#FFFBE8;">
   >     <a href="<%# ForumFunctions.GetPostURL(Eval("PostIDPath"), Eval("PostForumID")) %>"><%# Eval("PostSubject", true) %></a>
   >     <p><%# HTMLEncode(LimitLength(StripTags(RemoveDynamicControls(RemoveDiscussionMacros(Eval("PostText")))), 400)) %></p>
   >   </div>
   >
   >   ```
   > - **Transformation type**: Item transformation
   > - **Page types**: All (empty)
   > - **Level**: 1
   >   - **Apply to sublevels**: yes (checked)
   > - ASCX transformation code:
   >
   >   ```xml
   >
   >   <div>
   >     <a href="<%# ForumFunctions.GetPostURL(Eval("PostIDPath"), Eval("PostForumID")) %>"><%# Eval("PostSubject", true) %></a>
   >     <p><%# HTMLEncode(LimitLength(StripTags(RemoveDynamicControls(RemoveDiscussionMacros(Eval("PostText")))), 400)) %></p>
   >   </div>
   >
   >   ```
   > - **Transformation type**: Header transformation
   > - **Level**: All (empty)
   >   - **Apply to sublevels**: yes (checked)
   > - Transformation code:
   >
   >   ```xml
   >
   >   <div style="margin-left:30px">
   >
   >   ```
   > - **Transformation type**: Footer transformation
   > - **Level**: All (empty)
   >   - **Apply to sublevels**: yes (checked)
   > - Transformation code:
   >
   >   ```xml
   >
   >   </div>
   >
   >   ```
7. Return to Visual Studio, right-click the web form in the Solution explorer and select **View in Browser**.

The page displays the forum posts according to the hierarchical transformation:

![](https://docs.kentico.com/docsassets/k82/uniview/f1.png)
