Razor Templates & ViewModels

A view model is an object that can be rendered in a view (Razor template). The view model represents an entity such as a page or a paragraph and has been optimized for rendering in front end.

Since view models are objects with strongly typed properties you will be able to use intellisense in Visual Studio and easily find available values (Figure 1.1)

Figure 1.1 Intellisense

If you have experience with the regular Razor implementation in Dynamicweb, please note that you have two different view models available to you:

  • PageViewModel
  • ParagraphViewModel

Both are described in more detail below.

Additonally, here are some of the key conceptual differences:

  • Workflow / Intellisense
    Regular razor templates use a key/value collection where the view model templates are served a typed object with properties. The view model will make it possible to get full intellisense when working with templates in Visual Studio. You no longer have to rely as much on documentation or DwTemplateTags to find out what information is available.
  • Feedback
    The regular razor templates will fail silently if you misspell a property, since it is a simple lookup like this: @GetValue(“DwPageName”). The rendering engine will give you immediate feedback (error message) if you misspell the name of a view model property.
  • Performance
    View model templates has made it easier for us to optimize the parsing and rendering process. Therefore you should be able to notice some performance improvements when using view model templates compared to other types of templates.

Of course, it’s also a matter of taste – different strokes for different folks and all that.

In order to use a view model the template must inherit from ViewModelTemplate and should specify a model that is valid in the context where the template is used, e.g. page or paragraph. The type of view model should be specified at the top of the template:

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

In this example, we are specifying the view model for a page view model template

You can optionally specify some information about your template which will be displayed in layout selectors in the administration.

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> @Title("My view model template") @Description("Description of my view model template")

This will show up in the layout selector in the backend (Figure 2.3).

Figure 2.3 A view model template with a title and a description

Both view models (PageViewModel and ParagraphViewModel) work with the following standard template methods and features:

Property

Used in

Comments

@ContentPlaceholder()

Master templates

 

@MasterPageFile(“master.cshtml”)

Layout templates

 

@Include(…)

Everywhere

 

@IncludeFile(…)

Everywhere

 

@GetPageIdByNavigationTag("TagName")

Everywhere

Returns the first area page with the specified navigationtag. If no page is found, 0 is returned

@RenderItem(…)

Everywhere

 

@RenderItemList(…)

Everywhere

 

@RenderItemCreationForm(…)

Everywhere

 

@RenderNavigation(…)

Everywhere

Must start with a @

@SnippetStart(…)

@SnippetEnd(…)

@RenderSnippet(…)

Everywhere

 

@Translate(…)

Everywhere

 

When rendering a page layout you must use the PageViewModel:

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

Content placeholders are defined in the following manner:

@* A content placeholder *@ @Model.Placeholder("footer") @*A content placeholder with a title and a description *@ @Model.Placeholder("main", "Main content", "default:true;sort:1")

A placeholder can take the following parameters:

Parameter

Required

Comments

Id

Yes

Unique id of a layout container.

Title

No

Friendly name of the layout container which is displayed in the administration (defaults to the value of Id).

Settings

No

Additional settings that specifies how the content should be rendered.

 

The placeholder settings available to you are:

Property

Description

Default value

Possible values

Default

Whether new content should be placed in this container by default (page edit).

False

True or False

Sort

Controls the sorting in administration (page edit).

0

1-99

Template

The template that should be used for items in this container.

 

Any valid paragraph template. Must be placed in

/Templates/Paragraph,

/Templates/Designs/Paragraph or

/Templates/Designs/DesignName/Paragraph

A very simple page layout template could look like this:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> @Title("My view model template") @Description("Description of my view model template") <!DOCTYPE html> <html> <head> <title>@Model.Title</title> <meta name="description" content="@Model.Description" /> <meta name="keywords" content="@Model.Keywords" /> </head> <body> <h1>@Model.Name</h1> <div> @Model.Placeholder("main") </div> </body> </html>

When rendering a paragraph you must use the ParagraphViewModel. 

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

This view model gives you access to all basic properties of the current paragraph – ParagraphText, ParagraphImage and ParagraphModule:

<img src="@Model.Image" alt="@Model.ImageAlt" /> <div> @Model.Text </div> <div> @Model.GetModuleOutput() </div>

The module output is a string value.

