魔改即刻短文兼容Ech0

进行主题修改前必看

  • 博客魔改有风险,请务必备份你的原代码

  • 因为.pug.styl以及.yml等对缩进要求较为严格,请尽量不要使用记事本等无法提供语法高亮的文本编辑器进行修改。

  • 本文涉及修改内容会以diff代码块进行标识,复制时请不要忘记删除前面的+,-符号

  • 本帖基于Anzhiyu主题进行修改方案编写,因此请读者优先掌握Anzhiyu主题官方文档的内容后再来进行魔改。


前言

上个月看到柳神的一篇关于类似朋友圈的迁移魔改文,同时自己也关注这类良久,毕竟托静态博客的福,你是无论如何都挺难像动态博客那样好处理即时的内容,不过可以参考类似部分大佬的教程,将页面修改为通过API获取内容的方式,使其展示在前端.

我最早关注过MemosMoments这两项项目,其中Memos的设计是有比较大的缺陷(于我而言),单挑一处不稳定API就可以从这篇文章筛选出去了,不过好就好在占用极少,对在意占用资源的朋友们比较友好.

所以这一篇的目的就是修改即刻短文的获取方式由原essay.yml变更为网络API

参考文献以及鸣谢

本文来源项目:

本文修改基于以下项目:

📍特别提醒 请进行完以上部署的步骤后再进行以下的操作

本文代码来源:

本文另类思路来源:

(提供了添加配置项的思路,避免后续维护直接修改代码带来的不可逆操作)

参考步骤

优势对比

接下来的表格来源于柳神从Moments迁移到Ech0 | LiuShen’s Blog,基本我的评价也与此差不多.

特性MemosMomentsMemos
PWA适配✅ 支持❌ 不支持✅ 支持
标签系统✅ 完善✅ 完善✅ 支持
S3 图床✅ 支持✅ 支持✅ 支持
Meting音乐❌ 不支持✅ 支持✅ 支持
视频分享✅ 支持✅ 支持✅ 支持
设计风格功能导向,略显臃肿功能全面,类似后台简约美观,轻量
开发活跃度非常活跃,API易变相对稳定活跃,快速迭代
个人评价功能强大,但更新太折腾,生态不稳定。功能完美,但没PWA对我是减分项界面戳我,功能追上来了,PWA是加分项,目前的最爱

硬性要求

  • 一台服务器

  • 自主域名

  • 已部署anzhiyuHexo博客


Ech0部署

有服务器部署

如果你拥有个人服务器的就继续参考柳神的步骤走下去从Moments迁移到Ech0 | LiuShen’s Blog

在此我主要推无服务器的部署方法

无服务器部署

看到上面的硬性要求要求有服务器,有人就懵逼了起来,”都穷玩博客了,我哪里会有多余资金购置服务器”

说的对!对于我个人而言我是有一台服务器的,不过考虑到稳定性和续费的高昂价格,我不禁踌躇

所以我们走一些比较偏门的方法,令我们拥有一台服务器

在此我介绍云部署平台Zeabur(非广),类似的有Hugging Face

image.png

注册完毕后来到控制台-创建项目(随便一个地区)-Docker 容器镜像(填入以下内容)

  • 镜像: sn0wl1n/ech0:latest

  • 环境变量: JWT_SECRET(变量名) ; Hello Echos(变量值)

  • 端口: 6277 ; HTTP

  • 卷(创建两项): /data , /opt/ech0/data ; /backup, /opt/ech0/backup

具体解释源自:

不过我发现这种部署方案更新比较麻烦

创建完毕在项目里切换到网络,添加个人域名,比如我这里用的是ech0.gbfun.cc

image.png

后面就可以进入域名,注册ech0的管理员账号了

关于管理员的账号说明可以查阅上方的Ech0安装部署指南

📍 首次使用注册的账号会被设置为管理员(目前仅管理员支持发布内容)


魔改方案

接下来是高危步骤,请务必备份好源代码.

📍特别提醒 以下涉及修改内容较多,请务必备份源代码以方便回滚

涉及的相关文件

