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

2024-03-13

在 Jekyll 中你可以使用液体模板 https://shopify.github.io/liquid/我正在尝试编写一个包含网站中所有链接的导航。

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 %}

这样液体就会打印出来home and demo.

我需要的是检查是否value是字符串或数组,以便打印数组或单个链接!

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


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

简短回答:是的

要检查 Liquid 变量是否是字符串或元素列表(数组或散列),请使用数组过滤器检查它是否有第一个后代first https://help.shopify.com/themes/liquid/filters/array-filters#first: {% var.first %}如下 :

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

解释:

过滤器first返回数组或散列的第一个元素(如果有),如果变量为空或不是元素列表,则不返回任何内容,并且因为nil is a falsy value https://help.shopify.com/themes/liquid/basics/true-and-false#falsy在液体中,其作用与false in the if condition above.

e.g :

# 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) (cf. YAML 语法 http://docs.ansible.com/ansible/YAMLSyntax.html)

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,而不是将其定义为属性_config.yml,保持干净,这样它看起来就和上面一模一样了。

2. 创建站点地图模板

因为我们将包括sitemap本身递归(对于每个带有孩子的节点)我们将把这个模板放入_includes文件夹而不是_layouts

另请注意 Jekyll 允许将参数传递给包含 https://jekyllrb.com/docs/includes/#passing-parameters-to-includes。但有一个问题,param应该是一个string不是数组或哈希。因此,我们必须从 links 数组中创建一个字符串。

开始了:

<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>

3. 使用模板:)

<!-- 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 %}

4. 输出

for: /_data/sitemap.yml:

- home : "/"
- about: "/about"
- archive:
  - left : "/left"
  - right: "/right"
  - other:
    - up: '/other/up'
    - down: '/other/down'

模板产生:

  • home : /
  • 关于:/关于
  • archive :
    • 左:/左
    • 是的是的
    • other :
      • 上:/其他/上
      • 向下:/其他/向下

所以你必须把part[0] and part[1]中每个链接的<a> tag like:

<a href="{{part[1]}}"> {{part[0]}} </a>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检查变量是否是液体中的字符串或数组类型 的相关文章