A very simple paragraph template could look like this:

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> <div> <h1>@Model.Header</h1> <div> @Model.Text </div> <div> <img src="@Model.Image" alt="@Model.ImageAlt" /> </div> <div> @Model.GetModuleOutput() </div> </div>

Some view models will expose an item property which will give you an instance of ItemViewModel, e.g.

  • PageViewModel.Item (Item based pages)
  • PageViewModel.PropertyItem (Page Properties items)
  • PageViewModel.Area.Item (Website Properties items)
  • ParagraphViewModel.Item (Item based paragraphs)

The ItemViewModel.Fields gives you access to a collection of item fields and some methods for retrieving the field values. The following methods are available:

Method

Return type

Use with item field type

GetBoolean

Boolean

Check box

GetDateTime

DateTime

Date, Date and time

GetDouble

Double

Decimal number

GetInt32

Int32

Integer number

GetInt64

Int64

 

GetString

String

Text, Rich text, Color

GetFile

FileViewModel

File

GetFiles

IList<FileViewModel>

Folder

GetGeolocation

GeolocationViewModel

Geolocation

GetItem

ItemViewModel

Item type, Link to item

GetItems

IList<ItemViewModel>

Item relation list

GetUsers

IList<UserViewModel>

User

GetValue

object

Any

Examples:

@* Rendering all fields of an item *@ <div> @if (Model.Item != null) { <table> @foreach (var field in Model.Item.Fields) { <tr> <th>@field.Name</th> <td>@field.GetValue()</td> </tr> } </table> } </div> @* Rendering a specific field of an item *@ <div> @{ var myField = Model.Item.GetField("MyField"); if (myField != null) { <p>@myField.Name</p> <p>@myField.GetValue()</p> } } </div> @* Rendering a specific field value of an item *@ <input type="checkbox" checked="@Model.Item.GetBoolean("Checkbox")" />

GetValue() returns the field value as an untyped object.

You can use GetValue if you just want to render the value and don’t want to change the format in any way.

However, if you want to format the value, e.g. render a date in a specific format, then you would need to get the typed value and then apply your formatting.

Note that if the field value is a complex type, like the FileViewModel you get from a file field, then the output from GetValue will just render as the type name, e.g. “Dynamicweb.Frontend.FileViewModel”.

You can either use one of the helper methods for converting the value to the right type (recommended) or you can use GetValue and then cast the value yourself.

Example: Rendering a Date field using GetValue or GetDateTime

Method

Example

Result

GetValue

<div>@Model.Item.GetValue("Date")</div>

<div>01-11-2016 14:35:09</div>

GetDateTime

<div>@Model.Item.GetDateTime("Date").ToString("s")</div>

<div>2016-11-01T14:35:09</div>

GetDateTime  @Model.Item.GetDateTime("Date").Year <div>2016</div>

 

Example: Rendering a File field using GetValue or GetFile

Method

Example

Result

GetValue

<div>@Model.Item.GetValue("File")</div>

<div>Dynamicweb.Frontend.FileViewModel</div>

GetFile

<div>@Model.Item.GetFile("File").Path</div>

<div>/Files/Images/logo.png</div>

You can use the GetField method on ItemViewModel in order to get additional information about a specific field.

Example: Rendering information about a specific field:

<div> @{ var dateField = Model.Item.GetField("Date"); if (dateField != null) { <p>@dateField.Name</p> <p>@dateField.SystemName</p> <p>@dateField.GetDateTime()</p> } } </div>

You use the GetItem() method if you want to retrieve values from an item with a field of the type Item type. For example, you have a shared item type called Font which contains all sort of font settings. This itemt ype is used in your website settings – so to retrieve the value from the FontFamily field you do the following:

Model.Area.Item.GetItem("Font").GetString("FontFamily”);

You use the GetFile() method whenever you’ve used an item field of the type File – this is the only way to retrieve the path to the file.

Item.GetFile("Image").Path

GetFile() can return the file extension, the name, and the path to the file selected – if you use any other method, you will fail silently.

You use the GetItems() method if you have used an item field of the type Item relation list – this is the only way to retrieve values from item relation lists.

@foreach (var i in Model.Item.GetItems(“GalleryImages”)) { i.GetString(“Image”); }