惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
NISL@THU
NISL@THU
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
K
Kaspersky official blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
爱范儿
爱范儿
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
S
Securelist
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
美团技术团队
F
Fortinet All Blogs
小众软件
小众软件
Recorded Future
Recorded Future
V
Visual Studio Blog
B
Blog RSS Feed
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
Latest news
Latest news
Spread Privacy
Spread Privacy
H
Heimdal Security Blog

爱吃肉的猫

那就,再相逢 Butterfly的魔改教程:最新评论页 离歌不夜天 前端分享 - 滑动阻尼效果 Butterfly的魔改教程:右键菜单 音乐分享 - doi微醺氛围 Butterfly的魔改教程:动态相册页 近况记事 - 11 微信公众号:Ai大模型让回复更具智能化 近况记事 - 10 PWA:让你的网站变成桌面应用APP Healthy Love Butterfly的魔改教程:关于本站 近况记事 - 9 Butterfly的魔改教程:待办清单 TrollStore - 不掉签助手 近况记事 - 8 Twikoo评论回复邮件模版 过一个很特别的七夕 The Young Boy and the Sea Butterfly的魔改教程:文章订阅页 思考题目:混乱是阶梯 近况记事 - 7 Butterfly的魔改教程:loading加载动画 差旅游记 再见,不惑之年:二十又一 近况记事 - 6 Butterfly的魔改教程:自定页数跳转 堆友AI作图:3D资源设计平台,堆出你的未来 【QD-Today】自建私有自动签到服务 Long time no see Butterfly的魔改教程:聊天记录页 Butterfly的魔改教程:个性定位信息 近况记事 - 5 Butterfly的魔改教程:好物推荐页 CDN加速 二刷《想见你》 网络言论不是法外之地 近况记事 - 4 深夜训斥 近况记事 - 3 近况记事 - 2 日常打理的那些事 Butterfly的魔改教程:随机阅读一篇文章 随笔 · 封 布柒糖FM项目进展报告 清明路雨纷纷 TA - 仲夏夜的荒原 重构记录 - 4 近况记事 Butterfly的魔改教程:评论弹窗 2021款 Model Y 近两年用车总结 重构记录 - 3 百日祭 避风的港湾 Emoji表情大全 iCat-APP 开源记录 Butterfly的调整教程:文章外挂标签美化 iOS修改 - 万铲铲的致富之路 Markdown 基础教程 从你的全世界路过 小米摄像头!避!雷! VuePress 搭建教程 Hexo跳过指定文件渲染 百度贴吧每日自动签到 重构记录 - 1 GitHub Desktop提交报错 快速批量处理重命名 Git连接仓库常用命令 Ubuntu处理deb命令 掘金自动签到并挖矿 一个简洁的橙色调个人简介 我的猫以前也是流浪猫 布柒糖FM 最新指北 初学写个了油猴脚本 幽灵404页面 PC游戏 · 植物大战僵尸 语言包 · 越狱篇 砸壳多开 · 越狱篇 HuiRan Cursors 手动关闭Win10自动更新 iPhone XR 完美越狱 成功实例 三年的跌撞 关于《小橘妈妈》 魔改前置教程:添加自定义css和js文件 Hexo 博客添加RSS插件 Butterfly的魔改教程:导航栏魔改美化
Butterfly的魔改教程:即刻短文页
亦小封 · 2023-07-31 · via 爱吃肉的猫

230731更新后,三端全面支持 瀑布流、图片灯箱、图片灯箱、外部链接、自定标识、快速评论、音乐模块、视频模块、说说置顶 功能。除了社交平台,即刻说也可成为你的下一个“朋友圈”。

250103更新的版本里,结合了在此前多位喵友的反馈和提醒下,重新修正了本篇内容,至此,可以说是大大优化了上手的难度,和减少教程的上手难度。

如果没有服务器可以搭建memos,可以使用iCat自用的memos服务

引用站外地址,注意辨别

效果预览

创建数据

小节开始前,提醒事项。
对于初次魔改新手,建议先过一遍:魔改前置教程:添加自定义css和js文件

  • 创建[博客根目录]/source/essay/index.md页面,并配置以下内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