文件路径操作目的
_config.anzhiyu.yml修改添加 ech0 配置项
themes/anzhiyu/layout/includes/page/essay.pug修改动态加载容器
themes/anzhiyu/layout/includes/bbTimeList.pug修改首页轮播条动态加载
source/js/essay.js创建API 获取与渲染逻辑
themes/anzhiyu/layout/includes/additional-js.pug修改脚本配置注入
themes/anzhiyu/source/js/utils.js修改更新 initIndexEssay
themes/anzhiyu/source/css/_extra/essay_page/essay_page.css修改样式适配
themes/anzhiyu/layout/includes/head.pug修改轮播 CSS 条件
themes/anzhiyu/layout/includes/top/top.pug修改轮播 JS 条件

具体修改代码

  • _config.anzhiyu.yml - 添加 Ech0 配置

此处思路来源梦爱吃鱼的友链朋友圈项目

添加集中整体的 API 配置,便于维护

1
2
3
4
5
6
7
8
9
10
11
12
# Ech0 即刻短文配置
ech0:
enable: true
api_url: https://ech0.gbfun.cc/api/echo/page # Ech0 API地址
page_limit: 30 # /essay/页面展示条数
index_limit: 10 # 首页轮播条展示条数
cache_ttl: 1800000 # 缓存时间(毫秒) 30分钟
name: LixdHappy # 展示名称
desc: 羊了个羊 # 个人签名
avatar: /img/博客头像.gif # 头像
avatar_link: /about/ # 头像点击链接
top_background: https://img.gbfun.cc/file/project/MWjwM6eh.jpg # 顶部背景图

  • source/js/essay.js(核心逻辑)

代码源于柳神从Moments迁移到Ech0-说说页面

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
(function () {
'use strict';

const defaultConfig = {
api_url: 'https://ech0.gbfun.cc/api/echo/page',
page_limit: 30,
index_limit: 10,
cache_ttl: 1800000,
name: 'Ech0',
avatar: '/img/avatar.png'
};

function getConfig() {
return typeof Ech0Config !== 'undefined' ? { ...defaultConfig, ...Ech0Config } : defaultConfig;
}

// 获取数据(带缓存)
async function fetchEch0Data(limit) {
const config = getConfig();
const cacheKey = `ech0_cache_${limit}`;
const cacheTimeKey = `ech0_cache_time_${limit}`;
const now = Date.now();

const cachedData = localStorage.getItem(cacheKey);
const cachedTime = localStorage.getItem(cacheTimeKey);

if (cachedData && cachedTime && (now - parseInt(cachedTime)) < config.cache_ttl) {
return JSON.parse(cachedData);
}

try {
const response = await fetch(config.api_url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ page: 1, pageSize: limit })
});
const data = await response.json();
if (data.code === 1 && data.data && Array.isArray(data.data.items)) {
localStorage.setItem(cacheKey, JSON.stringify(data.data.items));
localStorage.setItem(cacheTimeKey, now.toString());
return data.data.items;
}
} catch (error) {
console.error('Ech0 API Error:', error);
}
return [];
}

