---
title: Creating the navigation menu
---

> 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).

> **Info:** This page is a part of a tutorial, which you should follow sequentially, from the beginning to the end. [Go to the first page: Getting started with Kentico](https://docs.kentico.com/k12sptutorial/getting-started-with-kentico.md).

In the [previous step](https://docs.kentico.com/k12sptutorial/mvc-development/displaying-the-page-content.md) of this tutorial, you have implemented the functionality that retrieves page data from the database and displays it on the live site. In this step, you will code a dynamic menu that allows your content editors to manage the website's navigation.

## You will learn about:

Website navigation tends to change based on the site's current content and the requirements of its owner. The _MenuItem_ page type allows website editors to select which pages from the content tree appear in the navigation menu. The menu's presentation, design, and behavior are then handled in the MVC application. We recommend using the strongly-typed classes that you generated for the _MenuItem_ page type to retrieve the menu data.

## Creating a view model for the menu items

1. In Visual Studio, create a new **Menu** subfolder in the **Models** folder.
2. Select the _Menu_ subfolder and add a new **MenuItemViewModel** class.
3. Define the view model properties using the following code:

   ```csharp

   namespace MEDIOClinic.Models
   {
       public class MenuItemViewModel
       {
           // Defines the properties of the MenuItem view model
           public string MenuItemText { get; set; }
           public string MenuItemRelativeUrl { get; set; }         
       }
   }

   ```
4. Save your changes.

## Creating the Menu controller

The controller class will define a _GetMenu_ action that loads and displays the content of the site's navigation menu. The action retrieves the menu data using the generated _MenuItemProvider_ class, then loads all pages which content editors selected as menu items, and organizes the data into a collection of models that gets passed to the view.

1. In the **Controllers** folder, create a new **MenuController** class.
2. Replace the default code with the following:

   ```csharp

   using System.Linq;
   using System.Web.Mvc;

   using CMS.DocumentEngine;
   using CMS.DocumentEngine.Types.MEDIO;

   using MEDIOClinic.Models;

   namespace MEDIOClinic.Controllers
   {
       public class MenuController : Controller
       {
           // GET: Loads and displays the site's navigation menu
           public ActionResult GetMenu()
           {
               // Loads all menu items using the page type's generated provider
               // Uses the menu item order from the content tree in the Kentico 'Pages' application
               var menuItems = MenuItemProvider.GetMenuItems()
                   .Columns("MenuItemText", "MenuItemPage")
                   .OrderBy("NodeOrder");

               // Loads the pages selected within the menu items
               // The data only contains values of the NodeGUID identifier column
               var pages = DocumentHelper.GetDocuments()
                   .WhereIn("NodeGUID", menuItems.Select(item => item.MenuItemPage).ToList())
                   .Columns("NodeGUID");

               // Creates a collection of view models based on the menu item and page data
               var model = menuItems.Select(item => new MenuItemViewModel()
               {
                   MenuItemText = item.MenuItemText,
                   // Gets the URL for the page whose GUID matches the given menu item's selected page
                   MenuItemRelativeUrl = pages.FirstOrDefault(page => page.NodeGUID == item.MenuItemPage).RelativeURL
               });

               return PartialView("_SiteMenu", model);
           }
       }
   }

   ```
3. Save your changes.

> **Info:** The methods of the generated page type providers, as well as the more general _DocumentHelper.GetDocuments_ method, work using the Kentico **DocumentQuery** API. DocumentQuery provides an abstraction layer over your SQL database and allows you to call additional methods that adjust how the page data is retrieved.
>
> For example, the _OrderBy_ method sets the order of the retrieved data items, and the _Columns_ method ensures that the underlying SQL query only loads the data columns that you need. For performance reasons, we strongly recommend limiting columns in all data retrieval API calls.
>
> See the documentation if you wish to learn more: [Working with pages in the API](https://docs.kentico.com/k12sp/custom-development/working-with-pages-in-the-api.md)

## Creating the navigation menu view

A navigation menu is an element that appears on most pages of a website. For this reason, you will define the menu's output in a partial view, which can then be added to the site's main layout (or into the views of other pages if necessary).

1. In the _MenuController_, right-click the **GetMenu** method and select **Add View**.
2. Fill in the following values:
   - **View** **name**: \_SiteMenu
   - **Template**: Empty (without model)
   - **Create as a partial view**: Yes (selected)
3. In the view code, add a using statement for the _MEDIOClinic.Models_ namespace.
4. Add the _@model_ directive and specify the model type as an _IEnumerable_ collection of _MenuItemViewModel_.
5. Define the menu output by rendering HTML links within a __ element (using the menu item URL and text values from the model). The partial view code should look like this:

   ```csharp

   @using MEDIOClinic.Models;

   @model IEnumerable<MenuItemViewModel>

   <nav>
       @foreach (MenuItemViewModel menuItem in Model)
       {
           @* Iterates through the view model collection and renders HTML links for the menu items *@
           <a href="@Url.Content(menuItem.MenuItemRelativeUrl)" title="@menuItem.MenuItemText">@menuItem.MenuItemText</a>
       }
   </nav>

   ```
6. Save your changes.

## Updating the website layout

You have coded the functionality behind the navigation menu. Let's put the code to use and add the menu to the site's layout.

1. Edit your _\_Layout.cshtml_ file (in the _Views/Shared_ folder).
2. Locate the section defined by __ tags, and replace it with the **Html.Action** Razor call. Invoke the _GetMenu_ action in the _Menu_ controller.
3. Locate the __ element in the __ section that displays the _MEDIO clinic_ logo, and set the value of the _href_ attribute to: \~/

   > **Info:** The tilde character with the forward slash (_\~/_) ensures that the Medio clinic logo link targets the root page of the website.

Your final _\_Layout.cshtml_ markup should look like this:

```xml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    @* Dynamically resolves the page's title *@
    <title>Medio Clinic - @ViewBag.Title</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
    <link href="http://fonts.googleapis.com/css?family=Lato:400,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
    <link href="http://fonts.googleapis.com/css?family=Lobster" rel="stylesheet" type="text/css">
    @* Loads the styles.css resource *@
    @Styles.Render("~/Content/css")
    @* Razor section for additional page-specific styles *@
    @RenderSection("styles", required: false)
</head>
<body>
    <header>
        <div class="col-sm-offset-3 col-sm-6">
            <div class="col-sm-6">
                @* Targets the root page of the website *@
                <a href="~/" title="MedioClinic homepage" class="logo">MEDIO clinic</a>
            </div>
            <div class="col-sm-6 nav">
                @* Loads the partial view with the navigation menu, including the <nav> element *@
                @Html.Action("GetMenu", "Menu")
            </div>
        </div>
        <div class="clearfix"></div>
    </header>
    @* Loads the content of your Tutorial's pages as sub views *@
    @RenderBody()
    <footer>
        <div class="col-sm-offset-3 col-sm-6">
            <div class="row">
                <div class="col-sm-6">
                    <h4>MEDIO clinic</h4>
                    <ul>
                        <li><i class="fa fa-map-marker"></i> Address: <address>7A Kentico street, Bedford, NH 03110, USA</address></li>
                        <li><i class="fa fa-envelope-o"></i> E-mail: <a href="mailto:info@medio-clinic.com" title="Email us">info@medio-clinic.com</a></li>
                        <li><i class="fa fa-phone"></i> Phone number: <a href="tel:5417543010" title="Phone us">(541) 754-3010</a>
                    </ul>
                </div>
                <div class="col-sm-6">
                    <span class="cms">Powered by <a href="http://www.kentico.com" title="Kentico CMS">Kentico CMS for ASP.NET</a></span>
                </div>
            </div>
        </div>
        <div class="clearfix"></div>
    </footer>
    @* Razor section for additional page-specific scripts *@
    @RenderSection("scripts", required: false)
</body>
</html>

```

Build your project and test your navigation menu on the live site website. Because the original layout already contained hard-coded HTML links, you won't see a difference on the live site. However, you can test the menu's dynamic functionality by adding another menu item in the Kentico administration interface (_Pages_ application), or by changing the order of the _Home_ and _Medical center_ items. The implementation you've built ensures any menu item changes are immediately displayed in the navigation menu.

You can download packages with the [exported MEDIO clinic MVC website](https://docs.kentico.com/docsassets/k12sptutorial/creating-the-navigation-menu/Kentico12_MedioClinicMVCTutorial_ExportedWebsite.zip) and the [MEDIOClinic project files](https://docs.kentico.com/docsassets/k12sptutorial/creating-the-navigation-menu/Kentico12_MedioClinicMVCTutorial_project.zip). To compare the sample solution with your own implementation, import the website into your Kentico installation in the **Sites** application or view the code of the MVC application in Visual Studio.

**Previous page:** [Displaying the page content](https://docs.kentico.com/k12sptutorial/mvc-development/displaying-the-page-content.md) — **Next page:** [Next steps in MVC development](https://docs.kentico.com/k12sptutorial/mvc-development/next-steps-in-mvc-development.md)

**Completed pages:** 9 of 10