title: 即刻短文
date: 2023-01-17 13:38:17
type: essay
top_img: false
aside: false
top_page: true
top_bg: https://img.meuicat.com/banner
top_item: 即刻短文
top_title: 封の碎碎念
top_tips: 使用 即刻短文动态部署版 构建
top_link: /about/
top_text: 关于博主
---

<!-- 页面内容 -->
  • 创建[主题目录]/layout/includes/page/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
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
148
149
150
151
152
153
154
155
156
157
mixin renderArticle(item)
.item
.bber-content
if item.content
p.datacont= item.content

if item.image
.bber-image
each iten, indey in item.image
- const image = item.image[indey].split('||')
img(src=image[0] alt=image[1] ? image[1] : '' title=image[1] ? '' : '即刻短文配图' )

if item.video
.bber-video
if item.video.bilibili
- const autoplay = item.video.autoplay ? '&autoplay=1' : '&autoplay=0'
- const biliurl = '//player.bilibili.com/player.html?bvid=' + item.video.bilibili.match(/(BV\w+)/)[1] + autoplay

iframe(src=biliurl scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true")
else if item.video.player
video(src=item.video.player controls="controls" style="object-fit: cover")

if item.aplayer
.bber-music
.aplayer(data-id=item.aplayer.id data-server=item.aplayer.server data-type="song" data-autoplay="false" data-mutex="true" data-theme='var(--icat-theme)')

hr

.bber-bottom
.bber-info
.bber-info-time
i.MeuiCat.icon-calendar-todo-fill
time.datatime(datetime=item.date)= 'Loading'

if item.from
.bber-info-from
span= item.from

if item.link
- const link = item.link.split('||')
a.bber-content-link(target="_blank" href=link[0] title=link[1] ? link[1] : '跳转到短文指引的链接')
i.MeuiCat.icon-link-m-line
| 链接

if item.top
.bber-info-top
i.MeuiCat.icon-hot-top-fill
| 置顶

if item.content
.bber-reply(onclick="commentText(" + `'${item.content}'` + ")")
i.MeuiCat.icon-chat-fill

- const {strip, mode, mode_link} = theme.essay

if theme.essay.enable
section#bber
case mode.trim()
when 'local'
- const essaydata = site.data.essay.essay_list

if essaydata && essaydata.length > 0
#waterfall.list
- const limitedList = strip === -1 ? essaydata : essaydata.slice(0, strip)
each item in essaydata.filter(item => item.top)
+renderArticle(item)
each item in limitedList.filter(item => !item.top)
+renderArticle(item)

#bber-tips
if strip === -1 || Math.abs(strip) >= essaydata.length
| - 已展开所有短文 -
else
| - 只展示最近 #{strip} 条短文 -

when 'json'
#page-load
img(src="https://img.meuicat.com/blog/loading.svg")
script.
async function essayFormat(data) {
const renderArticle = async (item) => {
let image = '', video = '', type = ''

if (item.image) item.image.map(e => image += `<img src="${e.split(' || ')[0]}" ${e.split(' || ').length > 1 ? `alt='${e.split(' || ')[1]}'` : `title="即刻短文配图"`} />`).join('')
let aplayer = item.aplayer ? `<div class="bber-music"><div class="aplayer" data-server="${item.aplayer.server}" data-type="song" data-id="${item.aplayer.id}" data-autoplay="false" data-mutex="true" data-theme="var(--icat-theme)"></div></div>` : ''
if (item.video) video = item.video.player ? `<div class="bber-video"><video src="${item.video.player}" controls="controls" style="object-fit: cover;"></video></div>` : item.video.bilibili ? `<div class="bber-video"><iframe src="//player.bilibili.com/player.html?bvid=${item.video.bilibili.match(/(BV\w+)/)[1]}${item.video.autoplay ? '&autoplay=1' : '&autoplay=0'}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe></div>` : ''
const time = changeTime(item.date)
let link = item.link ? ((type = item.link.split(' || ')), `<a class="bber-content-link" href='${type[0].startsWith('/') ? type[0] : (type[0].startsWith('http') ? type[0] : 'https://' + type[0])}' title="${type.length > 1 ? type[1] : '跳转到短文指引的链接' }" target="_blank"><i class="MeuiCat icon-link-m-line"></i>链接</a>`) : '';

return `<div class="item"><div class="bber-content">${item.content ? `<p class="datacont">${item.content}</p>` : ''}${image ? `<div class="bber-image">${image}</div>` : ''}${aplayer}${video}</div><hr><div class="bber-bottom"><div class="bber-info"><div class="bber-info-time"><i class="MeuiCat icon-calendar-todo-fill"></i><time datetime="${item.date}">${time}</time></div>${link}${item.from ? `<div class="bber-info-from"><span>${item.from}</span></div>` : ''}${item.top ? `<div class="bber-info-top"><i class="MeuiCat icon-hot-top-fill"></i>置顶</div>` : ''}</div>${item.content ? `<div class="bber-reply" onclick="commentText('${item.content}')"><i class="MeuiCat icon-chat-fill"></i></div>` : ''}</div></div>`
}

const { strip } = GLOBAL_CONFIG.essay
let essayTips, items = [], topitem = []

const processedData = await Promise.all(data[0].essay_list.map(async (item) => {
const formatdata = await renderArticle(item)
if (!formatdata) return null
if (item.top) {
topitem.push(formatdata)
} else {
items.push(formatdata)
}
return formatdata
}))
essayTips = strip === -1 || strip >= items.length ? `<div id="bber-tips">- 已展开所有短文 -</div>` : (items = items.slice(0, (strip - topitem.length)), `<div id="bber-tips">- 只展示最近 ${strip} 条短文 -</div>`)

return `<div id="waterfall" class="list">${topitem.concat(items).filter(item => item !== null).join('')}</div>${essayTips}`
}

when 'memos'
#page-load
img(src="https://img.meuicat.com/blog/loading.svg")
script.
async function essayFormat(data) {
const renderArticle = async (item) => {
const contentRegex = /#(.*?)\s|\n/g, imageRegex = /\!\[(.*?)\]\((.*?)\)/g, playerRegex = /{\s*player\s*(.*)\s*}/g, linkRegex = /(?<!\!)\[(.*?)\]\((.*?)\)/g, topRegex = /#top/g, fromRegex = /(?<![\w\/])(?<!\{)\{([^{}\s]+)\}(?!\})(?![\w\/])/g
let time = new Date((item.createdTs - (new Date().getTimezoneOffset() * 60)) * 1000).toISOString(), content = item.content, image = '', img = content.match(imageRegex), aplayer = content.match(/{\s*music\s*(.*?)\s*(.*?)\s*}/g), video = content.match(playerRegex), link = content.match(linkRegex), type = '', from = content.match(fromRegex)

if (item.resourceList.length) {
if (!img) img = []
item.resourceList.forEach(e => {
if (e.externalLink) img.push(e.externalLink)
else img.push(`${baseUrl}/o/r/${e.uid}`)
})
}

if (img) image += img.map(e => `<img src="${e.replace(imageRegex, '$2')}" ${e.replace(imageRegex, '$1') ? `alt="${e.replace(imageRegex, '$1')}"` : `title="即刻短文配图"`} />`).join('')
aplayer = aplayer ? `<div class="bber-music"><div class="aplayer" data-server="${aplayer[0].match(/\{\s*music\s*(.*?)\s*\d+\s*\}/)[1]}" data-type="song" data-id="${aplayer[0].match(/\d+/)[0]}" data-mutex="true" data-autoplay="false" data-theme="var(--icat-theme)"></div></div>` : ''
video = video ? `<div class="bber-video"><video src="${video[0].replace(playerRegex, '$1').trim()}" controls="controls" style="object-fit: cover;"></video></div>` : content.match(/{\s*bilibili\s*(.*?)\s*}/g)
video = Array.isArray(video) ? `<div class="bber-video"><iframe src="//player.bilibili.com/player.html?bvid=${video[0].match(/(BV\w+)/)[1]}${video[0].match(/{\s*bilibili\s*(.*?)\s*true\s*}/g) ? '&autoplay=1' : '&autoplay=0'}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe></div>` : ''
const timeFormat = changeTime(time)
link = link ? ((type = link[0].replace(linkRegex, '$2')), `<a class="bber-content-link" href='${type.startsWith('/') ? type : (type.startsWith('http') ? type : 'https://' + type)}' title="${link[0].replace(linkRegex, '$1') ? link[0].replace(linkRegex, '$1') : '跳转到短文指引的链接' }" target="_blank"><i class="MeuiCat icon-link-m-line"></i>链接</a>`) : ''
from = from ? `<div class="bber-info-from"><span>${from[0].replace(fromRegex, '$1')}</span></div>` : ''
content = content.replace(contentRegex, '').replace(imageRegex, '').replace(/\{(.*?)\}/g, '').replace(linkRegex, '').trim()

return `<div class="item"><div class="bber-content">${content ? `<p class="datacont">${content}</p>` : ''}${image ? `<div class="bber-image">${image}</div>` : ''}${aplayer}${video}</div><hr><div class="bber-bottom"><div class="bber-info"><div class="bber-info-time"><i class="MeuiCat icon-calendar-todo-fill"></i><time class="datatime" datetime="${time}">${timeFormat}</time></div>${link}${from}${item.content.includes('#top') ? `<div class="bber-info-top"><i class="MeuiCat icon-hot-top-fill"></i>置顶</div>` : ''}</div>${content ? `<div class="bber-reply" onclick="commentText('${content}')"><i class="MeuiCat icon-chat-fill"></i></div>` : ''}</div></div>`
}

const { strip, mode_link } = GLOBAL_CONFIG.essay
const baseUrl = mode_link.substring(0, mode_link.indexOf("/", mode_link.indexOf("//") + 2))
let essayTips, items = [], topitem = []

const processedData = await Promise.all(data.map(async (item) => {
const formatdata = await renderArticle(item,baseUrl)
if (!formatdata) return null
if (item.content.includes('#top')) {
topitem.push(formatdata)
} else {
items.push(formatdata)
}
return formatdata
}))
essayTips = strip === -1 || strip >= items.length ? `<div id="bber-tips">- 已展开所有短文 -</div>` : (items = items.slice(0, (strip - topitem.length)), `<div id="bber-tips">- 只展示最近 ${strip} 条短文 -</div>`)

return `<div id="waterfall" class="list">${topitem.concat(items).filter(item => item !== null).join('')}</div>${essayTips}`
}
  • 修改[主题目录]/layout/page.pug来使页面匹配。
1
2
3
4
5
6
7
8
      when 'shuoshuo'
include includes/page/shuoshuo.pug
+ when 'essay'
+ include includes/page/essay.pug
+ +commentLoad
default
include includes/page/default-page.pug
+commentLoad
  • 打开[主题目录]/layout/includes/head/config.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
  if (highlightEnable) {
const { copy, language, height_limit, fullpage, macStyle } = theme.code_blocks
highlight = JSON.stringify({
plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs',
highlightCopy: copy,
highlightLang: language,
highlightHeightLimit: height_limit,
highlightFullpage: fullpage,
highlightMacStyle: macStyle
})
}

+ let essay = 'undefined'
+ if (theme.essay && theme.essay.enable && theme.essay.mode !== 'local') {
+ const { strip, mode, mode_link, mini } = theme.essay
+ essay = JSON.stringify({
+ strip: strip,
+ mode: mode,
+ mode_link: mode_link,
+ mini_strip: mini.strip
+ })
+ }

···

percent: {
rightside: !{theme.rightside_scroll_percent},
},
- autoDarkmode: !{theme.darkmode.enable && theme.darkmode.autoChangeMode === 1}
+ autoDarkmode: !{theme.darkmode.enable && theme.darkmode.autoChangeMode === 1},
+ essay: !{essay}
}
  • _config.butterfly.yml主题配置文件中,新增以下配置项。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18





