java模板引擎

主页地址

http://code.google.com/p/trimpath/wiki/JavaScriptTemplateSyntax

 

代码下载

使用:

Updated Feb 04, 2010 by steve....@gmail.com
   JavaScriptTemplateAPI  
JavaScript Templates API
{ JavaScript Templates (JST) home | API | syntax | modifiers | download | community }

Using JavaScript Templates
First, in your HTML/JSP/PHP/ASP file, include the trimpath/template.js JavaScript file.

  <script language="javascript" src="trimpath/template.js"></script>
The trimpath/template.js file can live anywhere you want and may be renamed. It has no dependencies to other files. For example, you might move it to lib/trimpath/template.js or js/trimpath/template.js. We suggest using a subdirectory named trimpath to help you remember what it's about and also give you a space to place more (future) TrimPath components. Future TrimPath components might depend on living in the same directory as trimpath/template.js.

After including trimpath/template.js, a JavaScript variable named TrimPath will hold an Object ready for you to use.

The TrimPath Object
The TrimPath Object is the global singleton object that is the access point for all TrimPath components. Except for this TrimPath Object, we try to keep the global variable namespace clean for you.

The TrimPath Object will have the following JST-related methods...

TrimPath.parseDOMTemplate ( elementId, optionalDocument )
Retrieves the innerHTML of the document DOM element that has the given elementId. The innerHTML is then parsed as a template. This method returns a '''templateObject''', which is described later. Throws an exception on any parsing error. The method parameters are...

'''elementId'''	 Id of the DOM element whose innerHTML is used as the template.
'''optionalDocument'''	 An optional DOM document, which is useful when working with multiple documents with iframes, framesets or multiple browser windows. [BR] Defaults to document.
The document DOM element is usually a hidden

<textarea>
. You can use a style attribute to hide a textarea. For example:
<textarea id="elementId" style="display:none;">
template body
</textarea>
TrimPath.processDOMTemplate ( elementId, contextObject, optionalFlags, optionalDocument )
Helper function that calls TrimPath.parseDOMTemplate() and then the process() method on the returned '''templateObject'''. The output of templateObject.process() is returned. Throws an exception on any parsing error. The method parameters are...

'''elementId'''	 Same as for TrimPath.parseDOMTemplate.
'''contextObject'''	 See templateObject.process()
'''optionalFlags'''	 See templateObject.process()
'''optionalDocument'''	 Same as for TrimPath.parseDOMTemplate.
TrimPath.parseTemplate ( templateContentStr, optionalTemplateName )
Parses a String as a template and returns a '''templateObject''' which is described later. Throws an exception on any parsing error. The method parameters are...

'''templateContentStr'''	 String that has JST markup.	 For example: "Hello ${firstName} ${lastName}"
'''optionalTemplateName'''	 An optional String of the template's name. [BR] Used to help in debugging.	
The templateObject
A templateObject is returned by TrimPath.parseTemplate() and TrimPath.parseDOMTemplate(). It represents a successfully parsed template. A templateObject has one key method...

templateObject.process ( contextObject, optionalFlags )
The process() method merges the template with the '''contextObject'''. The process() method may be called repeatedly, without any template parsing performance overhead, so the highest performance can be had by caching and reusing templateObjects. The return value of this method is a String of the 'rendered' template.

The '''contextObject''' parameter must be an Object, which becomes part of the lookup "scope" of the template. If a template refers to ${a}, then contextObject.a is accessed. For ${a.b.c}, then contextObject.a.b.c is acccessed.

Note that the '''contextObject''' can contain any JavaScript object, including strings, numbers, date, objects and functions. So, calling ${groupCalender(new Date())} would call contextObject.groupCalender(new Date()). Of course, you would have to supply the groupCalender() function, which should return a string value.

The '''optionalFlags''' may be null, or an Object that with the following optional slots...

