DotLiquid模板引擎简介
DotLiquid是一個在.Net Framework上運行的模板引擎,采用Ruby的Liquid語法,這個語法廣泛的用在Ruby on rails和Django等網頁框架中。
DotLiquid相比于Mvc默認模板引擎Razor的好處有:
因為不需要編譯到程序集再載入
首次渲染速度很快
不會導致內存泄漏
可以在任何地方使用
不需要先準備WebViewPage,ViewContext等復雜的上下文對象
DotLiquid的官網是http://dotliquidmarkup.org/,開源協議是非常寬松的MS-PL。
示例代碼
我創建一個使用了DotLiquid的示例Mvc項目,完整代碼可以查看這里。
以下的示例將以Mvc中的Action為單位,都存放在HomeController下。
最基礎的使用
Template.Parse可以把字符串解析為模板對象,再使用Render把模板對象渲染為字符串。
打開頁面可以看見Hello, World!。
?var template = Template.Parse("Hello, {{ name }}!"); ?
??var result = template.Render(Hash.FromAnonymousObject(new { name = "World" })); ?
??return Content(result); }
使用過濾器
在|后面的就是過濾器,過濾器可以連鎖起來使用。
escape過濾器用于做html編碼,避免name中的"<"當成是html標簽描畫。
upcase過濾器把字符串中的字母全部轉換為大寫。
打開頁面可以看見Hello, <WORLD>!。
定義過濾器
DotLiquid支持自定義過濾器,首先需要一個過濾器類型,其中的函數名稱就是過濾器名稱。
過濾器支持多個參數和默認參數。
在網站啟動的時候把這個過濾器注冊到DotLiquid
public class MvcApplication : System.Web.HttpApplication{ ? ?protected void Application_Start() ? ?{ ? ? ? ?// 在原有的代碼下添加Template.RegisterFilter(typeof(DotliquidCustomFilter));} }這個例子會顯示Hello, orl!
public ActionResult CustomFilter(){ ? ?var template = Template.Parse("Hello, {{ name | substr: 1, 3 }}!"); ? ?var result = template.Render(Hash.FromAnonymousObject(new { name = "World" })); ? ?return Content(result); }使用標簽
DotLiquid中有兩種標簽,一種是普通標簽(Block),一種是自閉合標簽(Tag)。
這里的assign是自閉合標簽,if是普通標簽,普通標簽需要用end+標簽名閉合。
顯示內容是Hello, World!
自定義標簽
這里我將定義一個自閉合標簽conditional,這個標簽有三個參數,如果第一個參數成立則描畫第二個否則描畫第三個參數。
public class ConditionalTag : Tag{ ??public string ConditionExpression { get; set; } ? ?
?
?public string TrueExpression { get; set; } ? ?public string FalseExpression { get; set; } ?
?
?public override void Initialize(string tagName, string markup, List<string> tokens) ? ?{ ? ? ?
??base.Initialize(tagName, markup, tokens); ? ? ?
??var expressions = markup.Trim().Split(' ');ConditionExpression = expressions[0];TrueExpression = expressions[1];FalseExpression = expressions.Length >= 3 ? expressions[2] : "";} ?
??
???public override void Render(Context context, TextWriter result) ? ?{ ? ? ?
??? ?var condition = context[ConditionExpression]; ? ? ?
??? ??if (!(condition == null || condition.Equals(false) || condition.Equals("")))result.Write(context[TrueExpression]); ? ? ? ?else ? ? ? ? ? ?result.Write(context[FalseExpression]);} }
在網站啟動時把這個標簽注冊到DotLiquid
public class MvcApplication : System.Web.HttpApplication{? ?protected void Application_Start() ? ?{ ? ? ? ?// 在原有的代碼下添加Template.RegisterTag<ConditionalTag>("conditional");} }
這個例子會顯示Bar
public ActionResult CustomTag(){? ?var template = Template.Parse("{% conditional cond foo bar %}");
? ?? ?var result = template.Render(Hash.FromAnonymousObject(new { cond = false, foo = "Foo", bar = "Bar" })); ? ?return Content(result); }
模板文件
DotLiquid也支持從文件讀取模板,需要先定義一個TemplateFileSystem。
public class DotliquidTemplateFileSystem : IFileSystem{ ? ?public string ReadTemplateFile(Context context, string templateName) ? ?{ ? ? ? ?var path = context[templateName] as string; ? ? ? ?if (string.IsNullOrEmpty(path)) ? ? ? ? ? ?return path; ? ? ? ?var fullPath = HttpContext.Current.Server.MapPath(path); ? ? ? ?return File.ReadAllText(fullPath);} }設置DotLiquid使用自定義的文件系統
public class MvcApplication : System.Web.HttpApplication{ ? ?protected void Application_Start() ? ?{ ? ? ? ?// 在原有的代碼下添加Template.FileSystem = new DotliquidTemplateFileSystem();} }再定義一個控制器基類
public abstract class DotliquidController : Controller{ ??public ContentResult DotliquidView(string path = null, object parameters = null) ?
?{ ? ? ? ?// 路徑為空時根據當前的Action決定if (string.IsNullOrEmpty(path)){ ? ? ? ? ? ?var controller = RouteData.Values["controller"]; ? ? ?
? ? ? ?var action = RouteData.Values["action"];path = $"~/DotliquidViews/{controller}/{action}.html";} ? ? ? ?// 根據路徑讀取模板內容var templateStr = Template.FileSystem.ReadTemplateFile(new Context(), "'" + path + "'"); ? ? ? ?// 解析模板,這里可以緩存Parse出來的對象,但是為了簡單這里就略去了var template = Template.Parse(templateStr); ? ? ? ?// 描畫模板Hash templateParameters; ? ?
? ? ? ?if (parameters is IDictionary<string, object>)templateParameters = Hash.FromDictionary((IDictionary<string, object>)parameters); ? ? ?
? ? ? ??elsetemplateParameters = Hash.FromAnonymousObject(parameters ?? new { }); ? ? ?
? ? ? ?? ?var result = template.Render(templateParameters); ? ? ? ?// 返回描畫出來的內容return Content(result, "text/html");} }
現在可以在控制器中使用基于DotLiquid的模板了
public ActionResult HelloTemplateFile(){ ? ?return DotliquidView(); }上面會返回文件~/DotliquidViews/Home/HelloTemplateFile.html的內容
Hello, Template!嵌入子模板
為了實現代碼的重用,DotLiquid的模板還可以嵌入其他子模板,嵌入需要使用include標簽。
以下例子會顯示Hello, Include!
文件~/DotliquidViews/Home/HelloInclude.html的內容
Hello, {% include "~/DotliquidViews/Home/HelloIncludeContents.html" %}!文件~/DotliquidViews/Home/HelloIncludeContents.html的內容
Include繼承父模板
除了嵌入子模版,還能實現布局(Layout)方式的繼承父模板,繼承需要使用extends和block標簽。
以下例子會返回Html<div class="layout"><h1>Here is title</h1><p>Here is body</p></div>
文件~/DotliquidViews/Home/HelloExtendsLayout.html的內容
<div class="layout"><h1>{% block title %}Default title{% endblock %} ? ?</h1><p>{% block body %}Default body{% endblock %} ? ?</p></div>文件~/DotliquidViews/Home/HelloExtends.html的內容
{% extends "~/DotliquidViews/Home/HelloExtendLayout.html" %}{% block title %} Here is title {% endblock %}{% block body %} Here is body {% endblock %}描畫自定義對象
請先看以下的例子
public class ExampleViewModel{ ??public string Name { get; set; } ?
? ?public int Age { get; set; } } public ActionResult CustomObject(){
? ?var template = Template.Parse("Name: {{ model.Name }}, Age: {{ model.Age }}"); ?
? ? ?var model = new ExampleViewModel() { Name = "john", Age = 35 }; ?
? ? ??var result = template.Render(Hash.FromAnonymousObject(new { model })); ?
? ? ?? ?return Content(result); }
你可能預料這個例子會顯示Name: john, Age: 35,但實際運行時會給出以下錯誤
Name: Liquid syntax error: Object 'Dotliquid.Example.Dotliquid.ExampleViewModel' is invalid because it is neither a built-in type nor implements ILiquidizable, Age: Liquid syntax error: Object 'Dotliquid.Example.Dotliquid.ExampleViewModel' is invalid because it is neither a built-in type nor implements ILiquidizable這是因為DotLiquid為了安全性,默認不允許描畫未經注冊的對象,這樣即使模板由前端使用者提供也不會導致信息泄露。
為了解決上面的錯誤,需要把ExampleViewModel注冊為可描畫的對象。
除了使用RegisterSafeType注冊,你也可以讓ExampleViewModel繼承ILiquidizable,在部分場景下會更適合。
?protected void Application_Start() ?
?{ ? ? ? ?// 在原有的代碼下添加Template.RegisterSafeType(typeof(ExampleViewModel), Hash.FromAnonymousObject);} }
寫在最后
DotLiquid是一個靈活性很高并且依賴很少的模板引擎,雖然沒有Razor流行,但大量的單元測試保證它可以經得起實際的使用。
目前使用了DotLiquid的項目有
Pretzel靜態網站生成工具
Nancy網頁框架
ZKWeb網頁框架
目前DotLiquid準備升級2.0版本,作者正在召集PR,如果你有意向可以到DotLiquid的github看看。
原文地址:http://www.cnblogs.com/zkweb/p/5864794.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的DotLiquid模板引擎简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Visual Studio“15”启动速
- 下一篇: 基于Bootstrap 3.x的免费高级