// 生成单个 essay 项目的 HTML
function generateEssayItemHTML(item, config) {
const content = item.content || '';
const date = item.created_at || new Date().toISOString();
const images = Array.isArray(item.images) ? item.images : [];
const extensionType = item.extension_type || '';
const extension = item.extension || '';
const location = item.location || '';
const tags = Array.isArray(item.tags) && item.tags.length ? item.tags.map(t => t.name || t) : [];

let html = `
<li class="bber-item">
<div class="user-avatar" style="background: url(${config.avatar}) left 28% / cover no-repeat #ffffffad;"></div>
<div class="bber-content">
<div class="right">
<div class="bber-name">${config.name}</div>
<p class="datacont">${escapeHtml(content)}`;

// 图片
if (images.length > 0) {
html += `<div class="bber-container-img">`;
images.forEach(img => {
const imgUrl = img.image_url || img;
html += `<a class="bber-content-img" href="${imgUrl}" target="_blank" data-fancybox="gallery"><img src="${imgUrl}" loading="lazy"></a>`;
});
html += `<div class="bber-content-noimg"></div><div class="bber-content-noimg"></div><div class="bber-content-noimg"></div></div>`;
}

// 视频
if (extensionType === 'VIDEO' && extension) {
html += `<div class="bber-video-container">`;
if (extension.startsWith('BV') || extension.includes('bilibili')) {
const bvid = extension.startsWith('BV') ? extension : extension.match(/BV[\w]+/)?.[0] || extension;
html += `<div class="bilibiliPlayer"><iframe src="https://www.bilibili.com/blackboard/html5mobileplayer.html?bvid=${bvid}&as_wide=1&high_quality=1&danmaku=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" loading="lazy"></iframe></div>`;
} else if (extension.includes('youtube') || extension.match(/^[\w-]{11}$/)) {
const videoId = extension.match(/^[\w-]{11}$/) ? extension : extension.match(/(?:v=|\/)[\w-]{11}/)?.[1] || extension;
html += `<div class="youtubePlayer"><iframe src="https://www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen loading="lazy"></iframe></div>`;
}
html += `</div>`;
}

// 音乐
if (extensionType === 'MUSIC' && extension) {
const music = parseMusicLink(extension);
if (music) {
html += `<div class="bber-music"><meting-js id="${music.id}" server="${music.server}" type="song" mutex="true" preload="none" theme="var(--anzhiyu-main)" data-lrctype="0" order="list"></meting-js></div>`;
}
}

// 外链
if ((extensionType === 'WEBSITE' || extensionType === 'GITHUBPROJ') && extension) {
let siteUrl = '', title = '';
try {
const extObj = typeof extension === 'string' ? JSON.parse(extension) : extension;
siteUrl = extObj.site || extObj.url || extension;
title = extObj.title || siteUrl;
} catch { siteUrl = extension; title = extension; }
html += `<div class="bber-external-link"><a href="${siteUrl}" target="_blank" rel="nofollow noopener" class="external-link"><i class="anzhiyufont anzhiyu-icon-link"></i><span>${escapeHtml(title)}</span></a></div>`;
}

html += `</p><hr class="essay-hr">`;

// 底部信息
html += `<div class="bber-bottom"><div class="bber-info">
<div class="bber-info-time"><i class="anzhiyufont anzhiyu-icon-clock"></i><time class="datatime" datetime="${date}" style="display: inline;">${getRelativeTime(date)}</time></div>`;

// 标签
if (tags.length > 0) {
html += `<div class="essay-tag"><i class="anzhiyufont anzhiyu-icon-tags faa-tada"></i><span>${escapeHtml(tags.join(', '))}</span></div>`;
}

// 外链按钮
if ((extensionType === 'WEBSITE' || extensionType === 'GITHUBPROJ') && extension) {
let linkUrl = '';
try { linkUrl = JSON.parse(extension).site || extension; } catch { linkUrl = extension; }
html += `<a class="bber-content-link" title="跳转到短文指引的链接" href="${linkUrl}" rel="external nofollow" target="_blank"><i class="anzhiyufont anzhiyu-icon-link"></i>链接</a>`;
}

html += `</div><div class="bber-reply" onclick="rm && rm.rightMenuCommentText('${escapeHtml(content)}')"><i class="anzhiyufont anzhiyu-icon-message"></i></div></div></div></div></li>`;

return html;
}

// 渲染页面
async function renderEssayPage() { /* ... */ }
async function renderIndexEssayBar() { /* ... */ }
function initEssaySwiper() { /* ... */ }
function initEch0() { /* ... */ }

// 初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initEch0);
} else {
initEch0();
}
document.addEventListener('pjax:complete', initEch0);

window.Ech0Essay = { init: initEch0 };
})();

主要有几项特性:

  1. Ech0 API获取内容数据

  2. 30分钟 localStorage 缓存

  3. 支持图片,视频(B站/YouTube),音乐,外链

  4. 兼容Pjax


  • essay_page.css

以下内容没有diff代码块标注修改位置,请自行斟辨.

  1. datacontbber-content去除圆角(此处内容可能并不需要,因为我的修改内容过多,可能有破坏了该处的原有样式,所以我在此进行了修改,可能原有anzhiyu代码并没有此处内容)
