-
Notifications
You must be signed in to change notification settings - Fork 1.5k
View location conventions
While rendering a view is as simple as invoking the View indexer on the NancyModule
class, there is quite a lot going on “under the hood” to attempt to locate the correct view template, based on the information provided. This “under the hood” work is actually achieved using a series of “view location conventions”.
The conventions themselves are quite simple. Each convention uses the available “hints”, such as view name, model type and view location context, and produces a series of potential view template names/locations. Nancy will iterate over the conventions, in the order they have been defined, until a view template is located, or until there are no more conventions to use.
A view location convention is defined by a function of the type Func<string, dynamic, ViewLocationContext, string>
, and the default conventions that are shipped with Nancy are as follows:
(viewName, model, viewLocationContext) => {
return viewName;
}
This convention will basically look for the view in the root of your application. However, if the view name does contain a relative path, the view name will actually point to that path, relative the root of the application, e.g for view admin/index
it will look for the view in admin/index
.
(viewName, model, viewLocationContext) => {
return string.Concat("views/", viewName);
}
This should be pretty self explanatory; Nancy will look for the view in a views folder located in the root of the application. Again, if you have specified a relative path in your view name, Nancy will look for the view in the path, relative to the views folder, e.g for view admin/index
it will look for the view in views/admin/index
. Note: do not be alarmed by the use of the hard coded “/” path separator; these are a kind of “virtual” path, rather than physical file system paths, and they always use “/” as a separator.
(viewName, model, viewLocationContext) => {
return string.Concat("views/", viewLocationContext.ModulePath, "/", viewName);
}
This convention looks a bit more complicated, but it’s really still quite simple. What this is doing is looking for the view, inside a sub-folder of the views folder, where the sub-folder has the same name as the modulePath
of the module that is being used to execute the current request. So for the view index
in a module with a path products
it will look for the view in views/products/index
. Again, if the view name contains a relative path, Nancy will look in the path relative to the views/modulePath folder
, e.g for view admin/index
, in a module with a path products, it will look for the view in views/products/admin/index
.
(viewName, model, viewLocationContext) => {
return string.Concat(viewLocationContext.ModulePath, "/", viewName);
}
This convention looks for the view inside of a folder with the same name as the modulePath that is located in the root of the application.
(viewName, model, viewLocationContext) => {
return string.Concat(viewLocationContext.ModuleName, "/", viewName);
}
This convention looks for the view inside of a folder with the name of the module, but with the suffix Module trimmed of, that is located in the root of the application.
(viewName, model, viewLocationContext) => {
return string.Concat("views/", viewLocationContext.ModuleName, "/", viewName);
}
This convention looks for the view inside of a folder with the name of the module, but with the suffix Module trimmed of, that is located in the views folder of the application.
If you do not provide a view name and only send in the model, then Nancy will derive the view name from the name of the model type. If the name of the model ends with Model
then it will be stripped off.
-
Customer
model type name ->Customer
view name -
CustomerModel
model type name ->Customer
view name
The default conventions definitely won’t suit the need of all applications, or perhaps not always suit your personal preference on where views should be stored. For these scenarios the view conventions, as with everything else in Nancy, are overridable.
To do this, you will need to create a custom bootstrapper and add your conventions (using the function signature described earlier) to the Conventions.ViewLocationConventions
collection.
For example:
public class CustomConventionsBootstrapper : DefaultNancyBootstrapper
{
protected override void ApplicationStartup(TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
this.Conventions.ViewLocationConventions.Add((viewName, model, context) =>
{
return string.Concat("custom/", viewName);
});
}
}
This would add a view location convention which would look for the view inside of a folder called custom that should be located at the root of the application.
The ViewLocationConventions
collection is a standard list that can be modified, using the normal operators it provides. This enables you to do things such as deleting the default conventions or changing the order in which conventions are invoked.
You can also call .Insert(0, *convention*)
as well so that it is evaluated first, before all others. Then the existing View Conventions can be used as fall-backs.
You can also create a class that implements the IConvention
interface and in the Initialise
method you add you conventions to the ViewLocationConventions
property of the conventions that are passed in.
Nancy will locate all implementation of the interface and wire up the conventions, before they are passed onto the ConfigureConventions
method of the bootstrapper.
« Part 10. Tips for Implementing your own View Engine — Documentation overview — Part 12. Localization »
- Introduction
- Exploring the Nancy module
- Routing
- Taking a look at the DynamicDictionary
- Async
- View Engines
- Using Models
- Managing static content
- Authentication
- Lifecycle of a Nancy Application
- Bootstrapper
- Adding a custom FavIcon
- Diagnostics
- Generating a custom error page
- Localization
- SSL Behind Proxy
- Testing your application
- The cryptography helpers
- Validation
- Hosting Nancy with ASP.NET
- Hosting Nancy with WCF
- Hosting Nancy with Azure
- Hosting Nancy with Suave.IO
- Hosting Nancy with OWIN
- Hosting Nancy with Umbraco
- Hosting Nancy with Nginx on Ubuntu
- Hosting Nancy with FastCgi
- Self Hosting Nancy
- Implementing a Host
- Accessing the client certificate when using SSL
- Running Nancy on your Raspberry Pi
- Running Nancy with ASP.NET Core 3.1