Liquid模板引擎


介绍
Liquid/ˈlɪkwɪd/ 液体,液体的,明亮的,清澈的,晶莹的,清脆的,易变现金的。 液体liquid这个名字象征着无形。
这个gem是由shopify公司贡献的开源gem包,shopify这家公司是一家电商服务公司,Shopify淘宝、亚马逊、eBay最大的不同点就在于,它并不一个直接面对消费者的平台,而是一个专为卖家提供服务的平台。是一种SaaS服务,和淘宝相似而又不同,你的taobao上的买家,这个客户是taobao的,但是shopify里的开的店,里面的买家是你的客户。Shopify暂不多表,有兴趣的可以去了解下,它将开独立电商网店的成本降到了每个月几十美金。

Liquid是一个模板引擎,一般的情况下我们写一个网页会先写死网页的布局,然后里面的内容是动态的内容。可以把这个布局看成是模板,那liquid将布局也变成了动态的了。
  • 它有简洁的标记markup. 模板引擎如果没有好看的标记那就用起来没意思。
  • 模板需要安全,用户可以编辑模板,但是用户如果在模板里面写代码那是不能被服务器运行的,否则就没啥安全可言了。
  • 模板必须是无状态的stateless, 模板编译和模板的呈现要分开,解析模板和编译模板是比较消耗资源的,模板的呈现只需要传一个hash、局部变量和对象就能完成。
关于stateless无状态,可以和stateful有状态来做对比解释。无状态的意思是你上次传给我的数据,我不保留,下次给我什么就展示什么,不受上次的影响。

为什么你要用Liquid?
  • 你想让你的用户去编辑应用前端的页面的呈现的样子,但又不想他们在服务器上运行不安全的代码。
  • 你想直接从数据库里面取模板用来渲染。
  • 你喜欢简单的样式模板引擎。
  • 你需要一个像写email一样来写HTML的模板引擎。
  • 你不喜欢你当前用的模板引擎的markup标记。

Liquid长什么样?
<ul id="products">
  {% for product in products %}
    <li>
      <h2>{{ product.name }}</h2>
      Only {{ product.price | price }}

      {{ product.description | prettyprint | paragraph }}
    </li>
  {% endfor %}
</ul>

如何使用Liquid
先安装liquid,将 gem 'liquid' 添加到你的gemfile里面
Liquid支持一个简的基于API的类:Liquid::Template.
标准用法你可以只传一文件的内容,然后带一个hash参数调用。
@template = Liquid::Template.parse("hi {{name}}")  # Parse and compiles the template
@template.render('name' => 'tobi) # => "hi tobi"

Error Modes错误模型
设置liquid的错误模式,让你specify指定你的模板解释to be interpreted的的严格程度。通常情况下,解释器the parser是非常lax松的,而且可以接收几乎所有任何内容而不报错。不幸的是这会让你调试起来非常困难,而且导致unexpected的行为。
liquid也可以配置一个更加严格parser,可用在编辑的模板invalid时候,给出更好的错误信息,你可以启用enable这个新的parser,like this:

Liquid::Template.error_mode = :strict # Raises a SyntaxError when invalid syntax is used
Liquid::Template.error_mode = :warn # Adds strict errors to template.errors but continues as normal
Liquid::Template.error_mode = :lax  # The default mode, accepts almost anything.

If 你想仅针对specific指定的templates 去设置错误mode,你可以通过传error_model参数给 parse, 如:
Liquid::Template.parse(source, error_model: :strict)
这个strict模式只对当前的theme编辑器有用。

这里建议你在新建的app里使用strict或者warn模式,避免出现不可用的templates。也建议你用在现存的apps里面使用,便于获得更好的error messages.

未定义的变量和过滤器 variables and filters
默认情况下,如果变量或者过滤器没有定义,渲染器renderer 不会抛出异常,也不会有其它的提示, i.e. 没有传给 render方法。 你可以改进这个情况,通过passing strict_variables: true 或者 stirct_filters: true 选项给render方法。当其中一个选项option被set为true。所有未定义的variables和没有被定义的filters将被存在一个Liquid::Template的实例的 errors数组里面。 Here are some examples:

template = Liquid::Template.parse("{{x}} {{y}} {{z.a}} {{z.b}}")
template.render ({'x' => 1, 'z' => {'a' => 2} }, {strict_variables: true })  # '1 2 ' # when a variable is undefined, it's rendered as nil
template.errors
#=> [#<Liquid::UndefinedVariable: Liquid error: undefined variable y>, #<Liquid::UndefinedFilter: Liquid error: undefine variable b>]

template = Liquid::Template.parse("{{x | filter1 | upcase}}")
template.render({'x' => 'foo'}, { strict_filters: true })
#=> ' ' # when at least one filter in the filter chain is undefined, a whole expression is rendered as nil
template.errors
#=> Liquid::UndefinedVariable: Liquid error: undefined fileter fileter1

如果你想第一时间抛出异常而不是将这些pushing all of them in errors, 你可以用render! 方法:

template = Liquid::Template.parse("{{x}} {{y}}") 
template.render!({'x' => 1}, { strict_variables: true})
#=> Liquid::UndefineVariable: Liquid error: undefined variable y

使用Usage tracking
去帮助跟踪使用一个feature或者code path in production, we have released opt-in usage tracking. 启用这个 我们提供了一个空方法 Liquid:: Usage.increment 你能够自定义你的需求。 这个功能feature 很好的suited通https://github.com/Shopify/statsdinstrument. 无论如何这个实现的选择is up to you.取决于你。
一旦你开启了跟踪 usage tracking, 我们建议 你通过这个Github Issues 报告任何你的系统记录的日志events。It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. 报告这些问题事件很大可能性会用来deprecating 弃用一些代码或者 improving代码。因此请上报任何的concerns问题

更加详细的介绍
阅读量: 1017
发布于:
修改于: