Table of Contents

Designs & Templates

In introduction to designs and how they are constructed

A design is a collection of files which control how content from a DynamicWeb solution is shown in frontend - static resources, templates, and so on - stored in a folder on disk. A DynamicWeb design typically consists of the following:

  • Templates with markup and code fetching content from the DynamicWeb solution
  • Static resources such as css, javascript, etc.

Below a simple example of a template structure. All templates will always be under the /Files/Templates folder.

/Files/
├── Templates/
│   ├── Designs/
│   │   ├── myDesign/
│   │   │   ├── Paragraph/
│   │   │   │   ├── image.cshtml
│   │   │   │   ├── text.cshtml
│   │   │   ├── Navigation/
│   │   │   │   ├── topNavigation.cshtml
│   │   │   │   ├── leftNavigation.cshtml
│   │   │   ├── myLayout1.cshtml
│   │   │   ├── myLayout2.cshtml
│   │   │   ├── myMaster.cshtml

A design (myDesign above) is a 'root' folder for a group of templates that are used to render an entire website. DynamicWeb can have multiple websites using different designs - each design being in different designs folders.

Inside a design there are layouts (containing the overall markup like <head> and <body> sections) - that would be the myLayout1.cshtml and myLayout2.cshtml templates above. They would contain 2 different layouts - i.e. one with a top navigation and one with a left navigation. They will both be using the PageViewModel ViewModel.

The design folder contains subfolders for other types of templates - Paragraphs and Navigation. Each of these folders contains templates specific for that type of content. The paragraph templates will be using the ParagraphViewModel and the navigation templates will be using the NavigationTreeViewModel

Many features and apps in DynamicWeb will have its own subfolder inside the design-folder with templates using the relevant with ViewModels or tags specific to that functionality.

Design-folders are placed under Files/Templates/Designs - each design should have a dedicated subfolder here, and will appear in the Templates-section in the Assets-area tree. Designs-folder A design is applied to a website/area by opening the website settings for the website, switching to the Layout tab, and selecting a default page template. Once you've selected a default page layout, only layouts from that design can be selected elsewhere, e.g. when selecting a non-default templates for a page or a paragraph.

Setup website

When you have installed a new DynamicWeb and run the setup guide, DynamicWeb 10 will start up with an existing website with no pages: Empty DynamicWeb

To create a page:

  1. Click the +-icon next to the 'Navigation' section
  2. Choose a 'Standard page'
  3. Give it a name i.e. 'Home'
  4. Press 'Save and close'

Home page

You now have a home page with no content.

Right click the page and choose 'preview' and see what happens Home page created

This is the preview of your 'Home' page:

Home page preview

You will see the message 'No layout selected for website'

This website still does not have a design or any layouts which is why we see this message.

Creating a design

To create a design, you first create a design-folder and then a page layout:

  1. Go to 'Assets' and navigate to the folder /Templates/Designs/
  2. Click the +-icon next to the 'Designs' folder to create a subfolder - this will be our design.
  3. Name the folder 'MySimpleDesign', click 'Create'
  4. Right click the new 'MySimpleDesign' folder and choose 'New file'
  5. Name the file 'Layout_default.cshtml', click 'create'

New layout

You now have a design (the folder named 'MySimpleDesign') and 1 layout in the design named 'Layout_default.cshtml'.

The layout is currently just an empty text file, of course. Lets add some markup and apply the layout to the website:

  1. Click the ...-menu for the 'Layout_default.cshtml' and choose 'Edit'
  2. Add some markup to the file.

In this example we will use Bootstrap's Quick start template - cut'n'paste the markup to the file editor in DynamicWeb and press 'Save and close'.

Bootstrap markup

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous" defer></script>
</head>
<body>
    <h1>Hello, world!</h1>
</body>
</html>

Result in DynamicWeb New layout step 1

At this point the layout is still static, which means that the content you see in frontend if you preview the page doesn't come from anything you've filled out in the DynamicWeb administration.

Choosing the default layout

