Skip to content
jun@diosay.com edited this page Mar 20, 2014 · 2 revisions

OTPL(Open Template Programming Language),开放模板编程语言。

注:目前OTPL正在努力编写和校正中,语法和规范存在BUG和可能调整,使用请谨慎!并且我们也希望您参与其中,共同完善它。 ##术语定义: LWS:线性空白。由连续的空白( )、制表符(\t)组成。正则表达式为:\s

E(expression): 语法表达式。

CE(Condition expression):条件表达式。要求 CE 中不能有线性空白,如果有则必须将 CE 用括号(())包裹。

VE(Value expression):求值表达式。

NV:(Named variable):命名变量。

##标签定义: 定界符:默认左定界符为 {,默认右定界符为 }。定界符允许在具体实现中更换。由合法定界符包裹的称为一个标签(Markup)

为解决模板布局的设计需要根据具体模板中语法的注释连接定界符也是允许的,如 HTML中 `<!--{...}-->` 或   `/*{...}*/`。

标识符():由字母(a-zA-Z)、数字(0-9)、下划线(_)组成。

语义标记(token):token是标识符、美元符号($)、符号(@)组成。它是定义一个标签语法含义的开始。

独立(span)标签:指一个 Markup 就可以完全表达语义的Markup类型。

{token.../}

块(block)标签: 指需要多个Markup成对出现才能表达语义的Markup类型。

{token} //块开始
...
{/token} //块结束

编译时注释(comment):特殊的标签,它的token是固定的,且只有以下两种。

标签级注释:
{// ... }

块(区域)级注释:
{/* ...}
   comments
   comments
{...*/}

冲突解决

按模板原样输出,主要解决如 javascript、css 等脚本语言的语法问题 :
{literal}
...
{/literal}

说明:在一个标签大括号({})中,不能再次出现 左大括号({)和右大括号(}),如果出现请用引号(""),引号("")中的引号(")请用转义符(\)转义。

关键词:literal,iteration,break,continue,each,for,do,while,odd,even,first,last,if,elif,case,when,in,count

模板文件名后缀

  • *.stpl
  • *.tpl
  • *.stpl.html
  • *.tpl.html

##语法 ###符号

@: 表示函数调用。注意:该语法只能出现在标签的开始。

如:
{@func()}        //正确
{token @func()}  //错误
{@var}           //错误

$: 域变量,也就是在当前作用域下定义的变量,或系统预定义变量。

如:
	{for:i lt<10}
		{$i}        //输出变量 i 的值。
	{/for}
	{$i}            //错误。因为 变量 i 未在作用范围域中。

又如:
	{$view.url}     //输出系统预定义变量 view 的成员属性 url 的值。
	{$view.func()}  //调用系统预定义变量 view 的成员函数 func,该类函数要求必须要用返回值。如果无返回值,则需要在标签开始加 @ 符号,如:{@$view.func()}

注意:变量表达式根语言与数据类型有关,如:$item[3],如果变量item不是集合(数组)类型则可能出错。$obj.property 如果 $obj 不是对象或者没有 property 

变量和函数变量是指在后台运行时由用户处理并传递到模板视图中的值。函数是系统预定义或由用户注册到模板视图中的。与一般编程语言一样他们可以直接使用。用例:

变量名与函数名必须是一个有效的`标识`,并且不能为`关键字`。
		  
	变量:
	{var}                   //正确。直接输出变量 var 。
	{var.prop}              //正确。调用并输出变量的成员属性。
	{var.func()}			//正确。调用并输出变量的成员函数,不输出参见 @ 的使用。
	{var[index]}			//正确。调用并输出变量的成员指定索引的值。index 可以是一个`表达式`。
	{now | format='Y-m-d'}  //正确。采用指定格式化函数输出格式化后的变量 var 。竖线(|)为可选 其后的字符串表示格式化规则。
	{if var<10}             //正确。

	函数:
	{func()}				//正确。调用输出`闭包`,不输出参见 @ 的使用。注意:除非是系统函数,否则不建议这样变量的方式使用,而应该进行运行时`注册`(函数的注册,根据实现语言的不同而不同,目前未定义)。并且根据实现的语言平台,函数也必须符合相应规则,如PHP就必须符合`闭包`的规则。

注意:变量与函数根语言与数据类型有关,如:item[3],如果变量item不是集合(数组)类型则可能出错。obj.property 如果 obj 不是对象或者没有 property 

字符串:标签中的字符中必须是以引号(') 包裹。字符串中包含引号('),必须使用转义符()转义。

.: 获取对象属性,如:foo.bar

[]: 获取数组下标的值,如:arr[index];

():括号。)前面是标识符则表示函数,是操作符则表示范围。如:

  {func()}				//函数
  {if var<(3 + 5)}		//范围

#:数据类型定义。目前系统默认注册了两个类型:mapsetentry 三个类型,其它类型根据实现语言的不同再另行规定。目前系统使用到的标签为:deffor 两个标签。

操作符:直接转换为实现语言与之相匹配的原生操作符。

	`&&`:逻辑与。
	`||`:逻辑或。
	`==`:等于。
	`!=`:不等于。
	`>` :大于。
	`>=`:大于等于。
	`<` :小于。
	`<=`:小于等于。
	`+、-、*、/、% `:常用的加、减、乘、除、模(余) 运算符。
	`=` :赋值。 //有时将作参数使用

def:定义变量。

{def:var}			// 定义动态类型变量 var。
{def:var=val}		// 定义动态变量,并设置初始值为 val。
{def#set:var}		// 定义变量 var 的类型为 set 
{def#set:var=val}	// 定义变量 var 的类型为 set ,并设置初始值为 val。

###变量 ####模板变量 模板变量与语言系统的常量很相似,不能在模板中改变值。直接使用其名称就可以使用,如: {{item}} 直接就可以输出后台定义的item的值。 ####临时变量 临时变量的语法:'$'+标识符 ,临时变量是具有上下文关系的变量,是符合由语言系统的变量,如:{{$var}} php 中 $var , $var=10; c# 中 int var ,int var=10;

{{each:item<int>=list}}
	{{$item.name}}
{{/each}}

{{var:var<int>=10}}

{{for:i=0 i<10 i++}}
{{/for}}

{{rang:i 100}}

###分支: ####if分支 {if CE} ... {elseif CE} ... {else} ... {/if} CE:必须。表示条件表达式。

//OTPL
${if var==13}
${elif :var <15}
${/if}

//PHP
if(data['var']==13){
	
}
else if($var<15){
	
}
//C# 实现
//OTPL
${if int(var)==13}
${elif :var <15}
${/if}
//C#
if(view.ToInt(data['var'])==13){
	
}
else if(var<15){
	
}
//GO 实现
//OTPL
${if int(var)==13}
${elif :var <15}
${/if}
//go
if int(data['var'])==13 {
	
}else if var<15{
	
}

-----
NodeIf		:Node	//TOKEN CLASS
type		:if		//类型
list		:Node[]	//同级列表
children	:Node[] //子级列表
closed		:bool	//是否关闭
args		:		//参数
variables	:		//上下文变量
text		:string	//

####switch分支 {case:NV=VE} ... {when CE} ... {default} ... {/case} NV:必须。表示本次分支的变量。 VE:必须。表示取值表达式,可以直接是一个变量。 CE:必须。表示条件表达式。

###循环:

在OTPL中,只有 `for` 一个循环的概念,其原形如下:

BNF:
FOR_STATEMENT :: =
"for"[":"<"var_name">["<" "type" ">"]"="value expression
"LWS"
("to"|"in"|"loop")[LWS]"="[LWS]["("]value expression [")"]
]statement

OTPL:
{for[:name<type>=VE op=VE]}
...
{forelse}
...
{/for}

{for}{/for}
{for:item<type>=val op=val}{/for}
{for}...{forelse}...{/for}

表达式中方括号("[]"),表示可选。

NV: 循环变量名。T: 表示静态类型,没有则是动态类型。VE: 值,如果为 null 则根据 OP 自动赋值。

OP:操作符和终止值:

	to,in,loop
	
	lt、gt、le、ge:小于、大于、大于等于、小于等于。:i++ 。VE: 默认值:0

	//OTPL
	{for:i lt=100}
	{for:i gt=100}
	{for#int=5 lt=100 step=5}

	//原形解析
	for(var i=0;i<100;i++){}
	for(var i=100;i>0;i--){}
	for(int i=5;i<100;i+=5){}
	
	eq|not: 等于,非,不等于
	//OTPL
	{for eq=NE}
	{for not=NE}
	
	//原形解析
	while(NE){}
	while(!NE){}

	in:列举一个可迭代类型(如:数组)。VE: 默认值:null
	//OTPL
	{for:item in=NE}
	{for#entry:item in=NE}

	//原形解析
	foreach(var item in NE){}
	foreach(entry item in NE){}
	
step: 每次循环的跨度,如果 OP 为 `in` 则忽略。

注意:如果 `NV`、`OP` 均为空白,则为无限循环,如:

	{for}
	...
	{/for}
	
	//原形解析
	while(true){}

循环上下文变量

停止循环。
{break}

将跳过当前本次循环并进入下一次循环。
{continue}

获取当前循环的次数(int)。注意:iteration 获取的次数不同于 循环体的变量 如for,它的初始值为 1,每次迭代加 1。
$iteration:NV
var:循环的变量。

获取当前循环的总次数(int)。
$count:NV
var:循环的变量。

判断当前循环的第一次循环(bool)。它等同于 $iteration:var==1。
$first:NV
var:循环的变量。

判断当前循环的最后一次循环(bool)。它等同于 $iteration:var==$count:var。
$last:NV
var:循环的变量。

判断当前循环的次数是否是偶数(bool)。它等同于 $iteration:var % 2==0。
$even:NV
var:循环的变量。

判断当前循环的次数是否是奇数(bool)。它等同于 !$even:var。
$odd:NV
var:循环的变量。

##预定义模板函数(内置函数):

名称(别名) CLR方法(c#) 说明

强制转换函数:

  • to_short(value) ToInt16(object) 转换为int16或其默认值
  • to_int(value) ToInt32(object)
  • to_long(value) ToInt64(object)
  • to_ushort(value) ToUInt16(object)
  • to_uint(value) ToUInt32(object)
  • to_ulong(value) ToUInt64(object)
  • to_single(value) ToSingle(object)
  • to_double(value) ToDouble(object)
  • to_number(value) ToDecimal(object)
  • to_bool(value) ToBoolean(object)
  • to_str(value) ToString(object)
  • to_date(value) ToDateTime(object)
  • to_guid(value) ToGuid(object)
  • to_type(value,type) ToType(object)

类型验证函数:

  • is_short(value) IsInt16(object)

  • is_int(value) IsInt32(object)

  • is_long(value) IsInt64(object)

  • is_ushort(value) IsUInt16(object)

  • is_uint(value) IsUInt32(object)

  • is_ulong(value) IsUInt64(object)

  • is_single(value) IsSingle(object)

  • is_double(value) IsDouble(object)

  • is_number(value) IsDecimal(object)

  • is_bool(value) IsBoolean(object)

  • is_str(value) IsString(object)

  • is_date(value) IsDateTime(object)

  • is_guid(value) IsGuid(object)

  • is_type(value,type) IsType(object) 未实现

  • is_null(value) IsNull(object)

  • is_empty(value) IsNullOrEmpty(object)

获取函数:

  • get_short(index,data) GetInt16(string,object) 转换为int16或其默认值
  • get_int(index,data) GetInt32(string,object)
  • get_long(index,data) GetInt64(string,object)
  • get_ushort(index,data) GetUInt16(string,object)
  • get_uint(index,data) GetUInt32(string,object)
  • get_ulong(index,data) GetUInt64(string,object)
  • get_single(index,data) GetSingle(string,object)
  • get_double(index,data) GetDouble(string,object)
  • get_number(index,data) GetDecimal(string,object)
  • get_bool(index,data) GetBoolean(string,object)
  • get_str(index,data) GetString(string,object)
  • get_date(index,data) GetDateTime(string,object)
  • get_guid(index,data) GetGuid(string,object)
  • get_type(index,data,type) GetType(string,object)

设置函数:

定义函数:


优化脚本(CSS/JS/LESS-CSS)

{@optimize:js save='file|auto'}
{/optimize}

捆绑脚本

{@bundle:css save='auto|none|filename.ext' optimize='true'}
    <link rel="stylesheet" type="text/css" href="content/css/style.css">
    <style type="text/css">
        dddd
    </style>
{/bundle}

{@static:html path='~/web/static/signin.html' monitor='src'}


nodejs: https://github.com/GoalSmashers/clean-css https://github.com/ded/sqwish https://github.com/fczuardi/node-css-compressor

定义类型: type: 类型是应用语言为静态语言时需要,如C# , 可选: int,long,short,uint,ulong,ushort,datetime,bool,string,float,double,number,set,map var 为动态类型使用,如C# 类的 dynamic 也是允许的 {def:name=10 type='null'}

{cache time="" type="a"}

许可协议

如无另外说明,OTPL 均遵循 CC BY-ND-SA 3.0 协议发布。

Except as noted, the OTPL is licensed under the CC BY-ND-SA 3.0 License。
Clone this wiki locally