Chainsaw HTML
Chainsaw.js (cshtml) is an HTML rendering script for Node.js. It can be used with Express.js, Hapi.js or as a stand alone. The syntax is vaguely based on .NET's Razor.
npm install cshtml
Getting Started With Express.js
Simply set the view engine as 'cshtml' and call the response.render function. The first parameter is the name of the file (you don't need the .cshtml extension). The 2nd paramenter is the view model (see below) which is optional.
var express = ;var app = ;app; app;app;
Getting Started With Hapi.js
Chainsaw.js also easily integrated with Hapi.js. If you are unfamiliar with Hapi.js I advise you to review their tutorials. I am showing only the relevant parts because the code is long. Simply define the view engine:
server;
I chose in the above example to work with html files instead of cshtml. You can choose whatever file extension you wish. Then use the standard reply.view command. The first paramater is the name of the file. The second is your object view model.
reply;};
As A Stand-Alone
First you need to 'require' the cshtml model. Then you use the render function with 3 parameters:
- the file to be rendered
- the view model (see below)
- callback function
The callback function receives two parameters: error (if any) and the result which is the rendered HTML.
var http = ;var cshtml = ;var params = title: "hello world"; http;
The View Model
Just like most HTML rendering scripts you have an object with parameters that you want to sprinkle all over your HTML. Chainsaw.js supports all variables including arrays and functions.
var viewModel = title: "welcome" people: name: "bob" age:24 name: "larry"age:32 { return personname + " : his age is "+personage; }
The File Extension
If you're using Express.js, you have use the cshtml extension. If you're using Hapi.js, the file extension is defined in the view engine (see above). If not, you can call them whatever you want, for example:
- Index.html
- Index.txt
- Index.johnDoe
- etc.
Interpolation
Simple double square brackets:
[[title]]
Renders to…
welcome
You can also use interpolation for more complex code (based on the view model above):
[[people.length > 3 ? "long":"short"]][[ printName(people[0])]]
Renders to …
shortbob : his age is 24
Foreach loops
@<span>personname</span> <span>personage</span>
Renders to…
bob 24larry 32
You can also loop over properties in an object. In this example let's assume obj = { name: barney, age: 25 }
@foreach(var prop in obj)[[[[prop]] [[obj[prop]]]]]
Renders to...
name barneyage 25
For loops
@forvar i = 0; i < peoplelength; i++ <span>peopleiname</span> <span>peopleiage</span>
Renders to…
bob 24larry 32
Conditional Statements (If-Else Blocks)
The if statement starts with a @if()... You can follow it with multiple else if's and of course an else. If's can also be nested within other @if block.
@ifpeople0name == "harold" <span>the name is harold</span> else if peoplelength == 3 <span>there are 3 people</span> else <span>the sky is blue<span>
Renders to…
the sky is blue
Switch Case Blocks
A switch case block starts with a @switch(). It's followed by cases. If the case is true, the HTML in the brackets is rendered. You can also add a case default.
var temp = Math@
Declaring Variables
You can define variables using this format:
var temp
or
var temp = 12
If you want to declare a few variables, you'll need to declare them one at a time. Each one in its own brackets [[ ]]
.
Executing Code
Any code you want to execute can be wrapped in a @[[ ]]
. Brackets prefixed with the @ symbol will not render anything.
Important note: any variables declared in these code brackets @[[ ]]
, cannot be accessed outside the code block. If you want to create a variable that is accessible outside the code block, use the [[var..]]
syntax (see above).
Another important note: notice that the syntax within the code brackets is regular javascript, i.e. using if(){}
and for(){}
and not if()[[ ]]
and for()[[ ]]
.
var avg = 0;@ forvar i = 0; i < peoplelength;i++ avg += peopleiage; avg = avg / peoplelength; <h1>The average age is Math</h1>
Will render to
The average age is 28
Rendering Partials
A partial is a different file which contains more HTML that needs to be inserted into your main HTML page. All view model parameters are available in the partial. In your main file add this line:
@render [file path]
views/Index.cshtml
<div id="people-container">@ @render views/partials/textcshtml</div>
views/partials/text.cshtml
[[person.name]] [[person.age]]
Renders to…
bob 24larry 32
Layouts
Using layouts are useful when you want all the pages to have the same header and footer for example. On the main file being rendered you add on top the layout command:
@layout [path to layout file]
On the layout file, you have to add the @renderBody
command to specify where the content is supposed to be rendered. You can also work with several layers of layouts:
views/Index.cshtml
@layout views/innerLayout.cshtmltext text<!--views/Index.cshtml-->
innerLayout.cshtml
@layout views/layout.html <!--innerLayout.cshtml--> @renderBody
Layout.cshtml
[[title]] <!--Layout.cshtml--> @renderBody
Renders to...
welcome<!--Layout.cshtml--> <!--innerLayout.cshtml--> text text<!--views/Index.cshtml-->
Escaping The Chainsaw Command Symbol @ And Double Brackets [[ or ]]
The 'chainsaw command symbol @' doesn't need escaping. If it's followed by a space or a command it doesn't recognize it just renders the @ as is.
Double square brackets have to be escaped using two preceding asterisk **[[
and **]]
:
**[[title**]]
Renders to…
[[title]]
Rendering Sections
Section rendering comes to solve a common problem: You have a site with several content pages and a layout page for all them. Each content page has its own js and css files that need to be loaded in the tags that's on the layout file. How do you easily manage this? the answer - using sections.
On your layout page you designate where each section should be rendered.
layout.html
CHainsaw.js @renderSection scripts @renderSection styles
In the above example, I created two sections named 'styles' and 'scripts'.
Now lets say I have two content pages: home.cshtml and about.cshtml. So on each page, I will reference the section and add within the square brackets [[ ]]
, what I want rendered in that section:
home.cshtml
@section scripts[[]]@section styles[[]]
about.cshtml
@section scripts[[]]@section styles[[]]
The section names in @section [name]
has to correspond to an existing @renderSection [name]
.
The rendered home page will look like this:
Chainsaw.js
We can also have several @section's with the same name on the same page and they will all be rendered together in the relevant section.
Commenting out commands
If any command is wrapped in the usual HTML comment tags, it will be ignored.
<!--@render text.cshtml--><!--[[name]]-->
Renders as…
<!--@render text.cshtml--><!--[[name]]-->
Questions, Comments, Bugs
Feel free to contact me: davidzalmanson@gmail.com