Cover image

Liquid for Designers[转]

Oct 5, 2015

这两天在用jekyll搭博客,一看是liquid语言立刻傻眼了!

话说Liquid是个什么鬼?

不过好在Github上有文档, 但是可惜是英语的.虽说作为一个Code Monkey来说,英语应该作为第二母语来使用,但我还是尽我所能的去寻找第一母语吧.

功夫不负有心人,让我找到了 @Havee的这篇Jekyll扩展的Liquid设计,虽然这篇也是转自http://yanshasha.com/2013/01/22/Liquid-for-designers/,不过可惜原文已挂,为了防止这么好的母语翻译文档继续挂掉,so,我还是转过来吧,以备不时之需.

原文:Jekyll扩展的Liquid设计

在Liquid中有两种类型的标记:OutputTag.

{{ 两个配对的花括号中 }}
{% 成对的花括号和百分号中 %}

Output


下面是关于输出标记的简单实例:

Hello {{ name }}
Hello {{ user.name }}
Hello {{ 'tobi' }}

高级输入:过滤器

输入标记带有过滤器,方法很简单.第一个参数总是过滤器左边值的输出.当下个过滤器运行时,刚刚所得到的过滤器的返回值就会成为新的左边值.知道最后没有过滤器时,模板就会接受最后的结果字符串.

Hello {{ 'tobi' | upcase }}
Hello tobi has {{ 'tobi' | size }} letters
Hello {{ 'tobi' | capitalize }}
Hello {{ '1982-02-01' | date:"%Y" }}

输出的结果是:

Hello TOBI
Hello tobi has 4 letters
Hello Tobi
Hello 1982

标准过滤器

Tags


tags用于你的模板中的逻辑,新的标签很容易开发,因此我希望在发布这些代码以后,大家可以为标准标签库增加更多的内容。 下列是当前已经支持的标签:

注释

任何被包含在{% comment %}以及{% endcomment %}之间的语句被解析为注释,也就是说这些语句不会被显示出来

We made 1 million dollars {% comment %} in losses {% endcomment %} this year

输出的结果是:

We made 1 million dollars  this year

Raw

raw会暂时性的禁用对标签的解析功能。这在需要展示一些可能产生冲突的内容(如下代码中,要展示liquid语句,就需要包含在raw标签之间,否则就会被解析)时非常有用。

{% raw %}

    In Handlebars,{{ this  }} will be HTML-eacaped, but {{{ that }}} will not.

{% endraw %}

if/else

if/else在其他编程语言里应该已经被熟知了。Liquid使得你可以通过ifunless(elsifelse为可选)编写简单的表达式:

{% if user %}
  Hello {{ user.name }}
{% endif %}

# Same as above
{% if user != null %}
  Hello {{ user.name }}
{% endif %}

{% if user.name == 'tobi' %}
  Hello tobi
{% elsif user.name == 'bob' %}
  Hello bob
{% endif %}

{% if user.name == 'tobi' or user.name == 'bob' %}
  Hello tobi or bob
{% endif %}

{% if user.name == 'bob' and user.age > 45 %}
  Hello old bob
{% endif %}

{% if user.name != 'tobi' %}
  Hello non-tobi
{% endif %}

# Same as above
{% unless user.name == 'tobi' %}
  Hello non-tobi
{% endunless %}

# Check for the size of an array
{% if user.payments == empty %}
   you never paid !
{% endif %}

{% if user.payments.size > 0  %}
   you paid !
{% endif %}

{% if user.age > 18 %}
   Login here
{% else %}
   Sorry, you are too young
{% endif %}

# array = 1,2,3
{% if array contains 2 %}
   array includes 2
{% endif %}

# string = 'hello world'
{% if string contains 'hello' %}
   string includes 'hello'
{% endif %}

Case语句

如果你需要更多的条件判断,你可以使用 case 语句:

{% case condition %}
    {% when 1 %}
        hit 1
    {% when 2 or 3 %}
        hit 2 or 3
    {% else %}
        ... else ...
{% endcase %}

