在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 %}
通过这种方式,液体将打印home
和demo
。
我需要检查值是字符串还是数组才能打印数组或单个链接!
有没有办法检查液体变量是字符串还是数组? 我以前在链接的文档中找不到它!
答案 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
现在我们可以确定元素是否是字符串,我们可以这样做:
{% 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
)
所以我通过在每个元素之前添加"- "
(短划线和空格)来修改它的结构:
- 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}},为了保持清洁,因此它看起来与上面完全一样。
因为我们将递归地包含_config.yml
(对于每个有子节点的节点),我们会将此模板放在sitemap
文件夹而不是_includes
另请注意,Jekyll允许YAML syntax。但有一个问题,_layouts
应该是param
而不是数组或哈希。所以,我们必须从links数组中创建一个字符串。
我们走了:
string
<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>
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
模板生成:
所以你必须将每个链接的- 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
,如先前接受的答案所建议,现在返回字符串的第一个字符,因此,似乎不是确定值是否为字符串的好方法。数组。)