Before we make it use content from DynamicWeb, we will apply it to the website as the default layout for pages:

  1. Open the Content-area
  2. In the tree, use the ...-menu to open the Websites-list
  3. You should see a website called 'Standard'
  4. Click the website to edit it and go to the 'Layout'-tab
  5. On the layout tab, a default page template can be selected. Select the template we just created, 'Layout_default.cshtml'
  6. Save Choosing default layout

From now on, this template will be used on all pages unless another template is explicitly applied to specific pages. More on that later.

This setting will also 'lock' all pages in this website to only be able to use layouts from this design, i.e. which are located in this Design-folder.

Lets preview our 'Home' page and see how it renders now:

  1. Right click the 'Home' page in the navigation tree
  2. Choose 'Preview'

You will see the static content from the layout file: Choosing default layout

Using ViewModels to create dynamic layouts

Lets change the layout template from being static to showing content from the page, which is to say change it from being static to being dynamic.

To do so, you need to specify which ViewModel to use. You can think of a ViewModel as a sort of prepared catalog of data you typically want to use for specific types of layouts.

The ViewModel we've created for page layouts is the PageViewModel.

When you inherit this ViewModel in your layout...

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>

...you can use **@Model** in your template to access data from DynamicWeb. Change the the template to this:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@Model.Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous" defer></script>
  </head>
  <body>
    <h1>Hello, @Model.Name!</h1>
    
  </body>
  
</html>

@Model.Name is the name of the page - 'Home' - and @Model.Title is the meta title from the page. Try editing the page - open the page settings, go to the SEO tab, and change the title. Refresh the page in the frontend and see the title changed.

Save the template and preview the page again. You can now see the title of the page in <title> tag and the name of the page in the <h1>-tag.

The result of the rendering will look like this:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Welcome to Dynamicweb</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous" defer></script>
  </head>
  <body>
    <h1>Hello, Home!</h1>
    
  </body>
  
</html>

Choosing default layout

Layouts

You often need to create different page layouts for different types of content. Luckily, creating additional layouts is easy - you just create new layout files in our design folder:

  1. Navigate to Assets > Templates > Designs > MySimpleDesign
  2. Right click our 'Layout_Default.cshtml' file and choose 'Copy here'
  3. Rename the copied file to 'Layout_aboutUs.cshtml'
  4. Edit the 'Layout_aboutUs.cshtml' file so it has a different layout (below a simple sample)
@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@Model.Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous" defer></script>
  </head>
  <body>
    <h1>This is layout 2</h1>
    
    <h2>The name of the current page is '@Model.Name'</h2>

    <div>It was created @Model.CreatedDate.ToShortTimeString()</div>
    
  </body>
  
</html>

Create a new page in the website called 'About us' and choose the 'Layout_aboutUs.cshtml' Choosing default layout

Preview the page and see the result Preview additional layout

You now have a design with 2 layout templates in a design with different pages using them.

Master templates

In the layout example above the 2 layout templates are very similar - they share <head> section and will at some point have much more shared code.

The <body> section in our example is what is different.

But... it's kind of dumb to have the same code written twice. To avoid that you can use a master template to hold the shared code, so only the differences are left in the different layouts.

To create a master template:

  1. Copy one of the layout files and rename it to 'Master.cshtml'
  2. Remove everything in <body> section
  3. Add @ContentPlaceholder() where the content was

Master.cshtml

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@Model.Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous" defer></script>
  </head>
  <body>
    @ContentPlaceholder()
  </body>
</html>

The master template now contains the code shared between layouts. You can now change the layout templates to use the master template, and then when a page is rendered the content of the layout templates will be inserted where the @ContentPlaceholder() is in the master template.

To make the layout templates use the master template:

  1. Open the layout template
  2. Remove everything that is not inside <body>
  3. Add a directive in the top of the template to specify the master template

Layout_default.cshtml

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
@MasterPageFile("Master.cshtml")
    
<h1>Hello, @Model.Name!</h1>

Layout_aboutUs.cshtml

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
@MasterPageFile("Master.cshtml")    

<h1>This is layout 2</h1>
    
<h2>The name of the current page is '@Model.Name'</h2>

<div>It was created @Model.CreatedDate.ToShortTimeString()</div>

