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

[译] TrimPath模板引擎语法 #1

Open
loveky opened this issue Dec 3, 2015 · 2 comments
Open

[译] TrimPath模板引擎语法 #1

loveky opened this issue Dec 3, 2015 · 2 comments

Comments

@loveky
Copy link
Owner

loveky commented Dec 3, 2015

TrimPath模板引擎语法

本文翻译自JavaScript Template Syntax

表达式与表达式修饰符

  ${expr}
  ${expr|modifier}
  ${expr|modifier1|modifier2|...|modifierN}
  ${expr|modifier1:argExpr1_1}
  ${expr|modifier1:argExpr1_1,argExpr1_2,...,argExpr1_N}
  ${expr|modifier1:argExpr1_1,argExpr1_2|...|modifierN:argExprN_1,argExprN_2,...,argExprN_M}
  • expr可以是不包含右花括号}的任何合法JavaScript表达式
  • 修饰符的格式是modifierName[:argExpr1[,argExpr2[,argExprN]]]
    • argExpr可以是任何合法的expr
  Examples:
  ${customer.firstName}
  ${customer.firstName|capitalize}
  ${customer.firstName|default:"no name"|capitalize}
  ${article.getCreationDate()|default:new Date()|toCalenderControl:"YYYY.MM.DD",true,"Creation Date"}
  ${(lastQuarter.calcRevenue() - fixedCosts) / 1000000}

这里有一份内置的修饰符列表,你也可以通过TrimPath提供的API来创建自定义的修饰符。

表达式还可以写成${% customer.firstName %}这种形式,多出的%字符允许你的表达式中出现花括号}。例如:

  Visit our ${% emitLink('Solutions and Products', 
                            { color: 'red', blink: false }) %} 

表达式中的空白字符是可选的,你也可以写成下面的格式:

  ${%customer.firstName%}
  ${%customer.firstName|capitalize%}

声明

声明标签可以嵌套使用。

控制流

  {if testExpr} 
    {elseif testExpr}
    {else}
  {/if}
  • testExpr可以是任何不包含}的JavaScript表达式
  • testExpr不需要被()包围

示例:

  {if customer != null && customer.balance > 1000}
    We love you!
  {/if}

  {if user.karma > 100}
      Welcome to the Black Sun.
  {elseif user.isHero}
      Sir, yes sir!  Welcome!
      {if user.lastName == "Yen"}
         Fancy some apple pie, sir?
      {/if}
  {/if}
  <a href="/login{if returnURL != null && returnURL != 'main'}?goto=${returnURL}{/if}">Login</a>

TrimPath引擎还定义了一个帮助方法叫做defined(str),它可以检查给定的参数是否是JavaScript中的undefined值。通过它可以很方便的判断某个值是否被定义:

  {if defined('adminMessage')}
    System Administrator Important NOTICE: ${adminMessage}
  {/if}

循环

  {for varName in listExpr}
  {/for}


  {for varName in listExpr}
    ...循环主体...
  {forelse}
    ...当listExpr的值是null或者长度为0时执行此区域...
  {/for}
  • varName可以是任何合法的JavaScript变量名称
  • listExpr是一个JavaScirpt表达式,它执行结果必须是数组,对象或是null值中的1种。listExpr只会被执行一次。

循环过程中可以访问2个额外的变量:

  • __LIST__varName - 保存了listExpr的执行结果
  • varName_index - 保存了循环过程中当前值对应的索引或是键名。

示例:

  {for x in customer.getRecentOrders()}
    ${x_index} : ${x.orderNumber} <br/>
  {forelse}
    You have no recent orders.
  {/for}

 以下是与上边代码功能相同的伪代码
  var __LIST__x = customer.getRecentOrders();
  if (__LIST__x != null && __LIST__x.length > 0) {
    for (var x_index in __LIST__x) {
      var x = __LIST__x[x_index];
      ${x_index} : {$x.orderNumber} <br/>
    }
  } else {
    You have no recent orders.
  }

变量声明

  {var varName}
  {var varName = varInitExpr}
  • varName可以是任何合法的JavaScript变量名
  • varinitExpr不可以包含}

示例:

 {var temp = crypto.generateRandomPrime(4096)}
  Your prime is ${temp}.  

宏声明

  {macro macroName(arg1, arg2, ...argN)}
    ...body of the macro...
  {/macro}
  • 一个宏就像是一个JavaScript函数,只是宏的主体是另一个模板而不是JavaScript代码。
    • 也就是说宏的主体可以包含TrimPath表达式和声明。
  • macroName可以是任何合法的JavaScript变量名。
  • 宏执行后的返回值是一个字符串。
  • 可以通过${macroName()}的形式调用一个宏。

