事情的缘由是我无意中发现之前写的部分文章里的图片没有渲染出来,才想起之前博客系统改版,从 Pelican 切换到 Snow 时竟然忘记了,看了一下原文,大部分都是以下形式
<div class="row"> <div class="col-md-4"> [[https://s.libforest.com/images/pic/西湖/日落(二).jpg]] </div> <div class="col-md-4"> [[https://s.libforest.com/images/pic/西湖/日落(三).jpg]] </div> <div class="col-md-4"> [[https://s.libforest.com/images/pic/西湖/日落(一).jpg]] </div> </div>
因为我之前的博客主题使用了 Bootstrap,为了能够让多张图片并排显示,所以用了 Bootstrap 里的 .row .col-*
。但前不久移除了全部的 Bootstrap,现在当然不会生效。另外一点是我之前用的 org mode 解析器可以直接解析 HTML 中的链接,但更换了新的解析器 org-golang 后,已经无法不能解析HTML中的原始链接
此次利用 Snow 博客系统中的 shortcode 功能实现多图排版,让图片可以并排显示,多行显示。
解析原始链接
首先在主题下创建一个名为 img-layout
的 shortcode,比如我使用的主题叫做 snow,所以在 themes/snow/templates/shortcodes
目录下创建一个 img-layout.html
文件,并添加 markdown
或者 org
的 filter 将原始文本解析成HTML
<div class="img-layout"> {%- if params.type == "markdown" %} {{ body | markdown | safe }} {%- else %} {{ body | org | safe }} {%- endif %} </div>
接着修改原始文章
#+begin_export html <shortcode _name="img-layout"> [[https://s.libforest.com/images/pic/西湖/日落(二).jpg]] [[https://s.libforest.com/images/pic/西湖/日落(三).jpg]] [[https://s.libforest.com/images/pic/西湖/日落(一).jpg]] </shortcode> #+end_export
经过修改,原始文章中的内容将会自动渲染成
<div class="img-layout"> <p> <img src="https://s.libforest.com/images/pic/西湖/日落(二).jpg" /> <img src="https://s.libforest.com/images/pic/西湖/日落(三).jpg" /> <img src="https://s.libforest.com/images/pic/西湖/日落(一).jpg" /> </p> </div>
并排显示
有了固定结构的HTML, 接着就可以添加 css,使多张图片可以并排显示
.img-layout p { display: flex; flex-wrap: wrap; } .img-layout p > img { width: auto; min-width: 0; max-width: 100%; flex: 10000 1 0%; } /* 处理手机等设备图片显示问题 */ @media screen and (max-width: 600px) { .img-layout p > img { min-width: 100% } } /* 添加图片上下左右间隔 */ .img-layout p { margin: -0.25rem 0 0 -0.25rem !important; } .img-layout p > * { margin: 0.5rem 0 0 0.25rem !important; }
多行显示
多行显示可以利用文件解析时每次遇到空行都会生成一个新的段落,比如
[[https://s.libforest.com/images/pic/西湖/日落(一).jpg]] [[https://s.libforest.com/images/pic/西湖/日落(二).jpg]]
就会生成
<p> <img src="https://s.libforest.com/images/pic/西湖/日落(一).jpg" /> </p> <p> <img src="https://s.libforest.com/images/pic/西湖/日落(二).jpg" /> </p>
故如果需要多行显示,只用在多张图片中间添加一个空行即可
图片懒加载和点击全屏
之前的图片懒加载和点击全屏的功能我也是利用 Snow 中的 shortcode 功能实现的,我在 themes/snow/templates/shortcodes
目录下建立了一个 img.html
的文件
<a href="{{ params.src }}" data-fancybox="image"> <img data-src="{{ params.src + '-thumb' }}" class="lazyload" /> </a>
这样,文章内所有的 img
标签的图片都会加上懒加载和点击全屏的功能(基于 lazysizes 和 fancybox)
但是,由于 Snow 中 shortcode 的实现是一次性遍历 HTML DOM,无法在一个 shortcode 内部调用另一个 shortcode。 所幸 Snow 是我自己写的,思索片刻,我在 shortcode 实现中加入了三行代码,这样就能在一个 shortcode 中重复调用其它的 shortcode
vars := map[string]interface{}{ ... + "_shortcode": func(s string) string { + return self.shortcode(page, s) + }, }
然后修改 img-layout.html
<div class="img-layout"> {%- if params.type == "markdown" %} {{ _shortcode(body | markdown) | safe }} {%- else %} {{ _shortcode(body | org) | safe }} {%- endif %} </div>
最后添加 css 样式
- .img-layout p > img { + .img-layout p > img, .img-layout p > a { + .img-layout p > a > img { + height: 100%; + }
显示效果
-
两张图片
-
三张图片
-
多行显示