menu search

Hugo 获取文章特色图片

Aug 15, 2017

静态博客基本上都支持Front Matter,用来添加标题、日期、标签等等信息,但也可以用来储存别的数据。同样的功能也能在WordPress和Typecho上找到。(自定义字段)

从Hugo内置的Opengraph.html模板中可以看出,官方想让我们使用的字段是images,用来添加多张特色图片。不过由于历史原因,我还是习惯使用image来添加单张图片。

需要输出图片的地方可以这么写:

{{ with .Params.image }}
	<img src="{{ . }}" />
{{ end }}

但有些文章并没有找到合适的特色图片,或者是一些旧文章,懒得去添加了。

如果使用的是注重文字的主题,可能也不会太在意。但是像我这种有首页输出图片的,那些没图片的文章看起来会有点突兀。

后来就想到了使用正则来匹配文章中的图片,并输出第一张图片的地址。很普遍的套路,WordPress 和 Typecho 上也能找到类似的解决方案。

Hugo 有两个与正则式相关的函数:findREreplaceRE。从名字上就可以看出,前者是用来匹配,后者是替换。

findRE 的使用方法为:{{ findRE PATTERN INPUT [LIMIT] }}。最后一个参数是用来限制返回的匹配数量。

对正则并不熟悉,所以在网上找了一个可以在Go Lang上使用的:!\[(.*?)\]\((.*?)\)
(抱歉忘记保存出处,找到后会补上链接。)


首先,使用findRE来匹配文章中的图片:

{{ with findRE `!\[(.*?)\]\((.*?)\)` .RawContent }}
	{{ . }} //Array
{{ end }}

内部会返回一个数组,包含了文章中的所有图片。

接着使用range函数来遍历。由于我只需要第一张图片,所以使用了first 1来限制循环次数:

{{ with findRE `!\[(.*?)\]\((.*?)\)` .RawContent }}
	{{ range first 1 . }}
		{{ $url := replaceRE `!\[(.*?)\]\((.*?)\)` "$2" . }}
	{{ end }}
{{ end }}

获取到的值是完整的Markdown标签,但我需要的是图片地址,我使用了replaceRE来获取。
注:$1是完整的Markdown标签,$2是地址


最后,附上我用的完整代码。使用到了 Hugo 的 $.Scratch 功能来设定页面变量。(方便减少模板逻辑)

{{ with .Params.image }}
	{{ $.Scratch.Set "image" . }}
{{ else }}
	{{ with findRE `!\[(.*?)\]\((.*?)\)` .RawContent }}
		{{ range first 1 . }}
			{{ $url := replaceRE `!\[(.*?)\]\((.*?)\)` "$2" . }}
			{{$.Scratch.Set "image" $url }}
		{{ end }}
	{{ else }}
		{{ $.Scratch.Set "image" false }}
	{{ end }}
{{ end }}

上面的代码可以直接粘贴到循环头部。

首先查看是否存在image字段,如果没有就去获取第一张图片。在后者也不存在的情况下,就设定为false

用了$.Scratch后,获取缩略图的逻辑就很简单了:

{{ with ($.Scratch.Get "image") }}
	<img src="{{ . }}" />
{{ end }}

Photo by Chris Barbalis on Unsplash

-EOF-

Comments

edit x send markdown image
paragraph comment heart