Skip to content
shepherdwind edited this page Jan 27, 2013 · 1 revision

Jsonify是velocityjs中最重要的一个Helper,主要用于解决数据同步问题。

Jsonify的基本思想是,根据给定vm编译成一个只包含数据的vm,编译后的vm通过解析可以获得一个json字符串

调用接口重要有两个,一个是命令行方式,和lessc命令类似,另外node模块的方式,和调用velocity解释器的api相似。Jsonify在0.3.3才开始稳定。执行命令之前,确保是安装到了最新版本的velocityjs,对比

  • velocity -v
  • npm info velocity version

###命令行方式调用

$ velocity -j xx.vm
$ velocity -j xx.vm > data.vm

###node模块调用

作为node模块,调用方式为

var Velocity = require('velocityjs');
var Jsonify = Velocity.Jsonify;
var asts = Parser.parse(fs.readFileSync(file).toString());

var makeup = new Jsonify(asts);
console.log(makeup.toVTL())

###编译规则

Jsonify执行过程中,把vm变量分为两者基本类型:

  1. 数据 $foo.bar => {foo: {bar: “$foo.bar”}}
  2. 函数 $foo.bar() => {foo: {bar: “function(){}”}}

主要处理数据,对于函数的处理是返回一段站位字符串function(){},因为函数无法描述在json中。数据主要分为三种不同的结构:

  1. 字符串/数字/布尔等简单数据,这种情况处理起来最简单
  2. 数组数据,来源于#foreach #foreach($a in $foo)
  3. map集合,来源于#foreach #foeach($a in $foo.keySet())
  4. 数据对象,同样来自于#foreach,和2类似,只是数组的元素是对象,而不是基本数据类型

遇到macro调用时,会找到macro形参对应的真实变量,并且支持递归。

例子:example.vm

  #macro(a $a $b)
    $a $b
  #end

  #macro(b $aa $bb)
    #a($aa, $bb)
  #end

  #b($aaa $bbb())

通过命令执行

$ velocity -j example.vm
{
  "aaa": "$aaa",
  "bbb": "function(){}"
}

###内部api使用/宏重写

Jsonify构造器接受三个参数

  1. asts velocity语法树对象,通过Parser.parse(vmText)获得
  2. context
  3. macros

第二个参数和第三个参数是可选的,用于定义vm中的一些宏或者方法,下面看一个例子:

文件a.vm

$ctrl.load("b.vm")
#parse("c.vm")

b.vm

$hello.b

c.vm

$hello.b

a.js

var velocity = require('velocityjs');
var fs = require('fs');
var str     = fs.readFileSync(__dirname + '/a.vm').toString();
var Jsonify = velocity.Jsonify;
var Parser  = velocity.Parser;

function loadVFile(txt){
  var file = __dirname + '/'+ txt;
  if (fs.existsSync(file)) {
    this.eval(fs.readFileSync(file).toString());
  }
}

var markup = new Jsonify(Parser.parse(str), {ctrl: {load: loadVFile}}, {parse: loadVFile});
console.log(markup.toVTL());

执行a.js

$ node a.js
{
  "hello": {
    "b": "$hello.b",
    "c": "$hello.c"
  }
}

上面a.vm中,第一个函数$ctrl.load调用的是Jsonify构造器第二个参数context中的方法,第二个宏#parse(“c.vm”),处理来自Jsonify构造器第三个参数。也就是说,Jsonify中提供一套api,可以通过这些api来在执行过程中执行自定义的函数,比如加载另外一个vm,进行解析。需要注意的是,在loadVFile函数定义中,必须使用this.eval这个api来解析获得的字符串。

Clone this wiki locally