Hexo Next模板添加相册功能 | 幸福的猪窝

Hexo Next模板添加相册功能

由于Wordpress越来越笨重,在习惯使用Markdown后发现几次升级Wordpress对Markdown支持不太友好。遂决定更换Hexo。
文章的迁移过程比较顺利。最后图库好像默认情况下无法支持。于是只好自己动手。
本文主要参考了 asdfv1929的实现过程,稍作修改。
同时还有两个同样衍生自asdfv1929的文章也在此鸣谢:
如何在Hexo中实现自适应响应式相册功能
Hexo NexT 博客增加瀑布流相册页面

我的主要实现思路

  1. 增加一个page的类型 gallery
  2. 修改Next的模板针对gallery数据调用工具类重新渲染页面。使用minigride生成瀑布式布局
  3. 调用lazyload 和
  4. 增加模板支持新建文章时默认支持

实现过程

  1. 修改next模板内容支持 gallery 类型的页面。打开 themes/next/layout/_scripts 目录下的commons.swig文件。修改为如下内容。为了区分被注释部分是我添加的。主要目的是遇到gallery的页面添加minigrid.min.js 和 gallery.js 两个文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
{% if page.type ==='gallery' %}
{%
set js_commons = [
'utils.js',
'motion.js',
'minigrid.min.js',
'gallery.js'
]
%}
{% else %} */

{%
set js_commons = [
'utils.js',
'motion.js'
]
%}
/*
{% endif %}*/
  1. 找到 themes/next/layout 目录复制一份tag.swig文件。重命名为 gallery.swig .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{% extends '_layout.swig' %}
{% import '_macro/post-collapse.swig' as post_template %}
{% import '_macro/sidebar.swig' as sidebar_template %}

{% block title %}{{ __('title.tag') }}: {{ page.tag }} | {{ title }}{% endblock %}

{% block content %}