Preview the pages again and see they still look the same in frontend.

Add something to your master template and observe that the change is visible in both pages using the 2 different layouts.

Now that you understand the principle of master templates, let's add a real design to the master template. The layout below features some more master-appropriate elements:

  • A header with logo and navigation
  • A main section with a ContentPlaceholder() where page layout content is inserted
  • A footer

Master.cshtml

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@Model.Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous" defer></script>
</head>
<body>
    <header class="top-0 position-sticky bg-white">
        <nav class="navbar navbar-expand-lg py-0 pb-1" aria-label="Offcanvas navbar large">
            <div class="container">
                <a class="navbar-brand fw-medium" href="#">DynamicWeb.</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar2" aria-controls="offcanvasNavbar2" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon text-white"></span>
                </button>
                <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar2" aria-labelledby="offcanvasNavbar2Label">
                    <div class="offcanvas-header">
                        <h5 class="offcanvas-title" id="offcanvasNavbar2Label">Navigation</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
                    </div>
                    <div class="offcanvas-body">
                        <ul class="navbar-nav nav-underline justify-content-end flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link p-0 active" href="#">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link p-0" href="#">About us</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </nav>
    </header>
    <main>
        @ContentPlaceholder()
    </main>
    <footer class="py-4 py-md-5 mt-5 bg-body-tertiary border-top">
        <div class="container py-4 py-md-5 px-4 px-md-3 text-body-secondary">
            <div class="row">
                <div class="col-sm">
                    <small>&copy; Dynamicweb @DateTime.Now.Year</small>
                </div>
                <div class="col-sm text-center">News</div>
                <div class="col-sm text-end">Social</div>
            </div>
        </div>
    </footer>
</body>
</html>

Navigations are a representation of the pages created in the content tree, for example a top navigation: TopNav

They are rendered using the NavigationTreeViewModel which sets the root of the returned navigation nodes.

There are two ways to use the NavigationTreeViewModel:

  1. Inline in any template using @GetNavigation(NavigationSettings) which will return a NavigationTreeViewModel
  2. Using a separate template using @Navigation.RenderNavigation(Template, NavigationSettings) which will return rendered markup using the passed template

Both rendering methods takes a NavigationSettings object to specify what navigation nodes are wanted.

Here we are using GetNavigation() inline to create a top navigation. The NavigationSettings-object is defined inside the GetNavigation-function, and you loop though the returned navigation nodes directly in the template:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <title>@Model.Title</title>
</head>
<body>
    <header>
        <ul>
            @{
                var myNavigation = GetNavigation(new() { StopLevel = 1 });
                foreach (var node in myNavigation.Nodes)
                {
                    <li>
                        <a href="@node.Link">@node.Name</a>
                    </li>
                }
            }
        </ul>
    </header>
</body>
</html>

In this example, we're using the @Navigation.RenderNavigation() method. The NavigationSettings-object is again defined inside the method, and again only has one setting (StopLevel = 1).

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <title>@Model.Title</title>
</head>
<body>
    <header>
        @Navigation.RenderNavigation("Navigation/TopNavigation.cshtml", new() { StopLevel = 1 })
    </header>
</body>
</html>

As you can see, this method requires you to point to a navigation template which contains the code for looping through navigation nodes.

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.Navigation.NavigationTreeViewModel>

<ul>
    @foreach (var node in Model.Nodes)
    {
        <li>
            <a href="@node.Link">@node.Name</a>
        </li>
    }
</ul>

Navigation templates are typically placed inside a Navigation-folder in the main design folder, but it's not a requirement.

Both examples above will render a one level navigation - i.e. a top navigation - due to the stop level setting. The output will look something like this:

<header>
  <ul>
      <li>
          <a href="/home">Home</a>
      </li>
      <li>
          <a href="/about-us">About us</a>
      </li>
      <li>
          <a href="/contact">Contact</a>
      </li>
  </ul>
</header>

Secondary navigations

Consider the following content page structure:

- Home
  - Subpage 1
  - Subpage 2
- About us
  - Meet the team
  - Management
