检查变量是否为液体中的字符串或数组的类型

时间:2016-08-12 12:05:38

标签: html arrays yaml jekyll liquid

在Jekyll中,您可以使用liquid template,我正在尝试编写包含网站中所有链接的导航。

sitemap:
  home: "/"
  demo:
    right: "/right"
    left: "/left"

我想要实现的是创建一个包含所有这些链接的侧边栏。但某些链接属于一个部分。输出应该是以下

<nav>
  <ul>
    <li>
      <a href="/">home</a>
    </li>
  </ul>

  <ul>
    <li>demo</li>
    <li>
      <a href="/right">right</a>
    </li>
    <li>
      <a href="/left">left</a>
    </li
  </ul>
</nav>

并非所有部分都必须有标题。主链接是一个独立的链接。 演示链接都在演示部分。

在液体中,我可以通过这种方式遍历站点地图:

{% for nav in site.sitemap %}
<ul>
  <li>{{ nav[0] }}</li>
</ul>
{% endfor %}

通过这种方式,液体将打印homedemo

我需要检查是字符串还是数组才能打印数组或单个链接!

有没有办法检查液体变量是字符串还是数组? 我以前在链接的文档中找不到它!

3 个答案:

答案 0 :(得分:13)

  

有没有办法检查液体变量是字符串还是数组?


简答:是

要检查液体变量是字符串还是元素列表(数组或散列),请使用数组过滤器first{% var.first %}检查它是否具有第一个后代,如下所示:< / p>

{% if var.first %}
  // var is not a string
{% else %}
 // var is a string
{% endif %}


说明:

过滤器first返回数组的第一个元素或散列(如果有),如果变量为空或者没有元素列表则返回任何内容,并且nil是{ {3}}在液体中,它与上面false中的if condition的工作方式相同。

例如:

# var1 = "a"     // string
{% var1.first %} // return:   // nil -> falsy

# var2 = [a,b,c] // array
{% var2.first %} // return: a

# var3 = {k1: a, k2: b, k3: c} // hash
{% var1.first %} // return: k1a

# var4 = {k1, k2, k3: c} // hash, first element is a key without associated value
{% var1.first %} // return: k1


OP问题的解决方案:遍历站点地图

现在我们可以确定元素是否是字符串,我们可以这样做:

{% for nav in site.sitemap %}
<ul>
  <li>
     {{ nav[0] }} :
        {% if nav[1].first %}
        // loop through: nav[1]
        {% else %}
          {{ nav[1] }}
        {% endif %}        
  </li>
</ul>
{% endfor %}

但是我发现将sitemap作为元素列表(a)更方便*,而不是单个大哈希(实际上是)(b) (参见falsy value

1。编辑站点地图数据结构

所以我通过在每个元素之前添加"- "(短划线和空格)来修改它的结构:

  - home: "/"
  - demo:
    - right: "/right"
    - left: "/left"  

给我们 a

{"home"=>"/"}{"demo"=>[{"right"=>"/right"}, {"left"=>"/left"}]} 

而不是 b

{"home"=>"/", "demo"=>{"right"=>"/right", "left"=>"/left"}} 

旁注:您可以将站点地图放在其自己的文件中:_data/sitmap.yml并通过site.data.sitemap访问它,而不是将其定义为{中的属性{1}},为了保持清洁,因此它看起来与上面完全一样。

2。创建站点地图模板

因为我们将递归地包含_config.yml(对于每个有子节点的节点),我们会将此模板放在sitemap文件夹而不是_includes

另请注意,Jekyll允许YAML syntax。但有一个问题,_layouts应该是param而不是数组或哈希。所以,我们必须从links数组中创建一个字符串。

我们走了:

string

3。使用模板:)

<ul>
  <!--                  links is a param -->
  {%for link in include.links %}

    <li>

      {% for part in link %}
        {{part[0]}} : <!-- part[0] : link name  -->

        {% if part[1].first %} <!-- the element has children -->

          <!-- concatenate jekyll array into a string -->
          {% assign _links = "" | split: "" %}
          {% for _link in part[1] %}
            {% assign _links = _links | push: _link %}
          {% endfor %}
          <!-- pass the string as a param to sitemap, then do the recursive dance -->
          {% include sitemap.html links = _links %}

        {% else %} <!-- no children -->

          {{part[1]}} <!-- part[1] : link url -->

        {% endif %}

      {% endfor%}

    </li>

  {%endfor%}

</ul>

4。输出

for:<!-- include and init the param with this ↓, or `site.sitemap` if it's defined in `_config.yml`, or ... --> {% include sitemap.html links= site.data.sitemap %}

/_data/sitemap.yml

模板生成:

  • 主页:/
  • about:/ about
  • 存档:
    • left:/ left
    • 右:/右
    • 其他:
      • up:/ other / up
      • down:/ other / down

所以你必须将每个链接的- home : "/" - about: "/about" - archive: - left : "/left" - right: "/right" - other: - up: '/other/up' - down: '/other/down' part[0]放在part[1]中,如:

<a> tag

答案 1 :(得分:1)

您可以按如下方式修改结构:

sitemap:
    home:
        link: "/"
    demo:
        children:
            right:
                link: "/right"
            left:
                link: "/left"

现在所有对象都遵循相同的模式:您可以只测试对象是否存在,而不是测试类型。您还可以使用recursion by inclusion来解析站点地图:

{% for nav in site.sitemap %}
<ul>
    {% include 'print-li' %}
</ul>
{% endfor %}

使用'print-li':

<li>
{% if nav.link %}
    <a href="{{ nav.link }}">{{ nav[0] }}</a>
{% else %}
    {{ nav[0] }}
{% endif %}

{% if nav.children %}
    {% for nav in nav.children %}
        {% include 'print-li' %}
    {% endfor %}
{% endif %}
</li>

答案 2 :(得分:1)

我正在使用Jekyll 2.8.5和

var[0]

对于字符串值是虚假的,但对于数组是真实的(其第一个元素是真实的)。

(另一方面,var.first,如先前接受的答案所建议,现在返回字符串的第一个字符,因此,似乎不是确定值是否为字符串的好方法。数组。)