# not_so_free_marker **Repository Path**: somereason/NotSoFreeMarker ## Basic Information - **Project Name**: not_so_free_marker - **Description**: 依照java freemarker的语法,实现一个python版本的模板渲染工具,用于根据需要生成本文,CSV,代码等等。因为功能相比于freemarker少很多,所以叫not so free marker - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-09-06 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: template-engine **Tags**: None ## README # NotSoFreeMarker 本工具通过设定模板和数据,渲染最终的文本.其中模板的支持if,循环和简单的运算.可用于生成复杂的代码,数据表格等,减少手工劳动. ## 调用方式 本工具的目标场景是读取数据文件和模板文件进行处理.模板和数据分别重复使用,组合生成不同的文件(如读取不同表的列,生成pojo和model的代码).这样也便于其它语言调用.此外还提供了基于文本和数据字典的调用,便于python语言调用. ```python import NotSoFreeMarker processed_str = NotSoFreeMarker.process(模板的内容,用于渲染的数据[map类型],include文件的路径[可选]) processed_str = NotSoFreeMarker.process_file(模板文件路径,json数据文件路径) ``` ## 数据格式 如果是数据文件,格式应该是json.注意,由于python语言的原因,对json的要求比较严格.如属性的名字必须用引号括起来等. 另外,数据的根结构不能是数组.如果要用数组,需要放在某个属性下,如: ```javascript //不可以 [ 1,2,3,4 ] //可以 { "array":[1,2,3,4] } ``` 如果直接输入数据,数据应该是map类型.map中,可以嵌套map,数组. ## 模板 模板的语法使用类似freemarker(后悔当初没借鉴velocity的,感觉那个实现更简单),支持变量,循环,条件,和简单的表达式. 这里是例子数据,后面的例子都基于这个: ```javascript { "a":1, "b":2, "c":[10,20,30], "d":{ "e":"abc", "f":"efg" } } ``` ### 变量 变量采用${变量名的格式},例如 * ${a} * ${c[0]} * ${d.e} 另外变量这里支持简单的表达式,支持的范围以python能解析为准,比如 * ${a+b} * ${c[10]+5*a} * ${len(d.f)} //len是python里取长度的函数 ### 函数 写变量的时候,支持简单的函数,如刚才提到的 * ${len(d.f)} //len是python里取长度的函数 但是,由于实现的比较简单.只支持"函数名(变量)"这样简单的函数.因此.如果要对内容进行深入一点的加工就不行了(比如想把内容变为大写,写成${内容.upper()}是不行的.因为代码无法识别这样的函数.) 为了解决这个问题,我写了几个内置函数,封装了常见的操作.他们都是用nsfm开头的.如${nsfm_upper(变量)},这种写法可以把变量的内容变为大写. 这些函数有: * nsfm_lower 变为小写 * nsfm_upper 变为大写 > 只支持"函数名(变量)"这样简单的函数的原因:函数书写比较自由,如a.b.c(e.f.g),这其中,a.b.c或者e.f.g都有可能是变量,也可能是某个函数(如os.path.abspath) > 设计的时候这里考虑的不周到.因而有一些bug.为了可用性起见.还是粗暴的用目前的方式来实现.等有时间了再改进. ### 循环 循环采用一对<#list>标签. 写法 ```html <#list d as item> ${item} <#/list> 输出为: 10 20 30 ``` 如果想要在循环中使用索引,可以加上index变量,写法为 ```html <#list items as (item,index)> ${item},${index} <#/list> 输出为: 10,0 20,1 30,2 ``` ### 条件 条件支持if,elseif,else, 写法: ```html <#if a>0 > a大于0 <#elseif a<=0 and a>-1> a在0和-1之间 <#else> a小于-1 ``` 其中,<#if>和都必须存在,剩下两个标签可选 ### 引用 模板还支持引入另外一个文件,这样可以把模板里公共的部分放到另外一个文件中. <#include "文件路径"> ### 注释 在模板中添加的注释,不会被渲染到结果中。 注释支持多行,注意<#--和-->中,尖括号与#和--之间,不可以有空格。 另外注释不支持嵌套 ```html <#-- 多行注释 --> <#--单行注释--> <#-- <#--这样嵌套的注释是不可以的--> --> ```