essay:
enable: true


strip: 30

mode: memos
mode_link: https://memos.meuicat.com/api/v1/memo?creatorId=1&tag=说说
mini:
enable: false
strip: 10

link: /essay/
  • 【可选】在_config.butterfly.yml主题配置文件中开启站点的pjax
1
2
3
4
5
6
7
8
9
10





pjax:
enable: true
exclude:


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
148
149
150
151
if hexo-config('essay.enable')
#bber
width 100%

#waterfall
transition 0.3s
opacity 0

&.list
display flex
flex-direction column

&.show
opacity 1

if hexo-config('enter_transitions')
.item
animation slide-in .6s .2s backwards

.item
position relative
display flex
flex-direction column
padding 1rem 1rem 0.9rem
width calc(100% / 3 - 1rem / 3)
transition all .3s, width 0s
@extend .cardHovers

+maxWidth1024()
width 49%
margin-right 1%

+maxWidth768()
width 100%

&:hover
box-shadow var(--icat-shadow-border)

.bber-content
display flex
flex-flow wrap
width 100%
height 100%

> *
margin-bottom .5rem !important

p.datacont
margin 0
font-size 15px
font-weight 700
color var(--icat-fontcolor)
line-height 1.38

.bber-image
display flex
gap .3rem
width 100%
flex-wrap wrap

