How to display data from Jekyll data file based on current page variable

时间:2019-04-16 22:21:50

标签: for-loop yaml jekyll liquid

The Problem

I have a div on my Jekyll site where I would like to display data that is generated from _data/book-data.yml, for example:

- name: johnson-everything-under
  title: Everything Under
  author: Daisy Johnson
  publisher: Faber & Faber
  pub-date: 12/12/2012

- name: johnson-train-dreams
  title: Train Dreams
  author: Denis Johsnon
  publisher: Granta
  pub-date: 01/01/2001

I'm trying to find a way to display the data that corresponds to the relevant page (each book entry has a different page), and I thought maybe this would be possible if the name key corresponds to the page.url, or some other page variable.

What I've tried

On a working page, I have an include which contains the following HTML:

<div class="book-meta">
  {% if page.category == "reviews"%}
  <div class="book-thumbnail">
    <img class="post-thumbnail-lg" src="{{ site.baseurl }}/assets/images/{{ page.thumbnail }}" alt="{{ page.thumbnail }}">
  </div>
  {% for book in site.data.book-data %}
  <div class="book-details">
    <ul class="book-meta-list">
      <li class="book-meta-item"><p><a href="#">{{ book.author }}</a></p></li>
      <li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
      <li class="book-meta-item"><p>{{ book.publisher }}</p></li>
      <li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
    </ul>
  </div>
  {% endfor %}
  {% endif %}
</div>

The CSS is not important, but as it is currently the output of the above HTML is:

Screenshot

Desired output

As you can see, the output contains both the blocks of metadata from the .yml file. I would like to find a way so that only the relevant block of data (the first block in this instance) is displayed:

Screenshot2

Potential solution(s)

I thought that there might be a way of matching a page.variable to the YAML block name so only the right book data gets output. Something along the lines of:

{% assign url_substring = page.url | split, '/' | last %}
// url_substring = johnson-everything-under
{% for book in site.data.book-data %}
{% if url_substring == book.name %}
// = true
<p>{{ book.title }}<p>
{% endif %}
{% endfor %}

Other than the fact that I can't get this to work properly, I can also see that the liquid tag {{ book.title }} has no way of knowing which book title to output, even if the page.url matches.

I'm not sure if I'm on the right track here, so if anyone has any other suggestions on how this might be achievable, I'd love to hear it. Thanks in advance.

1 个答案:

答案 0 :(得分:2)

您可以将Jekyll的where过滤器与智能包含功能结合使用:

{% assign book = site.data.book-data | where: 'title', include.title | first %}

<div class="book-meta">
  <div class="book-thumbnail">
    <img
      class="post-thumbnail-lg"
      src="{{ book.thumbnail | prepend: 'assets/images/' | relative_url }}"
      alt="{{ book.title }}"
    />
  </div>

  <div class="book-details">
    <ul class="book-meta-list">
      <li class="book-meta-item"><p><a href="#">{{ book.author }}</a></p></li>
      <li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
      <li class="book-meta-item"><p>{{ book.publisher }}</p></li>
      <li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
    </ul>
  </div>
</div>

请注意,我还在数据文件中添加了thumbnail信息。

然后只需将title参数传递给include(在您书页的布局中):

{% include books.html title = 'Everything Under' %}

如果您想呈现“列表”,则只需遍历并呈现:

{% for book in site.data.book-data %}
  {% include books.html title = book.title %}
{% endfor %}