google closure 笔记-SOY template

一 使用js模板

closure template 目前支持Javajs。可是模板语法的设计不依赖于任何现成的语言,因此理论上能够支持任何语言,只是暂时只有java编译器。javascript

使用js模板:编写模板文件 .soy文件,而后用一个java编写的编译器将其编译为js文件,这个编译好的js文件会提供一个函数来输出模板内容,html

只须要引入这个js文件而后在js中调用这个函数就能够获得模板的内容(内容是一个字符串)。java

1, 下载工具包git

 http://closure-templates.googlecode.com/files/closure-templates-for-javascript-latest.zipapi

解压以后会获得两个文件:app

SoyToJsSrcCompiler.jar, java编写的编译器,能够把soy模板编译为js文件dom

soyutils.js,编译器编译模板时须要使用的工具类。函数

2 模板语法工具

一个完整的模板hello.soy 源码以下ui

 

[javascript]  view plain  copy
 
  1. 1 {namespace demo.hello}  
  2. /** 
  3. 3   * Says hello to the world. 
  4. 4   */  
  5. 5 {template .helloWorld}  
  6. 6 Hello world!  
  7. 7 {/template}  



 

第一行是声明命名空间

第二行是注释,注意,这个注释必须得加,否则编译器会报错

第5行是模板名,是相对于demo.hello命名空间的,即为demo.hello.helloWorld

第6行是输出的内容

第7行是闭合标签

 

3 编译模板

SoyToJsSrcCompiler.jar能够将soy文件编译为js文件,编译器的使用以下

java -jar ../SoyToJsSrcCompiler.jar --outputPathFormat hello.js hello.soy

 

编译好的js文件会生成一个全局变量: demo.hello.helloWorld 函数,这个函数返回一个字符串 就是编译好的模板的内容。

使用此模板时只须要document.write(demo.hello.helloWorld())便可。

 

4 使用模板

新建一个hello.html,内容以下

 

[javascript]  view plain  copy
 
  1.  1 <html>  
  2.  2 <head>  
  3.  3     <title>The Hello World of Closure Templates</title>  
  4.  4     <script type="text/javascript" src="../soyutils.js"></script>  
  5.  5     <script type="text/javascript" src="hello.js"></script>  
  6.  6 </head>  
  7.  7 <body>  
  8.  8     <script type="text/javascript">  
  9.  9     // Exercise the .helloWorld template  
  10. 10     document.write(demo.hello.helloWorld());  
  11. 11     </script>  
  12. 12 </body>  
  13. 13 </html>  



 

 

其中:

第3,4行分别引入了工具类和编译好的模板文件,注意必定要先引入soyutils.js文件

第10行使用了模板hello.js提供的一个函数 demo.hello.helloWorld

 

5 添加另外一个模板

在上述的hello.soy文件后追加以下代码

 

[javascript]  view plain  copy
 
  1.  9 /** 
  2. 10  * Greets a person using "Hello" by default. 
  3. 11  * @param name The name of the person. 
  4. 12  * @param? greetingWord Optional greeting word to use instead of "Hello". 
  5. 13  */  
  6. 14 {template .helloName}  
  7. 15     {if not $greetingWord}  
  8. 16     Hello {$name}!  
  9. 17     {else}  
  10. 18     {$greetingWord} {$name}!  
  11. 19     {/if}  
  12. 20 {/template}  



 

这个新加的模板中使用了两个变量name和greetingWord。

编译此模板后生成的hello.js代码以下

 

[javascript]  view plain  copy
 
  1.  1 // This file was automatically generated from hello.soy.  
  2.  2 // Please don't edit this file by hand.  
  3.  3  
  4.  4 if (typeof demo == 'undefined') { var demo = {}; }  
  5.  5 if (typeof demo.hello == 'undefined') { demo.hello = {}; }  
  6.  6  
  7.  7  
  8.  8 demo.hello.helloWorld = function(opt_data, opt_sb) {  
  9.  9   var output = opt_sb || new soy.StringBuilder();  
  10. 10   output.append('Hello world!');  
  11. 11   return opt_sb ? '' : output.toString();  
  12. 12 };  
  13. 13  
  14. 14  
  15. 15 demo.hello.helloName = function(opt_data, opt_sb) {  
  16. 16   var output = opt_sb || new soy.StringBuilder();  
  17. 17   output.append((! opt_data.greetingWord) ? 'Hello ' + soy.$$escapeHtml(opt_data.name) + '!' : soy.$$escapeHtml(opt_data.greetingWord) + ' ' + soy.$$escapeHtml(opt_data.name) + '!');  
  18. 18   return opt_sb ? '' : output.toString();  
  19. 19 };  



 

能够看到其中生成了两个函数helloWorld和helloName

传递参数的方式很简单,只须要在调用的时候把参数以key-value的形式传入便可

 

[javascript]  view plain  copy
 
  1. 1 <html>  
  2.  2 <head>  
  3.  3     <title>The Hello World of Closure Templates</title>  
  4.  4     <script type="text/javascript" src="../soyutils.js"></script>  
  5.  5     <script type="text/javascript" src="hello.js"></script>  
  6.  6 </head>  
  7.  7 <body>  
  8.  8     <script type="text/javascript">  
  9.  9     // Exercise the .helloWorld template  
  10. 10     document.write(demo.hello.helloWorld());  
  11. 11     document.write("<br />" + demo.hello.helloName({name:"bob"}));     //传递参数  
  12. 12     document.write("<br />" + demo.hello.helloName({greetingWord:"wellcome:" ,name:"Lily"}));     //传递两个参数  
  13. 13     </script>  
  14. 14 </body>  
  15. 15 </html>  



 

 