throwExceptions	 Defaults to false. [BR] When true, the process() method will forward exceptions by re-throwing them. [BR] When false, any exceptions will stop template processing. The caught exception is converted to a String message, which is then appended onto the process()'s return value String, which has any partially processed results so far.
keepWhitespace	 Defaults to false. [BR] When true, all whitespace characters are emitted during template processing. [BR] When false, various whitespace characters (newline, space, tab) that surround statement tags (such as {if}, {else}, {for}) are stripped out to make any output look "cleaner and prettier".
The String.prototype.process() method
String.prototype.process ( contextObject, optionalFlags )
As a convenience, the String prototype is enhanced with a process() method. It parses the String as a template and invokes process(). The arguments are the same as for templateObject.process().

   var result = "hello ${firstName}".process(data)
   // ...is equivalent to...
   var result = TrimPath.parseTemplate("hello ${firstName}").process(data);
Adding Custom Modifiers
You may add your own custom modifiers by placing them into a '''MODIFERS''' Object, which should then be placed into the '''contextObject''' that is passed to the templateObject.process() method. Each custom modifier should be a function that takes minimally one String argument and returns a String. For example...

  var myModifiers = {
    hello : function(str, greeting) { 
      if (greeting == null)
          greeting = "Hello";
      return greeting + ", " + str;
    },
    zeroSuffix : function(str, totalLength) {
      return (str + "000000000000000").substring(0, totalLength);
    }
  };
  var myData = {
    firstName : "John", 
    getCurrentPoints : function() { /* Do something here... */ return 12; }
  }

  myData._MODIFIERS = myModifiers;

  "${firstName}".process(myData) == "John"
  "${firstName|hello}".process(myData) == "Hello, John"
  "${firstName|hello:"Buenos Dias"}".process(myData) == "Buenos Dias, John"
  "${firstName|hello:"Buenos Dias"|capitalize}".process(myData) == "BUENOS DIAS, JOHN"

  "${getCurrentPoints()}".process(myData) == "12"
  "${getCurrentPoints()|zeroSuffix:4}".process(myData) == "1200"
 

 

帮助:

 JavaScriptTemplateSyntax  
JavaScript Template Syntax
{ JavaScript Templates (JST) home | API | syntax | modifiers | download | community }

This page describes the syntax for JavaScript Templates, including its expression markup and statement tags.

Expressions and Expression Modifiers
  ${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}
An expr is any valid JavaScript expression, except for close-brace characters ('}').
A modifier looks like modifierName:argExpr1[,argExpr2[,argExprN]]
An argExpr is an 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}
Please see also the list of standard modifiers and how to use the API to create your own custom modifiers.

Expressions can also be optionally specified as "${% customer.firstName %}" syntax, which has the extra '%' delimiter characters. This syntax is useful if your expressions have brace characters. For example...

  Visit our ${% emitLink('Solutions and Products', 
                         { color: 'red', blink: false }) %} page.
  
  The extra spaces are actually not necessary, like...
  ${%customer.firstName%}
  ${%customer.firstName|capitalize%}
Statements
Statement tags are nestable in just like JavaScript statement blocks (if/else/for/function) are nestable.

Control Flow
  {if testExpr} 
    {elseif testExpr}
    {else}
  {/if}
The testExpr is any valid JavaScript expression, but no close-brace characters.
The testExpr does not require surrounding parenthesis.
  Examples:
  {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>
The JavaScript Template engine also defines a helper function called "defined(str)", which checks its argument for equality with the JavaScript undefined value. It is useful to check if a value is defined in the evaluation context. For example...

  {if defined('adminMessage')}
    System Administrator Important NOTICE: ${adminMessage}
  {/if}
Loops
  {for varName in listExpr}
  {/for}

  {for varName in listExpr}
    ...main body of the loop...
  {forelse}
    ...body when listExpr is null or listExpr.length is 0...
  {/for}
A varName is any valid JavaScript variable name.
A listExpr is a JavaScript expression which should evaluate to an Array, an Object, or to null. The listExpr is evaluated only once.
  Two variables are bound in the main body of the loop:
    __LIST__varName - holds the result of evaluating listExpr.
    varName_index   - this is the key or counter used during iteration.

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

  Converted pseudo-code for the above...
  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.
  }
Variable Declarations
  {var varName}
  {var varName = varInitExpr}
A varName is any valid JavaScript variable name.
A varInitExpr may not have any close-brace characters.
  Examples:
  {var temp = crypto.generateRandomPrime(4096)}
  Your prime is ${temp}.  
