Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

语法整理 #1

Closed
otakustay opened this issue Oct 28, 2013 · 1 comment
Closed

语法整理 #1

otakustay opened this issue Oct 28, 2013 · 1 comment

Comments

@otakustay
Copy link
Member

Issue方便讨论,就在这里了:

母板

<!-- master: masterName(master=masterName) -->
    <!-- contentplaceholder: x -->
    <!-- /contentplaceholder -->
    Additional content
    <!-- contentplaceholder: y -->
    <!-- /contentplaceholder -->
<!-- /master -->

母板即建立一个模板,里面放一些“变量”,继承母板的目标或者子母板通过填充这些“变量”来实现输出。

母板可以指定一个父母板,形成多层的母板关系。但父母板中的contentplaceholder不会再传递下去,即contentplaceholder只在一层有效。

自闭合。内部可嵌套任何条件和循环语句。

内容片

<!-- contentplaceholder: name -->
default content
<!-- /contentplaceholder -->

内容片用在母板中,为一个占位空间。

内容片 必须 闭合。内部可嵌套任何条件和循环语句。

内容片的起始和结束之间放的东西为“默认内容”,即使用此母板的目标或母板未使用content片段定义这个内容片时,使用此默认内容。

目标

<!-- target: targetName(master=masterName) -->
    <!-- content: x -->
    Replaced content
    <!-- /content -->
<!-- /target -->

<!-- target: targetName -->
target content could be any HTML
<!-- /target -->

目标就是最简单的一个模板块,使用getRendererrender,提供targetName即可使用。

master参数可选。

自闭合。内部可嵌套任何条件和循环语句。

内容

<!-- content: x -->
Content
<!-- /content -->

用于覆盖母板中定义的一个内容片,内容的名称必须与母板定义的对应。如果一个内容名称在母板中未定义,则报错。

自闭合。内部可嵌套任何条件和循环语句。

混合

<!-- mixin: mixinName($arg1, $arg2...) -->
    Content
<!-- /mixin -->

混合就是个辅助函数,不能单独被getRendererrender使用,只能在其它的母板、目标中引入。

引入混合使用如下语法:

<!-- use: mixinName -->

使用useimport区分,前者负责混合的引入,后者负责目标的引入。

目标可以当混合用,但目标是不能传递参数的,而混合可以传递参数。

管道

同Linux的概念;

${x|date}

则将x这个数据,调用date这个管道处理器(在模板引擎中我们叫filter)。

管道处理器可以有参数:

${x|date('yyyy-MM-dd', true)}

则调用date管道处理器时会把参数跟上,如这么实现:

function dateFilter(value, format, useLocale) {
    if (!useLocale) {
        value = value.getUTCDate();
    }
    return formatDate(value, format)
}

关于管道处理器怎么设计我们另开Issue讨论。

给管道传参还可以用另一个动态数据:

${x|date(${dateFormat}, true)}

这个实现不知道代价有多大,但很实用。

既然叫管道,自然可以连着用:

${x|raw|customEncode|highlightKeyword(${keyword})|html}

意思就是:先原样输出(禁用默认的HTML编码),再通过customEncode进行自定义编码,再高亮关键词(使用keyword为关键词),再进行HTML编码。

当然语法上要适应空格,不然粘一起太丑:

${x | raw | customEncode | highlightKeyword(${keyword}) | html}

块处理器

相比管道对单个数据生效,块处理器弥补2个问题:

  • 管道只对蛮量生效,不对常量作用
  • 管道不能有一块东西给它用

块处理器在定义后能这么写:

<!-- filter: markdown(${useExtra}, true) -->
## markdown document

This is the content, also I can use `${variables}`
<!-- /filter -->

当然这么一写就能嵌套组合了,不再详述。

块处理器一样能传参数。任何管理处理器都能当块处理器用,纯粹是调用语法上的变化而已。

其它

  • 循环:<!-- for: ${list} as ${item}, ${index} -->
  • 遍历:<!-- for: ${object} as ${value}, ${key} -->
  • 分支: <!-- if: condition --><!-- elif: condition --><!-- else -->

总结

与原tpl相比,主要变化在:

  1. master可以有master,这在多级布局中很重要
  2. contentplaceholder有默认内容,可以不被覆盖,我实际使用中也倍感需求
  3. 增加mixin,主要为了使用的时候可以传参,非常重要
  4. 管道模型,这能让模板更具编程性

问题

  1. 要不要能定义变量?<!-- var ${i} = 1 -->,我认为有必要,在循环中格外有用,但作用域怎么控制是个问题(要不要块作用域)
  2. 特殊的管道处理器给个简写,现在能想到的就是“不HTML编码”能写成${:xxx}吧
  3. 需要有个办法在模板中加注释,此类注释render后会消失,建议<!-- // xxx -->
  4. 有一个很高级的功能叫“属性省略”,即比如<input value="${value}" />,则如果${value}为空时,输出的是<input />,这个太高级了我觉得不用做,但有这功能的话模板用着会非常非常舒服。ASP.NET的Razor是有这功能的,jade也有
@errorrik
Copy link
Contributor

问题的2暂时不支持,可以考虑考虑。4就算了,不是特异性的模板,做这种处理,性能就基本不用看了哈。

and,没有mixin了,只有target。

finished了,就关了哈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants