Liquid模板引擎简单使用
最近在写一个配置表导出工具,自动生成代码那边会用到模板引擎,所以就熟悉了下Liquid的使用。
需要用到一个DotLiquid的库
using DotLiquid; var lqTemplate = Template.Parse(templateContent); var templateHash = new Hash(); // todo 逻辑部分 using (var sw = new StreamWriter("Assets/temp.txt", false, Encoding.UTF8)) { var rdParams = new RenderParameters(); rdParams.LocalVariables = templateHash; rdParams.RethrowErrors = true; lqTemplate.Render(sw, rdParams); }
基础变量+if判断
c#逻辑部分
templateHash["int"] = 123; templateHash["float"] = 10.56f; templateHash["str"] = "Hello World";
模板部分
int: {{ int }}
float: {{ float }}
str: {{ str }}
{% if int > 100 %}
大于100
{% endif %}
{% if str != 'abc' %}
不是abc
{% endif %}
{% if int > 10 and float > 10 %}
int和float都大于10
{% endif %}
模板执行结果

会看到有很多空行,因为模板表达式本身也会输出一行,有没办法去除呢?
去除空格,空行
就是在标签上加个减号
1) 移除到行首的所有空格
{%- %}
{{- }}
2) 移除到行尾的所有空格,或没有任何空格时移除换行符
{% -%}
{{ -}}
3) 两个也可以同时一起用
{%- -%}
{{- -}}
数组
c#逻辑部分
templateHash["StrArray"] = new string[] { "1", "2" };
模板部分
arr.ToString(): {{ #StrArray }}
size: {{ StrArray.size }}
arr[0]: {{ StrArray[0] }}
arr[1]: {{ StrArray[1] }}
arr loop:
{%- for item in StrArray -%}
index_{{ forloop.index }} : {{ item }}
{%- endfor -%}
执行结果

List
c#逻辑部分
var intList = new List<int>(); intList.Add(1); intList.Add(2); intList.Add(3); templateHash["intList"] = intList;
模板部分
intList: {{ intList.size }}
list[0]: {{ intList[0] }}
list[1]: {{ intList[1] }}
{%- for item in intList -%}
index_{{ forloop.index }} : {{ item }}
{%- endfor -%}
执行结果

Dictionary
c#逻辑部分
var dict = new Dictionary<string, object>(); dict.Add("a", 1); dict.Add("b", 2); dict.Add("c", 3); templateHash["dict"] = dict;
模板部分
a: {{ dict.a }}
b: {{ dict.b }}
c: {{ dict.c }}
{%- for entry in dict -%}
index_{{ forloop.index}} : {{ #entry }}, k:{{ entry.Key }}, v:{{ entry.Value }}
{%- endfor -%}
执行结果

无法访问到KeyValuePair的Key和Value属性,也不知道原因。
2)
c#逻辑部分
var dict2 = new Dictionary<int, string>(); dict2.Add(1, "a"); dict2.Add(2, "b"); dict2.Add(3, "c"); templateHash["dict2"] = dict2;
模板部分
dict[1]: {{ dict2[1] }}
dict[2]: {{ dict2[2] }}
dict[3]: {{ dict2[3] }}
{%- for entry in dict2 -%}
index_{{ forloop.index}} : {{ #entry }}, k:{{ entry.Key }}, v:{{ entry.Value }}
{%- endfor -%}
执行结果

执行到遍历的那里会报错,不支持KeyValuePair<int, string>类型

对象
c#逻辑部分
public class Student { public int Age { get; set; } public string m_Name; public string Name { get { return m_Name; } } } var stu = new Student(); stu.Age = 20; stu.m_Name = "ZhangSan"; templateHash["obj"] = Hash.FromAnonymousObject(stu); //不用Hash包装的话会报错
模板部分
age: {{ obj.Age }}
name: {{ obj.Name }}
name: {{ obj.m_Name }}
执行结果

注意:模板中不支持变量访问,支持属性访问
不用Hash包装stu对象,会出现下面的错误

Dictionary当作对象使用
c#逻辑部分
var dictObj = new Dictionary<string, object>(); dictObj.Add("Age", 20); dictObj.Add("Name", "ZhangSan"); dictObj.Add("m_Name", "ZhangSan"); templateHash["dictObj"] = dictObj;
模板部分
age: {{ dictObj.Age }}
name: {{ dictObj.Name }}
name: {{ dictObj.m_Name }}
执行结果

tips:模板内不支持函数调用
对象列表
c#逻辑部分
var stuList = new List<Student>(); for (int i = 0; i < 3; ++i) { var stu2 = new Student(); stu2.m_Name = $"Stu_{i}"; stu2.Age = 20 + i; stuList.Add(stu2); } templateHash["stuList"] = stuList;
模板部分
{%- for item in list -%}
index_{{ forloop.index}} : {{ item.Name }}
{%- endfor -%}
执行会报错

要改成下面这样
var stuList = new List<Hash>(); for (int i = 0; i < 3; ++i) { var stu2 = new Student(); stu2.m_Name = $"Stu_{i}"; stu2.Age = 20 + i; stuList.Add(Hash.FromAnonymousObject(stu2)); } templateHash["stuList"] = stuList;
执行结果

就是自定义类型得用Hash包装一下,liquid才能识别。
模板内定义变量
1) 等号右边为常量时,这样定义变量:{% assign name = 'ZhangSan' %}
{%- assign name = 'ZhangSan' -%}
{%- if name == 'ZhangSan' -%}
名字叫张三
{%- endif -%}
2) 等号右边为变量时,这样定义变量:{% capture name %}{{ stu.Name }}{% endcapture %}
{%- capture name %}{{ obj.Name }}{% endcapture -%}
{%- if name == 'ZhangSan' -%}
名字叫张三
{%- endif -%}
执行结果

参考
Liquid template language (shopify.github.io)
Liquid 语法说明 - Cloudhan - 博客园 (cnblogs.com)
Jekyll With Liquid_liquid定义数组-CSDN博客
Liquid for Designers · Shopify/liquid Wiki (github.com)

浙公网安备 33010602011771号