Introducing a new Markdown View Engine for ASP.NET Core

Jan 01, 2017     Viewed 3999 times    9 Comments
Posted in #markdown  #ViewEngine 

One of the things that I have been working on has been a new view engine option for ASP.NET Core. ASP.NET Core has always supported the concept of view engines which allow you to use a different template syntax options for your views.

ASP.NET Core shipped with a default view engine that called Razor which is of course is the view engine that knew and love from the previous version of ASP.NET.

The new view engine option I have been working on is using markdown syntax which is become popular last few years, especially for those who are working on GitHub.

What is Markdown?

Markdown is a lightweight markup language with plain text formatting syntax designed so that it can be converted to HTML and many other formats using a tool by the same name. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor. (Wikipedia)

Compared with Razor Syntax

To illustrate the similarities with Razor syntax let me show you some examples that Scott Gu mentioned them long time back in his blog post Introducing "Razor" - new view engine for ASP.NET.

Hello World Sample with Razor

Building it with Razor Syntax

<h1>Razor Example</h1>

<h3>
    Hello @name, the year is @DateTime.Now.Year
</h3>

<p>
   Checkout <a href="/Product/Details/@productId">this product</a>
</p>

Building it with Markdown Syntax

# Razor Example

### Hello @name, the year is @DateTime.Now.Year

Checkout [this product](/Product/Details/@productId)

Loops and Nested HTML Sample

Building it with Razor Syntax

<ul id="products">

    @foreach(var p in products) {
        <li>@p.Name ($@p.Price)</li>
    }

</ul>

Building it with Markdown Syntax

@foreach (var p in products) {
  - @p.Name: ($@p.Price)
}

If-Blocks and Multi-line Statements

If Statements

Building it with Razor Syntax

@if(products.Count == 0) {
    <p>Sorry - no products in this category<p>
} else {
    <p>We have a products for you!</p>
}

Building it with Markdown Syntax

@if (products.Count == 0) {
Sorry - no products in this category
} else {
We have products for you!
}

Multi-line Statements

Building it with Razor Syntax

@{
    int number = 1;
    string message = "Number is " " + number;
}

<p>Your Message: @message</p>

Building it with Markdown Syntax

@var number = 1
@var message = ""Number is "" + number

Your Message: @message

Integrating Content and Code

Does it break with email addresses and other usages of @ in HTML?

Building it with Razor Syntax

<p>
    Send mail to scottgu@microsoft.com telling him the time: @DateTime.Now.
</p>

Building it with Markdown Syntax

Send mail to scottgu@microsoft.com telling him the time: @DateTime.Now.

Identifying Nested Content

Building it with Razor Syntax

@if (DateTime.Now.Year == 2010) {
    <span>
        if year is 2010 then print this <br/>
        multi-line text block and
        the date: @DateTime.Now
    </span>
}

Building it with Markdown Syntax

@if (DateTime.Now.Year == 2011) {
If the year is 2011 then print this
multi-line text block and
the date: @DateTime.Now
}

Layout/MasterPage Scenarios – The Basics

Simple Layout Example

Building it with Razor Syntax

<!DOCTYPE html>
<html>
    <head>
        <title>Simple Site</title>
    </head>
    <body>

        <div id="header">
            <a href="/">Home</a>
            <a href="/About">About</a>
        </div>

        <div id="body">
            @RenderBody()
        </div>
    <body>
</html>
@{
    LayoutPage = "SiteLayout.cshtml";
}

<h1>About this Site</h1>

<p>
    This is some content that will make up the ""about""
    page of our web-site. We'll use this in conjunction
    with a layout template. The content you are seeing here
    comes from Home.cshtml file.
</p>
<p>
    And obviously I can have code in here too. Here is the
    current date/time: @DateTime.Now
</p>

Building it with Markdown Syntax

