This is a view engine for ASP.NET MVC using the Pug (formerly Jade) template engine for NodeJS.
As of now, it only supports MVC 5. MVC 6 (ASP.Net Core) support is planned, but Edge.js (which PugViewEngine uses to execute Pug) is still working on .Net Core support.
Can be installed from NuGet:
PM> Install-Package PugViewEngine
Requirements
- Visual Studio 2015 (the Community Edition should suffice)
- NPM Task Runner plugin for Visual Studio (used to get NPM packages)
Additional configurations may work, but this is all I have tested so far. I hope to support MonoDevelop on OS X and Linux, and the dotnet cli once .Net Core support is added.
In your Global.asax.cs
file, add the following line at the end of the Application_Start()
method:
ViewEngines.Engines.Add(new PugViewEngine.PugViewEngine());
When processing views, MVC will use Pug for views with the .pug
extension and Razor for .cshtml
. If you want to remove Razor entirely:
ViewEngines.Engines.Clear(); // call this first to clear all view engines
ViewEngines.Engines.Add(new PugViewEngine.PugViewEngine()); // then this to add PugViewEngine
Just create views as you normally would, just using the .pug
extension instead of .cshtml
, and Pug syntax instead of Razor syntax.
Within the view, you will have 3 JavaScript objects available: model
, viewBag
, and html
.
model
is your the model passed to the view. If your C# code looked like this:
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
....
// in PersonController
public ActionResult View()
{
PersonModel model = new PersonModel{
FirstName = "John",
LastName = "Doe",
Age = 35
};
return View(model);
}
in your view you can do something like:
// in Views/Person/View.pug
h2 Person
ul
li First Name: #{model.FirstName}
li Last Name: #{model.LastName}
li Age: #{model.Age}
and the resulting HTML will be:
<h2>Person</h2>
<ul>
<li>First Name: John</li>
<li>Last Name: Doe</li>
<li>Age: 35</li>
</ul>
You can use viewBag
the same way. You can set the value in C#:
ViewBag.Message = "This is our message.";
and in the Pug view:
h2 Message:
p= viewBag.Message
resulting in:
<h2>Message:</h2>
<p>This is our message.</p>
modelErrors
is a collection of key-value pairs, where the key is the model property name and the value is the error message string. It is populated from the ModelState
.
Example of a login form using modelErrors
to display error messages (using Bootstrap for styling):
form(novalidate="novalidate", action="/login", method="post")
each error in modelErrors.filter(e => e.Key === "")
.alert.alert-danger
= error.Value
.form-group(class=modelErrors.some(e => e.Key === "Email") ? "has-error" : "")
label.control-label(for="Email") Email:
input#Email.input-validation-error.form-control(
autofocus="autofocus",
name="Email",
type="text",
value=model.Email)
each error in modelErrors.filter(e => e.Key === "Email")
span.help-block= error.Value
.form-group(class=modelErrors.some(e => e.Key === "Password") ? "has-error" : "")
label.control-label(for="Password") Password:
input#Password.input-validation-error.form-control(
autofocus="autofocus",
name="Password",
type="password")
each error in modelErrors.filter(e => e.Key === "Password")
span.help-block= error.Value
.checkbox
label
input#RememberMe(type="checkbox", name="RememberMe", value="true", checked=model.RememberMe)
| Remember Me?
input.btn.btn-primary(type="submit", value="Log in")
html
provide various helpers, similar to @Html
in Razor views. In fact, most of the Pug html
helper functions call Razor's @Html
helper behind the scenes.
Here are all the helpers that are implemented so far:
action
- Renders a child action- That's it right now, more to come soon. Pull requests welcome.
action(actionName, controllerName, routeValues)
Renders a child action. Calls HtmlHelper.Action()
behind the scenes. The view engine the child view uses doesn't matter, this helper will insert the rendered HTML.
actionName
and controllerName
are strings, while routeValues
is a JavaScript object. controllerName
can be null
if the child action is in the same controller as the current action.
div.nav-bar= html.action("NavBar", "Common", null)
...
div.article= html.action("Article", null, {articleId: 4})
The first example would render the NavBar()
action in the CommonController
controller class. The second example would render the Article(int articleId)
action in the same controller the current action is in, passing a value of 4 in the articleId
parameter.