有没有办法检查液体变量是字符串还是数组?
简短回答:是的
要检查 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 :
所以你必须把part[0]
and part[1]
中每个链接的<a> tag
like:
<a href="{{part[1]}}"> {{part[0]}} </a>