<!DOCTYPE html>
<html>
    <head>
        <title>Simple Site</title>
    </head>
    <body>

        <div id="header">
            <a href="/">Home</a>
            <a href="/About">About</a>
        </div>

        <div id="body">
            @Body
        </div>

    </body>
</html>
@Layout SiteLayout

# About this SiteThis is some content that will make up the ""about""

page of our web-site. We'll use this in conjunction
with a layout template. The content you are seeing here
comes from Home.md file.

And obviously I can have code in here too. Here is the
current date/time: @DateTime.Now

Layout/MasterPage Scenarios – Adding Sections Overrides

Coming soon ...

As we have seen before markdown view engine make it easier to write clean views without writing HTML tags, but with the limitation of markdown syntax, we saw that we mix both html and markdown especially in layout pages to wrap up the content pages within <body> and use some styles and scripts, thanks CommonMark.NET that makes my life happy and make such thing possible.

FYI this is just a prototype which is still in development so that is why I quote some of the Razor syntax to add dynamic functionality to the content, but still I'm thinking if Razor-like syntax is better choice - like what we saw in @Body - or we may use handlebars - like {{Body}} - or any other sytax to provider rich functionalities.

You can download the source code for this post from my MarkdownViewEngine repository on GitHub.

Twitter Facebook Google + LinkedIn


9 Comments

Andrew Whitworth (1/3/2017 7:52:47 AM)

I like markdown and have used it on a number of occasions, but the biggest selling point for me would be if the new view engine could be used outside the context of a hosted process. If you could create a MarkdownViewEngine in normal C# code and use it to render templates, that would be the biggest selling point for me. If I want to use Razor to, for example, render html for an email body, I can't use the version in System.Web.* but instead have to pull in some third party option. If you enabled this in your Markdown view engine, I would switch almost immediately.

Hisham Bin Ateya (1/3/2017 7:31:14 PM)

@Andrew Whitworth could you please open an issue in the repo

Anth (1/3/2017 11:04:40 PM)

Seems interesting, good post but please proofread as there are a lot of grammar issues. Also, please reduce the margin and padding of the page on mobile, only half the screen width is used.

Calvin Rodo (1/5/2017 11:48:43 AM)

I'm not sure I really see the use case for dynamic functionality in markdown views. The real benefit I'd see for this is rendering comments and other user generated text. The main drawback I see with using this to replace the Razor View engine is that if you need to touch any html attributes say for instance your styling your code using css classes, you now have to mix HTML in with your markdown and if that's the case why not just Razor?

Hisham Bin Ateya (1/6/2017 6:44:44 AM)

@Calvin Rodo this is just a prototype and not replacement for Razor Engine. Regarding mixing HTML in markdown this way that I come up with to support layouts, due the limitation of markdown to render head & body tags

Elixir Software (1/14/2017 3:50:40 AM)

I like markdown , and I'm building my sites faster

Hisham Bin Ateya (1/17/2017 2:19:57 PM)

@Elixir hope the this view engine will help you when you migrate to ASP.NET Core :)

Tsahi (1/17/2017 10:40:37 PM)

I agree with @CalvinRodo. With all do respect for Markdown, it is not a replacement for HTML, because it gives you little control over styling. HTML attribues are also used for validation, accessibility and probably other uses, which can't be expressed with Markdown.

So this is a nice excersie with building a view engine, but not something usefull for a real web site.

And a final unrelated note: This blog engine is weird. It blocks my mouse right-click, so I can't select my spell checker language (a Firefox feature). Very annoying.

Hisham Bin Ateya (1/18/2017 5:19:42 PM)

@Tsahi you are right the Markdown doesn't give you a full control of the style, but it's a good for some scenarios such as Blogs, Documentations .. etc. FYI I build sort of documentation tool with this view engine, you can check it out mDocs: Building a project documentation using Markdown View Engine

Regarding the mouse right click it's not an issue I didn't in the early days for a reason, but I will try to get on that soon


Leave a Comment