Macro Declarations
  {macro macroName(arg1, arg2, ...argN)}
    ...body of the macro...
  {/macro}
A macro is like a JavaScript function, except the body of the macro is another JavaScript Template, not JavaScript.
That is, the body of the macro may contain JST expressions and statements.
The macroName may be any valid JavaScript variable name.
The return value of an invoked macro is a string.
You invoke the macro using the ${macroName()} expression syntax.
  Examples:
  {macro htmlList(list, optionalListType)}
    {var listType = optionalListType != null ? optionalListType : "ul"}
    <${listType}>
      {for item in list}     
        <li>${item}</li>
      {/for}
    </${listType}>
  {/macro}

  Using the macro...
  ${htmlList([ 1, 2, 3])}
  ${htmlList([ "Purple State", "Blue State", "Red State" ], "ol")}
  {var saved = htmlList([ 100, 200, 300 ])}
  ${saved} and ${saved}
Regarding macro scope: by default, macros are defined private to each template. If you want to export a macro so that it can be reused in other templates (such as building up a helper library of macros), one approach is to save a reference to your macro into your ''contextObject''. For example, in the ''contextObject'' that's the argument to ''template.process(contextObject)'', you can set ''contextObject'exported' = {};'' before you call process(). Then, here's how you can capture a macro into ''contextObject'exported'''...

  {macro userName(user)}
    {if user.aliasName != null && user.aliasName.length > 0}
      ${user.aliasName}
    {else}
      ${user.login}
    {/if}
  {/macro}
  ${exported.userName = userName |eat}
Cleverly, you might also set ''contextObject'exported' = contextObject;'' It's circular, but it works.

CDATA Text Sections
  {cdata}
    ...text emitted without JST processing...
  {/cdata}

  {cdata EOF}
    ...text emitted without JST processing...
  EOF
You can use the '''{cdata EOF}...EOF''' or '''{cdata}...{/cdata}''' markup syntax to tell JST to ignore processing for a block of text. The text will be emitted without any tag or markup processing. This can be useful if you're using a JavaScript Template to generate a JavaScript Template.

The 'EOF' may be any marker string without a '}' character. The marker string is used to delineate or 'bookend' a section of text.
The '...' is your text, which may contain newlines, which the JST engine will emit without any transformations.
For example...

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.
The above will output...

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.
In-line JavaScript
eval blocks
  {eval}
    ...javascript evaluated during JST processing...
  {/eval

  {eval EOF}
    ...javascript evaluated during JST processing...
  EOF
The EOF can be any text without a close-brace ('}') character.

The {eval} markup block can be useful to define multi-line JavaScript event handler functions near where they are used.

  <select οnchange="sel_onchange()"></select>
  {eval} 
    sel_onchange = function() {
     ...Do some complicated javascript...;
     ...more js code here...;
    }
  {/eval}
Note in the above example that the 'var' keyword is not used, like 'var sel_onchange = function() {...}'. This is to ensure that sel_onchange will be in global scope and hence usable as an event handler function.

minify blocks
  {minify}
    ...multi-line text which will be stripped of line-breaks during JST processing...
  {/minify 

  {minify EOF}
    ...multi-line text which will be stripped of line-breaks during JST processing...
  EOF
The EOF can be any text without a close-brace ('}') character.

A {minify} block allows you to inline long JavaScript or CSS code into your HTML attributes. For JavaScript, this is especially useful for event handlers like onchange, onmousedown, onfocus, onblur, etc. Without {minify}, handling linebreaks or newlines in long JavaScript code is possible but unwieldy.

  <select οnchange="{minify}
     ...Do some complicated multi-line javascript...;
     ...more js code here...;
     this.enabled = false;
  {/minify}">

  <select οnchange="{minify END_OF_JS}
     ...Do some complicated multi-line javascript...;
     ...more js code here...;
     this.enabled = false;
  END_OF_JS">
The {minify} block is also useful to make long inline CSS

<style>
attributes readable and maintainable, which can sometimes be useful in Internet Explorer which does not seem to support dynamically generated
<style>
tags.
<div id="commentPanel"
     style="{minify}
              display:none; 
              margin: 1em;
              border: 1px solid #333;
              background: #eee;
              padding: 1em;
            {/minify}">
  ...
</div>
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值