{#################}
{### GALLERY BLOCK ###}
{#################}
<div class="post-block tag">

<div id="posts" class="posts-collapse">
<div class="collection-title">
<{% if theme.seo %}h2{% else %}h1{% endif %}>{#
#}{{ page.tag }}{#
#}<small>{{ __('title.tag') }}</small>
</{% if theme.seo %}h2{% else %}h1{% endif %}>
</div>

{% for post in page.posts %}
{{ post_template.render(post) }}
{% endfor %}
</div>

</div>
{#####################}
{### END TAG BLOCK ###}
{#####################}

{% include '_partials/pagination.swig' %}

{% endblock %}

{% block sidebar %}
{{ sidebar_template.render(false) }}
{% endblock %}
  1. 创建gallery.js 和 gallery.css 定义相册样式和相册生成脚本。
    gallery.css 保存路径:themes/next/gallery/
    1
    2
    3
    4
    5
    .ImageGrid {width: 100%;max-width: 1040px;margin: 0 auto; text-align: center;}
    .card {overflow: hidden;transition: .3s ease-in-out; border-radius: 8px; background-color: #ddd;}
    .ImageInCard {padding:1px 1px 1px 1px}
    .ImageInCard img {padding: 0 0 0 0;}
    .TextInCard {line-height: 54px; background-color: #ffffff; font-size: 24px;}

gallery.js 保存路径:themes/next/source/js
这个文件我修改比较大,主要原因是我使用VSCode写markdowd,使用七牛云存储保存图片资源。快速免费的CDN还有图片处理功能很不错。VSCode中有很好用的插件可以实现图片黏贴的同时上传到七牛,所以我这里也省掉了处理本地图片的逻辑,数据源的读取也进行了调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
gallery = {
page: 1, //未来支持分页。
offset: 100, //offset 用于设置照片数量的上限
init: function () {
//初始化数据
var data = [];
//需要相册功能的页面需要把图片贴进去,再生成的时候会生成到 gallery-data的 div中然后遍历图片生成数组。
$(".gallery-data").find("img").each(function (index, item) {
data.push({ "src": item.src, "imageName": item.alt });
});
this.render(this.page, data);
},
render: function (page, data) {
var begin = (page - 1) * this.offset;
var end = page * this.offset;
if (begin >= data.length) return;
var html, imgNameWithPattern, imgName, imageSize, imageX, imageY, li = "";
for (var i = begin; i < end && i < data.length; i++) {
imgName = data[i].imageName;
imgSrc = data[i].src + "-gallery"; //此处添加了七牛的图片处理功能,可以动态压缩缩略图提高访问速度。同时添加水印。
//这里 250 指的是图片的宽度,可以根据自己的需要调整相册中照片的大小,我这里固定了图片的大小不会有瀑布式交错的效果。
li += '<div class="card" style="width:250px">' +
'<div class="ImageInCard" style="height: 250px">' +
'<a data-fancybox="gallery" href="' + imgSrc + '" data-caption="' + imgName + '">' +
'<img src="' + imgSrc + '"/>' +
'</a>' +
'</div>' +
'<div class="TextInCard">' + imgName + '</div>' + //图片下显示文件名作为说明的功能
'</div>'
}
$(".ImageGrid").append(li);
$(".ImageGrid").lazyload();
this.minigrid();
},
minigrid: function () {
var grid = new Minigrid({
container: '.ImageGrid',
item: '.card',
gutter: 12
});
grid.mount();
$(window).resize(function () {
grid.mount();
});
}
}
gallery.init();

  1. 修改文件 themes/next/layout/page.swig 这里要自改两段第一段是 block title 部分中 page.type === “gallery”的两行是新加的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{% block title %}{#
#}{% set page_title_suffix = ' | ' + title %}{#

#}{% if page.type === 'categories' and not page.title %}{#
#}{{ __('title.category') + page_title_suffix }}{#
#}{% elif page.type === 'tags' and not page.title %}{#
#}{{ __('title.tag') + page_title_suffix }}{#
#}{% elif page.type === 'schedule' and not page.title %}{#
#}{{ __('title.schedule') + page_title_suffix }}{#

#}{% elif page.type === "gallery" and not page.title %}{#
#}{{ __('title.photos') + page_title_suffix }}{#

#}{% else %}{#
#}{{ page.title + page_title_suffix }}{#
#}{% endif %}{#
#}{% endblock %}

第二部分在 PAGE Body 部分,同样也是 elif page.type === ‘gallery’部分是新加的。这里的

1
2
3
4
5
6
7
8
9
10
{% elif page.type === 'schedule' %}
{% include 'schedule.swig' %}
{% elif page.type === 'gallery' %}
{### 生成好的图片会在这里所为数据源 ###}
<div style = "display:none" class="gallery-data">{{ page.content }}</div>
{### 下面这个是相册的真实容器,gallery.js会进行处理把数据源的图片添加到这里。###}
<div class="ImageGrid"></div>
{% else %}
{{ page.content }}
{% endif %}

  1. 修改 themes/next/_config.yml 找到 Lazyload和 Fancybox的配置项分别启动

    *1. 启用 lazyload

    1
    2
    3
    # Vanilla JavaScript plugin for lazyloading images.
    # Dependencies: https://github.com/theme-next/theme-next-jquery-lazyload
    lazyload: true
    1. 启用 fancybox
      1
      2
      3
      4
      5
      # Fancybox. There is support for old version 2 and new version 3.
      # Choose only one variant, do not need to install both.
      # To install 2.x: https://github.com/theme-next/theme-next-fancybox
      # To install 3.x: https://github.com/theme-next/theme-next-fancybox3
      fancybox: true

    找到vendors部分对应的 Lazyload和Fancybox配置好cdn

    配置 fancybox

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Internal version: 2.1.5 & 3.5.7
    # See: https://fancyapps.com/fancybox
    # Example:
    # fancybox: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js
    # fancybox: //cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.6/jquery.fancybox.min.js
    # fancybox_css: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css
    # fancybox_css: //cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.6/jquery.fancybox.min.css
    fancybox: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js
    fancybox_css: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css

    配置Lazyload

    1
    2
    3
    4
    5
    6
    # Internal version: 1.9.7
    # See: https://github.com/tuupola/jquery_lazyload
    # Example:
    # lazyload: //cdn.jsdelivr.net/npm/jquery-lazyload@1/jquery.lazyload.min.js
    # lazyload: //cdnjs.cloudflare.com/ajax/libs/jquery_lazyload/1.9.7/jquery.lazyload.min.js
    lazyload: //cdn.jsdelivr.net/npm/jquery-lazyload@1/jquery.lazyload.min.js

    配置结束