示例:

  {macro htmlList(list, optionalListType)}
    {var listType = optionalListType != null ? optionalListType : "ul"}
    <${listType}>
      {for item in list}     
        <li>${item}</li>
      {/for}
    </${listType}>
  {/macro}

 使用宏
  ${htmlList([ 1, 2, 3])}
  ${htmlList([ "Purple State", "Blue State", "Red State" ], "ol")}
  {var saved = htmlList([ 100, 200, 300 ])}
  ${saved} and ${saved}

默认情况下,宏只能在定义它的模板中使用。如果你想导出一个宏以便在其他模板中复用,一种方法就是把保存一份宏的引用到contentObject中(contentObject就是你调用template.process方法时传递的参数)。在调用process方法前先设置'contextObject['exported'] = {};,然后可以在末班中通过这种方法获得宏的引用:

 {macro userName(user)}
    {if user.aliasName != null && user.aliasName.length > 0}
      ${user.aliasName}
    {else}
      ${user.login}
    {/if}
  {/macro}
  ${exported.userName = userName |eat}

你也可以直接设置contextObject['exported'] = contextObject;,这样做也可以工作,但是会造成循环引用。

CDATA文本块

  {cdata}
    ...此区域内的文本不会被引擎解析...
  {/cdata}

  {cdata EOF}
    ...此区域内的文本不会被引擎解析...
  EOF

你可以使用{cdata EOF}...EOF或是{cdata}...{/cdata}这2中语法来告诉模板引擎忽略对特定文本块的处理。这些文本块会被直接输出,其中包含的任何标签都不会被解析。当你需要通过JavaScript模板生成其他JavaScript模板时会非常方便。

  • EOF可以是任何不包含}的标记字符串。标记字符串用来标示一个文本块的结束。
  • 文本块可以包含换行符,输出时模板引擎会保留这些换行。

示例:

Hello, ${user.firstName}.
An example of expression markup in JST looks like...
{cdata END_OF_THE_CDATA_SECTION}
 ${customer.firstName} ${customer.lastName}
END_OF_THE_CDATA_SECTION
...which shows a customer's name.

Let me repeat that...
{cdata}
 ${customer.firstName} ${customer.lastName}
{/cdata}
...will show a customer's name.

以上模板会输出以下内容:

Hello, Steve.
An example of expression markup in JST looks like...

 ${customer.firstName} ${customer.lastName}

...which shows a customer's name.

Let me repeat that...

 ${customer.firstName} ${customer.lastName}

...will show a customer's name.

嵌入的JavaScript

eval代码块

  {eval}
    ...模板引擎解析模板时将执行此区域代码...
  {/eval

  {eval EOF}
    ...模板引擎解析模板时将执行此区域代码...
  EOF

EOF可以是任何不包含}的文本。
{eval}块可以用来在模板中定义多行的JavaScript事件处理函数。例如:

  {eval} 
    sel_onchange = function() {
     ...事件处理函数定义...;
    }
  {/eval}

需要注意的是,在上边的事例中我们_没有_使用var关键字来声明变量,例如var sel_onchange = function() {...}。这是为了保证sel_onchange在全局作用域中以便可以被事件处理机制访问到。

minify块

  {minify}
    ...此处可以写多行代码,模板引擎输出时会合并成一行...
  {/minify 

  {minify EOF}
    ...此处可以写多行代码,模板引擎输出时会合并成一行...
  EOF

{minify}块允许你在HTML属性中嵌入多行的JavaScript或CSS代码。对JavaScript来说,这可以很方便的编写多行的事件处理函数。例如:

  <select onchange="{minify}
     ...复杂的多行事件处理逻辑...;
     this.enabled = false;
  {/minify}">

  <select onchange="{minify END_OF_JS}
     ...复杂的多行事件处理逻辑...;
     this.enabled = false;
  END_OF_JS">

对应CSS来说,{minify}允许你方便的嵌入多行行内样式代码,例如:

<div id="commentPanel"
     style="{minify}
              display:none; 
              margin: 1em;
              border: 1px solid #333;
              background: #eee;
              padding: 1em;
            {/minify}">
</div>
@beanlee
Copy link

beanlee commented Apr 22, 2016

翻译的很赞,刚看了眼 jdf-ui 中 trimPath 的源码,特别想让他支持 for 中支持一个 break,有时间搞一下
: )

@keelii
Copy link

keelii commented Nov 22, 2016

我这也一有篇,可以同步参考,哈哈。

TrimPath 模板引擎使用指南

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

No branches or pull requests

3 participants