> *
width calc(100% / 4 - .9rem / 4)
aspect-ratio 1 / 1
overflow hidden
border-radius 6px

a img
width 100%
height 100%
object-fit cover

.bber-video
position relative
padding 30% 50%

video, iframe
position absolute
width 100%
height 100%
left 0
top 0
margin 0
border-radius 6px
border var(--icat-border-always)
cursor pointer

.bber-music
width 100%
height 90px

.aplayer
margin 0
border-radius 6px

hr
margin .5rem 0 1rem
width 100%
border var(--icat-border-dashed)

.bber-bottom
display flex
justify-content space-between
width 100%

.bber-info
display flex
flex-wrap wrap
align-items center

> *
display flex
align-items baseline
padding 8px
background var(--icat-gray-op)
color var(--icat-fontcolor)
font-size .7rem
line-height 1
border-radius 99px

&:not(:first-child)
margin-left 0.5rem

i
padding-right 4px
font-size .8rem

a:hover
background var(--icat-theme)
color var(--icat-with)

.bber-content-link
background-color rgba(103, 194, 58, 0.13)
color rgb(103, 194, 58)

.bber-info-top
background-color rgba(245, 108, 108, 0.13)
color rgb(245, 108, 108)

.bber-reply
cursor pointer
transition 0.3s

&:hover
color var(--icat-theme)

#bber-tips
display flex
justify-content center
margin-bottom 2rem
padding-top 2rem
color var(--icat-secondtext)
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
let essayData

const initwaterfall = () => {
const waterfallElement = document.querySelector('#waterfall')
if (!waterfallElement) return
const init = () => {
const rootStyle = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--global-font-size').trim()) * 0.5

const waterfall = new InfiniteGrid.MasonryInfiniteGrid(waterfallElement, {
gap: { horizontal: rootStyle - 2, vertical: rootStyle },
useTransform: true,
useResizeObserver: true
})
waterfall.renderItems()
setTimeout(() => {
btf.addGlobalFn('pjaxCompleteOnce', () => { waterfall.destroy(); }, 'removeWaterfall')
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
btf.loadLightbox(waterfallElement.querySelectorAll('img'))
waterfallElement.classList.add('show')
}, 300)
}

typeof InfiniteGrid === 'function' ? init() : btf.getScript(`${GLOBAL_CONFIG.infinitegrid.js}`).then(init)
}

const essay = {
swiper: () => {
const essayElement = document.querySelector('#essay')
if (!essayElement) return

const swiperFn = () => {
const swiper = new Swiper(essayElement, {
direction: 'vertical',
autoplay: {
delay: 3000,
disableOnInteraction: false
},
loop: true
})
essayElement.addEventListener('mouseenter', () => {
swiper.autoplay.stop()
})
essayElement.addEventListener('mouseleave', () => {
swiper.autoplay.start()
})
btf.addGlobalFn('pjaxCompleteOnce', () => { swiper.destroy(); }, 'removEessay')
}

typeof Swiper === 'object' ? swiperFn() : btf.getScript('https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.6/swiper-bundle.min.js').then(swiperFn)
},
init: async () => {
const essayElement = document.getElementById('bber') || document.getElementById('essay-mini')
if (!essayElement) return

if (GLOBAL_CONFIG.essay !== 'undefined') {
if (!essayData) essayData = await fetch(GLOBAL_CONFIG.essay.mode_link).then(res => res.json())
const html = await essayFormat(essayData)
essayElement.innerHTML = html
}
initwaterfall(), essay.swiper()
}
}
btf.addGlobalFn('pjaxComplete', essay.init(), 'removEessay')