1
2
3
4
#bber .bber-content .datacont {
/* ... */
border-radius: 0; /* 原为 12px */
}
1
2
3
#bber div.bber-content {
border-radius: 0; /* 原为 12px */
}

没有此处的修改,可能会造成datacont容器左上方变为圆角

  1. essay-tag胶囊样式

这里是我新加入的变量,用于获取Ech0的内容tag标签,该处是绝对定位布置在时间的右边,链接的左边

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
/* essay-tag 标签胶囊样式 */
#bber .essay-tag {
display: flex;
align-items: center;
font-size: 0.7rem;
color: var(--anzhiyu-fontcolor);
background-color: var(--anzhiyu-gray-op);
padding: 0 8px;
border-radius: 20px;
height: 24px;
cursor: default;
}

#bber .essay-tag i {
margin-right: 4px;
font-size: 0.7rem;
color: var(--anzhiyu-main);
}

#bber .essay-tag span {
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
  1. 视频容器样式
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
#bber .bber-video-container {
width: 100%;
margin: 10px 0;
}

#bber .bilibiliPlayer,
#bber .youtubePlayer {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
overflow: hidden;
border-radius: 12px;
}

#bber .bilibiliPlayer iframe,
#bber .youtubePlayer iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
border: var(--style-border);
}
  1. 移动端朋友圈样式
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@media screen and (max-width: 900px), (max-height: 580px) {
/* 高斯模糊背景 */
div#essay_page {
border: var(--style-border);
box-shadow: var(--anzhiyu-shadow-border);
border-radius: 10px;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: saturate(180%) blur(20px);
}

[data-theme="dark"] div#essay_page {
background: rgba(30, 30, 30, 0.78);
}

/* right区域左边距给头像留空间 */
body[data-type=essay] .right {
margin-left: 55px;
}

/* bber-item 朋友圈样式 */
#bber .timeline ul li.bber-item {
width: 95%;
border: none;
border-radius: 0;
padding: 0;
background: transparent;
box-shadow: none;
}

/* 显示用户名 */
.bber-name {
font-size: 16px;
font-weight: 800;
display: block;
}

/* 显示头像并绝对定位 */
.user-avatar {
width: 45px;
height: 45px;
border-radius: 10px;
overflow: hidden;
position: absolute;
display: block;
left: 0;
top: 0;
}

/* 防止内容溢出 */
#bber .bber-item .right {
max-width: calc(100% - 55px);
overflow: hidden;
}

/* 胶囊元素适配 */
#bber .bber-info-time,
#bber .bber-content-link,
#bber .bber-info-address,
#bber .essay-tag {
font-size: 0.65rem;
padding: 0 6px;
height: 22px;
}

#bber .essay-tag span {
max-width: 80px;
}
}

整体上来说,这部分最明显的是处理了移动端的背景,在夜间模式增加了高斯模糊的背景,提高可视度.


  • bbTimeList.pug

此处用于处理首页轮播条的获取数据方式由essay.yml变更为Ech0 API,经过此步骤后essay.yml可以自行删除或留念

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
//- bbTimeList.pug - Ech0 API动态加载版本
if theme.ech0 && theme.ech0.enable
- let onclick_value = theme.pjax.enable ? `pjax.loadUrl("/essay/");` : '';
- let href_value = theme.pjax.enable ? 'javascript:void(0);' : `/essay/`;
#bbTimeList.bbTimeList.container
i.anzhiyufont.anzhiyu-icon-jike.bber-logo.fontbold(onclick=onclick_value, title="即刻短文" gbtip="即刻短文", href=href_value, aria-hidden="true")
#bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1")
#bber-talk.swiper-wrapper(onclick=onclick_value)
//- 动态内容由JS渲染
a.li-style.swiper-slide(href=href_value) 加载中...
a.bber-gotobb.anzhiyufont.anzhiyu-icon-circle-arrow-right(onclick=onclick_value, href=href_value, title="查看全文" gbtip="查看全文")

script(src=url_for(theme.home_top.swiper.swiper_js))
script.
if (typeof Ech0Config === 'undefined') {
var Ech0Config = {
api_url: '#{theme.ech0.api_url}',
page_limit: #{theme.ech0.page_limit},
index_limit: #{theme.ech0.index_limit},
cache_ttl: #{theme.ech0.cache_ttl},
name: '#{theme.ech0.name}',
avatar: '#{theme.ech0.avatar}'
}
}