二 使用java模板

编写模板的规则都是同样的,依然按上面描述的方法来编写一个soy文件,不一样之处是:

js模板须要用一个编译器编译为js文件,而java模板则直接在servlet中建立一个对象,这个对象能够将soy文件编译为字符串。

 

下载工具包:

http://closure-templates.googlecode.com/files/closure-templates-for-java-latest.zip

 

新建HelloWorld.java文件:

  

[java]  view plain  copy
 
  1. import com.google.template.soy.SoyFileSet;  
  2.   import com.google.template.soy.data.SoyListData;  
  3.   import com.google.template.soy.data.SoyMapData;  
  4.   import com.google.template.soy.tofu.SoyTofu;  
  5.   5  
  6.   import java.io.File;  
  7.   7  
  8.   public class HelloWorld {  
  9.   9  
  10.  10     public static void main (String[] args) {  
  11.  11  
  12.  12         // Bundle the Soy files for your project into a SoyFileSet.  
  13.  13         SoyFileSet sfs = new SoyFileSet.Builder().add(new File("demo/hello.soy")).build();  
  14.  14  
  15.  15         // Compile the template into a SoyTofu object.  
  16.  16         // SoyTofu's newRenderer method returns an object that can render any template in file set.  
  17.  17         SoyTofu tofu = sfs.compileToJavaObj();  
  18.  18  
  19.  19         // Call the template with no data.  
  20.  20         System.out.println(tofu.newRenderer("demo.hello.helloWorld").render());  
  21.  21         System.out.println(tofu.newRenderer("demo.hello.helloName")  
  22.  22                             .setData(new SoyMapData(  
  23.  23                                     "name", "Ana",  
  24.  24                                             "additionalNames")  
  25.  25                             ).render());  
  26.  26     }  
  27.  27 }  

 

 

而后编译运行代码:

javac -classpath soy-latest.jar HelloWorld.java

java -classpath soy-latest.jar HelloWorld

结果老是出错,不知道为何⋯⋯

 

三 模板语法

 

语句:

模板中语句分为两类,html语句和模板语句,全部的模板语句都包括在{}中。通常语法以下:

{command value}

若是省略command,则默认为print

 

变量:

变量以$符号开头: 

{$name}

引用类型的数据,其输出方式相似于js,

$a.0.c == $a[0].c == $a[0]["c"]

由于模板会自动删除多余空格,因此能够用{sp}或者{nil}来添加空格

在namespace声明中能够指定escape

{namespace ns autoescape="contextual"}

模板支持的变量类型以下

Type              

Literal

Null

null

Boolean              

false or true

Integer

Decimal (e.g. -827) or hexadecimal (must begin with 0x and must use capital A-F, e.g. 0x1A2B).

Float

Must be in decimal and must either:

  • Have digits both before and after the decimal point (both can be a single 0), e.g. 0.5, -100.0, or
  • Have a lower-case e that represents scientific notation, e.g. -3e-3, 6.02e23.

Note: Even though the primitive type is named Float, it has the precision of a number in JavaScript or a double in Java.

String

Delimited by single quotes only. Closure Templates support these escape sequences: \\, \', \", \n, \r, \t, \b, \f, and \u#### where the #### can be any 4 hex digits to denote a Unicode code point.

List

A comma-separated list of heterogeneous values, for example: [1, 'two', [3, 'four']]. [] is the empty list.

Map

['key': 'value', <keyExpr><valueExpr>] maps keys to values.

Square brackets ([…]) delimit both lists and maps because braces ({…}) delimit commands.
[:] is the empty map. 

运算符

  •   - (unary)   not
  •   *   /   %
  •   +   - (binary)
  •   <   ]]]]>   <=   >=
  •   ==   !=
  •   and
  •   or
  •   ?: (ternary)

函数:

模板提供的基本函数以下:

Function

Usage

isFirst($var)

Use this with the foreach command. For more information see the foreach section of the Commands chapter.

isLast($var)

Use this with the foreach command. See more information in the foreach section of the Commands chapter.

index($var)

Use this with the foreach command. See more information in the foreach section of the Commands chapter.

hasData()

Checks whether a template data object was passed to this template. This function is rarely needed — use it only if all parameters to a template are optional, and thus the template may be called without any data object at all (omitted or null in javascript or null in Java). In this situation, the correct way to check for the presence of a parameter is {if hasData() and $myParam}. Alternatively, if you choose to always pass an empty data map (i.e. never pass null) to your template even when none of the optional params are needed, then you never have to use the hasData() function.

length($list)

The length of a list.

keys($map)

The keys in a map as a list. There is no guarantee on order.

round(number)                    

Round to an integer.

round(number, numDigitsAfterDecimalPoint)                                                

If numDigitsAfterDecimalPoint is positive, round to that number of decimal places; if numDigitsAfterDecimalPoint is negative, round to an integer with that many 0s at the end.

floor(number)

The floor of the number.

ceiling(number)

The ceiling of the number.

min(number, number)

The min of the two numbers.

max(number, number)

The max of the two numbers.

randomInt(rangeArg)

A random integer in the range [0, rangeArg - 1] (where rangeArg must be a positive integer). 

注释:

  • // begins a rest-of-line comment
  • /* comment */ delimit an arbitrary comment (can be multiline)

 

详细语法:见:https://developers.google.com/closure/templates/docs/commands

相关文章
相关标签/搜索