部署数据文件

  • 创建 [blogRoot]/source/_data/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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
essay_list:
- content: 即刻短文测试
date: 2023/07/31 15:30:50
from: iPhone XR
video:
player: /video/1.mp4

- content: 测试bilibili视频
date: 2023/07/31 15:30:50
video:
bilibili: //player.bilibili.com/player.html?aid=913951276&bvid=BV1RM4y1p75T&cid=1211165267&page=1

- content: bilibili网页链接
date: 2023/07/31 15:30:50
video:
bilibili: https://www.bilibili.com/video/BV17T4y1A7eW/?spm_id_from=333.1007.tianma.1-3-3.click

- content: bilibili单bv号
date: 2023/07/31 15:30:50
video:
bilibili: BV17T4y1A7eW
autoplay: true

- content: 完噜 还剩一天让我咋准备 😭
date: 2023/05/11 20:35:42
from: iPhone XR
image:
- https://s11.ax1x.com/2023/05/11/p9sKEh8.jpg

- content: 如果要定义 那就是下班后的日落和在家等我下班的她~
date: 2023/05/10 16:16:15
aplayer:
server: netease
id: 1949516216
top: true

- content: Melancholia - | 一款纯记录写作类Hexo主题 ✍️
date: 2023/04/23 22:27:22
from: Macbook Pro
link: https://github.com/yife68/Hexo-Theme-Melancholia || Melancholia

- content: 爱看 但还是得吃我一拳
date: 2023/04/22 15:10:30
from: iPhone XR
image:
- https://s11.ax1x.com/2023/05/03/p9JqGXd.jpg
- https://s11.ax1x.com/2023/05/03/p9Jq86H.jpg

- content: iCat 新启程
date: 2023/03/24 16:54:25
from: iPhone XR
link: https://meuicat.com/blog/14/
image:
- https://s11.ax1x.com/2023/05/02/p9GosYQ.jpg

- content: 各种观影史集于一体!人生足迹页诞生咯~
date: 2023/02/19 14:50:17
from: Macbook Pro
link: /collect/ || 链接描述
  • JSON文件可参照以下格式
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
[
{
"class_name": "即刻短文",
"essay_list": [
{
"content": "园长新造型!爱死",
"date": "2023/08/01 17:12:30",
"video": {
"bilibili": "//player.bilibili.com/player.html?aid=701381935&bvid=BV1dm4y1L7vj&cid=1212026428&page=1",
"autoplay": true
}
},
{
"content": "这辈子都不想完善项目了 😭 两点了 一看才搓完三分之一..",
"date": "2023/08/01 02:02:44",
"video": {
"player": "https://meuicat.com/video/1.mp4"
}
},
{
"content": "让我看看是谁在路上都还在敲键盘 噢 原来是我自己啊..",
"date": "2023/07/31 15:54:26",
"from": "iPhone XR"
},
{
"content": "落班 烧个排骨778~",
"date": "2023/07/26 17:55:36",
"from": "iPhone XR",
"image": [
"https://s11.ax1x.com/2023/07/26/pCjWbY4.jpg || 图片描述",
"https://s11.ax1x.com/2023/07/26/pCjWqfJ.jpg"
]
},
{
"content": "嘘..听歌..睡觉...",
"date": "2023/07/20 00:38:41",
"aplayer": {
"server": "netease",
"id": "1430702919"
},
"top": true
},
{
"content": "人生应该是一个轴对称的形状,最后失去的,也就是最开始拥有的。现在没人记得你的生日,有好处也有坏处,至少我是这么理解的。但无论是好还是坏,忍一忍,都会很快过去的",
"date": "2023/07/19 01:48:36",
"from": "iPhone XR",
"link": "/blog/64 || 链接描述"
},
{
"content": "用堆AI重绘一下我最爱的头像(图一 👉 图二)",
"date": "2023/07/06 16:30:32",
"from": "iPhone XR",
"link": "/blog/61",
"image": [
"https://img.meuicat.com/posts/2023/7/10.webp",
"https://img.meuicat.com/posts/2023/7/11.webp"
]
},
{
"content": "",
"date": "2023/06/30 08:26:22",
"aplayer": {
"server": "netease",
"id": "2009974513"
}
}
]
}
]
参数 释义 注意事项
content 【选填】说说内容 /
date 【必填】说说发布的时间 /
image 【可选】说说图片 图片的描述可在链接后以“||”分割开。如:”https://img.meuicat.com/posts/2023/7/11.webp || 亦小封”
aplayer 【可选】音乐播放器 /
aplayer.server 【必填】音乐播放器的服务器 目前仅支持填写:netease、tencent
aplayer.id 【必填】音乐ID 只能填写单曲id
video 【可选】视频 /
video.player 【选填】video视频播放器 /
video.bilibili 【选填】bilibili视频 必须是b站带BV号的视频链接
video.autoplay 【选填】bilibili视频是否自动播放 如需自动播放,请填写true
from 【可选】标识符,无实际意义 /
link 【可选】外部链接 链接描述可在链接后以“||”分割开。如:”https://meuicat.com/ || MeuiCat”
  • Memos用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#说说 {标识符} 我是内容 [我是链接](https://meuicat.com) ![](https://img.meuicat.cn/blog/8.png)