else if site.data.essay
each i in site.data.essay
if i.home_essay
- let onclick_value = theme.pjax.enable ? `pjax.loadUrl("/essay/");` : '';
- let href_value = theme.pjax.enable ? 'javascript:void(0);' : `/essay/`;
#bbTimeList.bbTimeList.container
i.anzhiyufont.anzhiyu-icon-jike.bber-logo.fontbold(onclick=onclick_value, title="即刻短文" gbtip="即刻短文", href=href_value, aria-hidden="true")
#bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1")
#bber-talk.swiper-wrapper(onclick=onclick_value)
each i in site.data.essay
each item, index in i.essay_list
if index < 10
- var contentText = item.image ? item.content + ' [图片]' : (item.video ? item.content + ' [视频]' : item.content)
a.li-style.swiper-slide(href=href_value)= contentText
a.bber-gotobb.anzhiyufont.anzhiyu-icon-circle-arrow-right( onclick=onclick_value, href=href_value, title="查看全文" gbtip="查看全文")

script(src=url_for(theme.home_top.swiper.swiper_js))

整体替换文件


  • essay.pug

整体替换文件

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//- essay.pug - Ech0 API动态加载版本
if theme.ech0 && theme.ech0.enable
#essay_page
.author-content.author-content-item.essayPage.single(style=`background: url(${theme.ech0.top_background}) left 28% / cover no-repeat;`)
.author-info
.msg
.avatar
a.essay-avatar(href=theme.ech0.avatar_link)
img(src=theme.ech0.avatar)
.eassy-name= theme.ech0.name
.desc= theme.ech0.desc
#bber
section.timeline.page-1.content
ul#waterfall.list
//- 动态内容由JS渲染
#bber-tips(style='color: var(--anzhiyu-secondtext);')
| - 加载中... -

script.
if (typeof Ech0Config === 'undefined') {
var Ech0Config = {
api_url: '#{theme.ech0.api_url}',
page_limit: #{theme.ech0.page_limit},
index_limit: #{theme.ech0.index_limit},
cache_ttl: #{theme.ech0.cache_ttl},
name: '#{theme.ech0.name}',
avatar: '#{theme.ech0.avatar}'
}
}
script(defer data-pjax src=url_for('/js/essay.js'))

else if site.data.essay
//- 回退到原有的静态数据模式
each i in site.data.essay
#essay_page
.author-content.author-content-item.essayPage.single(style = i.top_background ? `background: url(${i.top_background}) left 28% / cover no-repeat;` : "")
.author-info
.msg
.avatar
a.essay-avatar(href=i.avatarLink)
img(src=i.avatar)
.eassy-name=i.name
.desc=i.desc
#bber
section.timeline.page-1.content
ul#waterfall.list
each item, index in i.essay_list
if index < i.limit
li.bber-item
.user-avatar(style = i.top_background ? `background: url(${i.avatar}) left 28% / cover no-repeat #ffffffad;` : "")
.bber-content
.right
.bber-name=i.name
p.datacont= item.content
if item.image
.bber-container-img
each iten, indey in item.image
a.bber-content-img(href=url_for(item.image[indey]), target="_blank", data-fancybox="gallery", data-caption="")
img(src=url_for(item.image[indey]))
.bber-content-noimg
.bber-content-noimg
.bber-content-noimg
if item.video
.bber-container-img
each iten, indey in item.video
if (item.video[indey].includes('player.bilibili.com'))
div(style="position: relative; padding: 30% 45%;margin-top: 10px;margin-bottom: 10px;")
iframe(style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;margin: 0;border-radius: 12px;border: var(--style-border);" src=url_for(item.video[indey]) scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true")
else
a.bber-content-video(href=url_for(item.video[indey]) data-fancybox="gallery", data-caption="")
video(src=url_for(item.video[indey]))
.bber-content-noimg
.bber-content-noimg
.bber-content-noimg
if item.aplayer
.bber-music
meting-js(id=item.aplayer.id, server=item.aplayer.server, type="song", mutex="true",preload="none", theme="var(--anzhiyu-main)", data-lrctype="0", order="list")
.bber-bottom
.bber-info-address
if item.address
span=item.address
.bber-info-time
- var datedata = new Date(item.date).toISOString()
time.datatime(datetime= item.date)= datedata
.bber-info-link
if item.link
a.bber-content-link(title="跳转到短文指引的链接", href=url_for(item.link), rel="external nofollow")
i.anzhiyufont.anzhiyu-icon-link
| 链接
.bber-reply(onclick="rm.rightMenuCommentText(" + `'${item.content}'` + ")")
i.anzhiyufont.anzhiyu-icon-message
hr.essay-hr
#bber-tips(style='color: var(--anzhiyu-secondtext);')
="- 只展示最近" + i.limit + "条短文 -"


  • additional-js.pug
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  //- 即刻依赖waterfall
script(async data-pjax src=url_for(theme.asset.waterfall))

