在Jekyll中,如何获取文章的第一张图片?

27
在我的博客文章索引中,我想使用Liquid仅获取文章中的第一张图片并显示在索引中,以便它适用于GitHub Pages。我觉得使用split可能是解决方法,但我对Liquid不熟悉。我希望能够获取图片的URL并将其放入变量中以进行样式设置。理想的解决方案应该是这样的:
{% for post in site.posts %}
    <li>
      <a href="{{ post.url }}">{{post.content | first_image}}</a>
    </li>
  {% endfor %}

有什么想法吗?

5个回答

28
你可以在你的Front Matter中定义一个自定义变量,叫做 "image",这样它就会像WordPress的文章特色图像一样工作。
---
image: featured-image.jpg
---

记得要想清楚你的图片保存在哪里。在我的例子中,我创建了一个名为"imagens"(PT-BR)的文件夹。然后,进入你的index.html文件,将图片添加到模板中的任何位置。在我的网站上,它看起来像这样:

<ul class="post-list">
    {% for post in site.posts %}
      <li>
        <h2>
          <a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
        </h2>
        <span class="post-meta">{{ post.date | date: "%b %-d, %Y" }},</span>
        <span class="post-meta">por</span>
        <span class="post-meta">{{ post.author }}</span>
      </li>

      //IMAGE
      <img src="{{ site.baseurl }}/imagens/{{ post.image }}">
      //IMAGE


      {{ post.excerpt }}
      <a class="btn btn-default" href="{{ post.url | prepend: site.baseurl }}">Continuar lendo</a>
    {% endfor %}
  </ul>

就是这样。


此选项增加了最多的控制(对于那些包含大量图像和各种宽高比的内容非常有帮助)。 - cameron
我认为这是一个更简洁的解决方案。 - Cris Pinto
一个更直接的解决方案,支持这个。 - TheTechGuy

19

以下是解决您问题的一些方法:

1 - 使用文章摘要标签 此处有文档

您的文章:

---
layout: post
title: Testing images
---
## Title
Intro Text
![Image alt]({{ site.baseurl }}/assets/img/image.jpg "image title")
More intro text

Some more text blah !

您的模板:

<ul>
  {% for post in site.posts %}
    <li>
      <a href="{{ post.url }}">{{ post.title }}</a>
      {{ post.excerpt }}
    </li>
  {% endfor %}
</ul>

由于您的图像标记出现在excerpt_separator (\n\n = 两个换行符)之前,因此它将出现在文章摘录中。

2 - 使用您的文章 Yaml 前置数据来存储您的图像数据

文章:

---
layout: post
title: Testing images

images:

  - url: /assets/img/cypripedium-calceolum.jpg
    alt: Cypripedium Calceolum
    title: Cypripedium Calceolum

  - url: /assets/img/hello-bumblebee.jpg
    alt: Hello bumblebee !
    title: Hello bumblebee !
---

Intro here yo ! <-- THIS IS THE EXCERPT

Post body begin, and first image not in excerpt
{% assign image = page.images[0] %} <-- first element of the array is zero
{% include image.html image=image %}

Some more text blah !
{% assign image = page.images[1] %}
{% include image.html image=image %}

_includes/image.html(集中在包含文件中以进行标准化,但可以放在模板中):

<img src="{{ site.baseurl }}{{ include.image.url }}" alt="{{ include.image.alt }}" title="{{ include.image.title }}">

主页:

<ul class="posts">
  {% for post in site.posts %}
    <li>
      <span class="post-date">{{ post.date | date: "%b %-d, %Y" }}</span>
      <a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
      {{ post.excerpt }}
      {% assign image = post.images[0] %}
      {% include image.html image=image %}
    </li>
  {% endfor %}
</ul>

感谢您提供全面的答案。我应该提到我知道摘录,正如您所指出的,如果图像在摘录中,则可以使用它。您的第二个建议回答了我的问题,但我希望有一些可以放在模板中提取第一个图像的东西。 - David Silva Smith

17

解决了。不确定它的可伸缩性如何,但这个liquid代码会循环遍历所有文章,并从文章中获取第一个图像的源代码并显示该文章。我测试了多张图片,效果符合预期。

<ul>
  {% for post in site.posts %}
    <li>

      {% assign foundImage = 0 %}
      {% assign images = post.content | split:"<img " %}
      {% for image in images %}
        {% if image contains 'src' %}

            {% if foundImage == 0 %}
                {% assign html = image | split:"/>" | first %}
                <img {{ html }} />
                {% assign foundImage = 1 %}
            {% endif %}
        {% endif %}
      {% endfor %}

      <a href="{{ post.url }}">{{ post.title }}</a>
    </li>
  {% endfor %}
</ul>

5
很好,谢谢。我在我的网站上使用它,但将 foundImage 逻辑替换为循环中的 {% break %}。这样可节省对于包含许多图像的帖子而言的一些迭代次数。 - jarvisteve
谢谢你的提示!我不知道 break - David Silva Smith
这种方法对我也起作用,只是我更喜欢仅获取图像的src属性而不是所有属性。我该如何做到这一点,而不仅仅是使用<img {{html}} /> - user1475412
1
最终我没有使用这段代码,而是在frontmatter中使用了image: xxx.jpg。但如果你使用上面的代码,基本上你需要再次分割以查找src=",然后通过管道将文本抓取到另一个",就像{% assign html = image | split:"/>" | first %}这种情况一样。 - David Silva Smith
非常好的提示,这正是所需之物。 - Hesham Eraqi

4
如果你只需要图片的URL而不是整个标签,你可以使用以下方法。
安装 Liquid 过滤器 match_regex:
gem install match_regex

然后将其添加到Jekyll配置中:
plugins:
  - match_regex

在您的模板中创建一个捕获代码片段:
{% capture post_first_image %}
  {% assign hero_image = page.content | match_regex: '<img .*?src="([^"]+)"' %}
  {% if hero_image == nil %}
    {% assign hero_image = "/placeholder-image.png" | prepend: site_base %}
  {% endif %}
  {{ hero_image }}
{% endcapture %}

模板:

<meta property="og:image" content="{{ post_first_image | strip }}">

如果您不需要占位符图像,您可以简单地删除if条件。

不错。它在我的Ubuntu上运行良好,但在GitHub上却不行。不确定为什么。 - ihsanberahim
1
@ihsanberahim GitHub Pages支持的插件已经被列入白名单:https://docs.github.com/en/github/working-with-github-pages/about-github-pages-and-jekyll#plugins - sparanoid

2
我参考了David的回答,并找到了一种方法来仅获取标签中的src属性。
    {% assign foundImage = 0 %}
    {% assign images = post.content | split:"<img " %}
    {% for image in images %}
      {% if image contains 'src' %}

          {% if foundImage == 0 %}
              {% assign html = image | split:"/>" | first %}
              {% assign tags = html | split:" " %}
              {% for tag in tags %}
                {% if tag contains 'src' %}
                  <img {{ tag }} />
                {% endif %}
              {% endfor %}
              {% assign foundImage = 1 %}
          {% endif %}
      {% endif %}
    {% endfor %}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接