<!-- 常规写法 -->

#说说 网易云音乐 {music netease 29947420 }
#说说 腾讯音乐 {music tencent 330977131 }
<!-- 音乐写法 -->

#说说 普通视频 { player https://v.meuicat.com/video/1.mp4 }
#说说 哔哩哔哩手机视频 { bilibili https://m.bilibili.com/video/BV17T4y1A7eW }
#说说 哔哩哔哩网页视频 { bilibili https://www.bilibili.com/video/BV17T4y1A7eW/?spm_id_from=333.1007.tianma.1-3-3.click }
<!-- 视频写法 -->

#说说 #top
我是内容 ![我是图片描述](https://img.meuicat.cn/blog/8.png)![](https://img.meuicat.cn/blog/8.png)
<!-- 置顶写法 -->
参数 释义 注意事项
#标签 【必填】标签,用于区分说说 标签内前缀为#,至少需要有一个
#top 【可选】置顶,用于置顶说说。置顶的说说会排在最前面,不受数量显示限制 /
{自定义标识符} 【可选】标识符,无实际意义,选填 {}内容前后不能有空格和换行
music 【可选】音乐,写法注意规范,以空格隔开每个项。 /
music.service 【必选】music第一项数据,音乐服务商 目前仅支持填写:netease、tencent
music.id 【必选】music第二项数据,音乐id 仅可以是封面id/单曲id/歌单id
bilibili 【可选】bilibili,写法注意规范,以空格隔开每个项。 /
bilibili.link 【必选】bilibili第一项数据,bilibili视频链接 必须是b站带BV号的视频链接
bilibili.autoplay 【可选】bilibili第二项布尔值,bilibili视频是否自动播放。默认不自动播放 如需自动播放,请填写true

关于更多写法问题可以访问iCat - Memos查看

即刻Mini

上面已经集成了即刻mini的js操作,只需要在配置文件里,将mini.enable设置为true即可。

  • 新增[主题目录]/layout/includes/mixins/indexPostUI.pug页面内容。
1
2
3
4
  #recent-posts.recent-posts.nc
+ if theme.essay.enable && theme.essay.mini.enable
+ include ./essay_mini.pug
.recent-post-items
  • 创建[主题目录]/layout/includes/mixins/essay_mini.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
- const { strip, link } = theme.essay.mini

.essay-mini(onclick=`pjax.loadUrl('${link}')`)
i.MeuiCat.icon-bblogo(title="即刻短文" style="font-size: 2.5rem")
.swiper-container#essay
.swiper-wrapper#essay-mini
case theme.essay.mode
when 'local'
- const essaydata = site.data.essay
if essaydata && essaydata.essay_list.length > 0
each item, i in essaydata.essay_list.slice(0, strip)
.li-style.swiper-slide
| #{item.content}
if item.image
| 【图片】
else if item.aplayer
| 【音乐】
else if item.video || item.bilibili
| 【视频】
when 'json'
.li-style.essay-loading(style="text-align: center") 正在加载...
script.
async function essayFormat(data) {
const list = data[0].essay_list.slice(0, GLOBAL_CONFIG.essay.strip).map(item => {
const type = item.image ? '【图片】' : item.aplayer ? '【音乐】' : item.video ? '【视频】' : ''
return `<div class="li-style swiper-slide">${item.content + type}</div>`
})
return list.join(' ')
}
when 'memos'
.li-style.essay-loading(style="text-align: center") 正在加载...
script.
async function essayFormat(data) {
const list = data.slice(0, GLOBAL_CONFIG.essay.strip).map(item => {
let data = item.content, content = data.replace(/#(.*?)\s|\n/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '').replace(/(?<!\!)\[(.*?)\]\((.*?)\)/g, '').trim()
const type = data.match(/\!\[(.*?)\]\((.*?)\)/g) ? '【图片】' : data.match(/{\s*music\s*(.*?)\s*(.*?)\s*}/g) ? '【音乐】' : data.match(/{\s*player\s*(.*)\s*}/g) || data.match(/{\s*bilibili\s*(.*?)\s*}/g) ? '【视频】' : ''
return `<div class="li-style swiper-slide">${content + type}</div>`
})
return list.join(' ')
}
i.MeuiCat.icon-bb-btn-s-line(title="查看全文")
  • 在上面创建过的[主题目录]/source/css/_page/essay.styl样式文件,新增以下内容。
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
    #bber-tips
display flex
justify-content center
margin-bottom 2rem
padding-top 2rem
color var(--icat-secondtext)

+ if hexo-config('essay.mini.enable')
+ .essay-mini
+ display: flex
+ align-items: center
+ padding: .5rem 1rem
+ height: 50px
+ gap: 1rem
+ @extend .cardHovers
+ if hexo-config('enter_transitions')
+ animation: slide-in 0.6s 0.4s backwards
+
+ #essay
+ width: 100%
+ overflow: hidden
+
+ #essay-mini
+ display: flex
+ flex-direction: column
+ width: 100%
+ height: 25px
+ line-height: 25px
+ will-change: transform
+
+ .li-style
+ margin: auto
+ width: auto
+ max-width: 100%
+ height: 25px
+ font-weight: 700
+ text-align: center
+ overflow: hidden
+ text-overflow: ellipsis
+ white-space: nowrap
+
+ i, .li-style
+ transition .3s
+ cursor: pointer
+
+ &:hover
+ color: var(--icat-theme)
  • _config.butterfly.yml主题配置文件中inject下的headbottom分别引入swiper-bundle.min.css以及swiper-bundle.min.js
1
2
3
4
5
6
7
8
9
  ···

inject:
head:
- <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.6/swiper-bundle.min.js"></script>
bottom:
- <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.6/swiper-bundle.min.js"></script>

···

Meting说明

如遇到音乐模块无法显示,请将查看meting的js资源文件链接是否为butterfly资源。

如果为butterfly,请将链接改为第三方meting最新资源链接。

譬如:
https://unpkg.com/meting@2.0.1/dist/Meting.min.js
https://cdn.staticfile.net/meting/2.0.1/Meting.min.js

以及检查主题配置是否已经开启aplayerInject.enable

魔改适配

已适配Solitude主题,具体魔改教程可前往下方文章查看

引用站外地址,注意辨别

Solitude魔改教程:动态即刻短文

属于私人的叨叨池,畅所欲言;多种部署方式的iCat版动态即刻短文

旧版教程

引用站外地址,注意辨别

Butterfly的魔改教程:即刻短文页

属于私人的叨叨池,畅所欲言;多种部署方式的iCat版动静态即刻短文

更新历史

  • 240423 更新:三端功能全适配;优化使用体验,异步化处理;修复一些已知问题

  • 240411 更新:新增置顶功能;修复Memos版本时区错误、多余转义符等问题

  • 230808 更新:新增适配Memos动态部署功能

  • 230804 更新:新增显示短文数量的设置功能

  • 230802 更新:修复JSON加载导致的音乐功能错误;修复JSON载入导致时间戳混乱

  • 230731 更新:新增静态部署版的视频说,适配bilibili以及video链接

  • 250103 更新:显著优化新逻辑,减少渲染时间以及报错率

Butterfly的魔改教程:即刻短文页

此文章版权归 MeuiCat 所有,完整转载,请注明来源!