+ //- Ech0 即刻短文 API
+ if theme.ech0 && theme.ech0.enable
+ script.
+ if (typeof Ech0Config === 'undefined') {
+ var Ech0Config = {
+ api_url: '#{theme.ech0.api_url}',
+ page_limit: #{theme.ech0.page_limit},
+ index_limit: #{theme.ech0.index_limit},
+ cache_ttl: #{theme.ech0.cache_ttl},
+ name: '#{theme.ech0.name}',
+ avatar: '#{theme.ech0.avatar}'
+ }
+ }
+ script(defer data-pjax src=url_for('/js/essay.js'))

自行删除附带的+,还是没忍住标注


  • utils.js457-481行左右
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
// 初始化即刻 - 支持 Ech0 API 动态加载
initIndexEssay: function () {
const bbTimeList = document.getElementById("bbTimeList");
if (!bbTimeList) return;

// 检查是否使用 Ech0 API,如果是则等待 JS 加载完成
const swiperWrapper = document.querySelector('#bber-talk');
if (!swiperWrapper) return;

// 等待内容加载完成(如果是动态加载)
const slides = swiperWrapper.querySelectorAll('.swiper-slide');
if (slides.length === 0 || (slides.length === 1 && slides[0].textContent.includes('加载中'))) {
// 内容还没加载完成,等待 essay.js 处理
return;
}

setTimeout(() => {
const swiperContainer = document.querySelector('.essay_bar_swiper_container');
if (!swiperContainer) return;

// 销毁旧的 swiper 实例
if (swiperContainer.swiper) {
swiperContainer.swiper.destroy(true, true);
}


  • head.pug70-73行左右
1
2
if site.data.essay || theme.home_top.swiper.enable || (theme.ech0 && theme.ech0.enable)
link(rel='stylesheet' href=url_for(theme.home_top.swiper.swiper_css) media="print" onload="this.media='all'")

确保在配置项的enable: true可以生效


  • top.pug98-99行左右
1
2
3
if theme.home_top.swiper.enable
if !site.data.essay && !(theme.ech0 && theme.ech0.enable)
script(src=url_for(theme.home_top.swiper.swiper_js))

同理


至此,关于魔改即刻短文兼容Ech0 到此完毕

剩下内容你可以查阅柳神的后续步骤

从Moments迁移到Ech0-注意事项 | LiuShen’s Blog


总结

如果你仔细查阅过本站的大部分内容,你会发现基本上是对于anzhiyu主题的魔改,算是一些对于优秀设计的简陋复刻,个人水平十分有限,也是个穷学生才会折腾静态博客,不过有一说一,Hexo博客的构建着实令人着急,也难怪主题作者安知鱼会重构主题,不过个人认为这是潜力巨大才有开发的可能性

在此已接近每月一篇文章的速度更新,后续或许还会更加懒散,希望大家多多担待,往后主题定性后或许就开始搬运自己的文章上来了,更新速度或许还会更快?

如果你看到这里了,哪一天没有更新就可以看看即刻短文了解一下情况,算对鄙人莫大的慰籍了

在此,感谢你的耐心阅读,祝你有所感悟!