- Contact
  - Dealer map

Notice how each 1st level page has one or more subpages, these are second level pages, and by using different settings for StartLevel, StopLevel and ExpandMode in the NavigationSettings-object, as well as different markup, you can create a variety of different navigation structures.

A top-sublevel navigation renders the subpages of the active top node in a separate navigation, here a left-side navigation:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <title>@Model.Title</title>
</head>
<body>
    <header>
        <ul id="topNavigation">
            @{
                var myTopNavigation = GetNavigation(new() { StopLevel = 1 });
                foreach (var node in myTopNavigation.Nodes)
                {
                    <li>
                        <a href="@node.Link">@node.Name</a>
                    </li>
                }
            }
        </ul>
    </header>
    <main>
        <nav>
            <ul id="leftNavigation">
            @{
                var myLeftNavigation = GetNavigation(new() { StartLevel = 2, StopLevel = 2 });
                foreach (var node in myLeftNavigation.Nodes)
                {
                    <li>
                        <a href="@node.Link">@node.Name</a>
                    </li>
                }
            }
            </ul>
        </nav>
        <article>
            Content
        </article>
    </main>
</body>
</html>

A top-dropdown navigation renders the subpages of all top nodes as dropdowns.

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <title>@Model.Title</title>
</head>
<body>
    <header>
        <div class="dropdown">
            @{
                var dropdownNavigation = GetNavigation(new() { StopLevel = 2, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All });
                foreach (var node in dropdownNavigation.Nodes)
                {
                    <button class="btn btn-link dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        @node.Name
                    </button>
                    <ul class="dropdown-menu">
                        @foreach (var subnode in node.Nodes)
                        {
                            <li>
                                <a class="dropdown-item" href="@subnode.Link">@subnode.Name</a>
                            </li>
                        }
                    </ul>

                }
            }
        </div>
    </header>
</body>
</html>

A tree navigation uses StopLevel = 3 and ExpandMode = All in the NavigationSettings object to render a folded out tree of all nodes until level 3:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<!doctype html>
<html lang="en">
<head>
    <title>@Model.Title</title>
</head>
<body>
    <nav>
        @{
            var treeNavigation = GetNavigation(new() { StopLevel = 3, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All });
            <div id="treeNavigation">
                @{
                    RenderMyNavigation(treeNavigation.Nodes);
                }
            </div>
        }
        }
    </nav>

    @functions {
        void RenderMyNavigation(IEnumerable<Dynamicweb.Frontend.Navigation.NavigationTreeNodeViewModel> navigationNodes)
        {
            if (navigationNodes.Any())
            {
                <ul>
                    @foreach (var node in navigationNodes)
                    {
                        <li>
                            <a href="@node.Link">@node.Name</a>
                            @if (node.Nodes.Any())
                            {
                                RenderMyNavigation(node.Nodes);
                            }
                        </li>
                    }
                </ul>
            }
        }
    }

</body>
</html>

The NavigationSettings-object you pass to either of the methods used to render a navigation can have various properties - more than we've used in the examples above.

If you use a lot of properties, it's sometimes easier to parse for others if you define the object outside the method, like here:

@{
    var navigationSettings = new Dynamicweb.Frontend.Navigation.NavigationSettings()
    {
        StartLevel = 1,
        StopLevel = 5,
        IncludeFoldersAndHidden = false,
        ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All
    };

    var navigationTemplate = "Navigation/Default.cshtml";
}

@Navigation.RenderNavigation(navigationTemplate, navigationSettings)

Below we've created examples of how you can use some of the properties and what for.

Root nodes

By default, the navigation root is dynamic and depends on the current active page and the StartLevel property, but the NavigationSettings class contains two properties for controlling the root node of a navigation; RootPageId and RootNavigationTag.

The RootPageId property let's you specify a root node by the page ID:

var navigation = GetNavigation(new() { RootPageId = 123 });

Using page IDs is very specific and hardcoded, but also easy when working locally. However, when a layout is used across multiple websites and pages this approach is unsuitable; page IDs will not be the same on the other websites and solutions.

In those cases you can set the root node by the navigation tag:

var navigation = GetNavigation(new() { RootNavigationTag = "contactPages" });

The navigation tag is set using the page settings. You can use the same navigation tag on different pages on different websites, and so the design is easier to use across websites.

Expand mode

The ExpandMode-property can be used decide how the navigation tree should expand, e.g. like a breadcrumb, like a full tree or like a expanded tree.

Consider the following page tree structure:

- Home (Active page)
  - Sub page 1
  - Sub page 2
- About us
  - Meet the team
  - Management
- Contact
  - Dealers

If used with ExpandMode.Path...

GetNavigation(new() { StopLevel = 2, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.Path })

...the navigation will look like this:

<ul>
  <li>
    <a href="/home">Home</a>
    <ul>
        <li>
            <a href="/home/sub-page-1">Sub page 1</a>
        </li>
        <li>
            <a href="/home/sub-page-2">Sub page 2</a>
        </li>
    </ul>
  </li>
  <li>
    <a href="/about-us">About us</a>
  </li>
  <li>
     <a href="/contact">Contact</a>
  </li>
</ul>

If used with ExpandMode.PathOnly...

GetNavigation(new() { StopLevel = 2, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.PathOnly })

...the navigation will look like this:

<ul>
  <li>
    <a href="/home">Home</a>
  </li>
</ul>

If used with ExpandMode.All...

GetNavigation(new() { StopLevel = 2, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All })

...the navigation will look like this:

<ul>
  <li>
    <a href="/home">Home</a>
    <ul>
      <li>
        <a href="/home/sub-page-1">Sub page 1</a>
      </li>
      <li>
        <a href="/home/sub-page-2">Sub page 2</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="/about-us">About us</a>
    <ul>
      <li>
          <a href="/about-us/meet-the-team">Meet the team</a>
      </li>
      <li>
          <a href="/about-us/management">Management</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="/contact">Contact</a>
    <ul>
      <li>
          <a href="/contact/dealers">Dealers</a>
      </li>
    </ul>
  </li>
</ul>

If used with ExpandMode.None...

GetNavigation(new() { StopLevel = 2, ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.None })

...the navigation will look like this:

<ul>
  <li>
    <a href="/home">Home</a>
  </li>
  <li>
    <a href="/about-us">About us</a>
  </li>
  <li>
    <a href="/contact">Contact</a>
  </li>
</ul>

Each node in a navigation - a NavigationTreeNode - is represented by a NavigationTreeNodeViewModel, which has a number of properties you've already used like Name and Link.

Two boolean properties are used to find out which nodes are active or in the current navigation path:

  • IsActive - true for the active navigation node
  • InPath - true for the active navigation node and its parents all the way up to the top level

The properties can be used to add css classes:

 @foreach (var node in navigationNodes)
{
    <li class="@(node.InPath ? "fw-bold" : "")">
        <a href="@node.Link" class="@(node.IsActive ? "active" : "")">@node.Name</a>
    </li>
}

There are other properties as well, so we encourage you to take a look at the linked API documentation.

Item types

Item types are flexible components that allow implementers and designers to create structured, reusable content elements - specifically custom page types, custom paragraph types, or custom settings for websites, pages, and rows.

At the technical level, item types are collections of fields which are attached to system objects - e.g. a page, a paragraph, an website or a row - extending or supplanting the standard fields with the ones defined in the item type.

Item types are created under Settings > Areas > Content > Item types.

Since items are solution-specific, you need to create a template in your design folder for each item type to make sure field values are shown or reacted to in frontend. These templates should be named after the item type system name and placed alongside regular paragraph and page layouts, e.g.:

  • You have an item type which should be used as a paragraph called myParagraph, with a name, a description field, and a checkbox field called ShowInPage
  • In the /Files/Templates/Design/myDesign/Paragraph-folder create a layout called myParagraph.cshtml with markup and Razor doing stuff with the item fields:
@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>

@if (Model.Item.GetBoolean("ShowInPage"))
{
    <h1>@Model.Item.GetString("Title")</h1>

    <p>@Model.Item.GetString("Description")</p>
}
To top