Example:

{% case template %}
    {% when 'label' %}
        // {{ label.title }}
    {% when 'product' %}
        // {{ product.vendor | link_to_vendor }} / {{ product.title }}
    {% else %}
        // {{page_title}}
{% endcase %}

Cycle

我们常常需要在不同的颜色或类似的任务间轮流切换。Liquid 对于这样的操作有内置支持,通过使用 cycle 标签。

{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}

输出结果是

one
two
three
one

如果一组 cycle 没有命名,那默认情况下有用相同参数的会被认为是一个组。 如果你希望完全控制 cycle 组,你可以指定一个组名,这个组名甚至可以是一个变量。

{% cycle 'group 1': 'one', 'two', 'three' %}
{% cycle 'group 1': 'one', 'two', 'three' %}
{% cycle 'group 2': 'one', 'two', 'three' %}
{% cycle 'group 2': 'one', 'two', 'three' %}

输出结果是:

one
two
one
two

循环

Liquid 允许循环一个集合 :

{% for item in array %}
    {{ item }}
{% endfor %}

而当迭代循环一个哈希表时,item[0]存放的是key,item[1]存放的是value:

{% for item in hash %}
  {{ item[0] }}: {{ item[1] }}
{% endfor %}

在每次循环期间,下列的帮助变量都可用于额外的展示需要:

forloop.length      # => length of the entire for loop
forloop.index       # => index of the current iteration
forloop.index0      # => index of the current iteration (zero based)
forloop.rindex      # => how many items are still left?
forloop.rindex0     # => how many items are still left? (zero based)
forloop.first       # => is this the first iteration?
forloop.last        # => is this the last iteration?

你可以使用一些属性来影响接受循环中的哪项。 limit:int 使你可以限制接受的循环项个数;offset:int 可以可以让你从循环集合的第 n 项开始.

# array = [1,2,3,4,5,6]
{% for item in array limit:2 offset:2 %}
    {{ item }}
{% endfor %}
# results in 3,4

反转循环

{% for item in collection reversed %}
    {{item}}
{% endfor %}

除了对一个已经存在的集合进行循环,你还可以定义一段范围区域内的数字进行循环。这段区域既可以通过文字也可以通过变量数定义得到:

# if item.quantity is 4...
{% for i in (1..item.quantity) %}
    {{ i }}
{% endfor %}
# results in 1,2,3,4

一个for循环可以通过else语句来处理当集合中不存在元素的情况:

# items => []
{% for item in items %}
   {{ item.title }}
{% else %}
   There are no items!
{% endfor %}

变量赋值

你可以把数据存储在你自己定义的变量中,以便在输出或者其他标签中使用。创建一个变量的最简单方式是使用 assign 标签,其语法也是简单明了的:

{% assign name = 'freestyle' %}

{% for t in collections.tags %}
    {% if t == name %}
        <p>Freestyle!</p>
    {% endif %}
{% endfor %}

另一种常见用法是把 true/false 值赋给变量:

{% assign freestyle = false %}

{% for t in collections.tags %}
    {% if t == 'freestyle' %}
        {% assign freestyle = true %}
    {% endif %}
{% endfor %}

{% if freestyle %}
    <p>Freestyle!</p>
{% endif %}

如果你希望把一系列字符串连接为一个字符串,并将其存储到变量中,你可以使用 capture 标签。这个标签是一个块级标签,它会 captures 任何在其中渲染的元素,并把捕获的值赋给给定的变量,而不是把这些值渲染在页面中。

{% capture attribute_name %}{{ item.title | handleize }}-{{ i }}-color{% endcapture %}

<label for="{{ attribute_name }}">Color:</label>
<select name="attributes[{{ attribute_name }}]" id="{{ attribute_name }}">
  <option value="red">Red</option>
  <option value="green">Green</option>
  <option value="blue">Blue</option>
</select>

05 Oct 2015

Post by: MetaCoder