发布于 

【hexo专栏】hexo文章扩展组件如何写

背景

在使用hexo写博客的时候,有时候会遇到特殊的需求,举例比如平常我们写文章运行一个命令,用markdown的普通的代码片段,如下效果:

1
docker run -itd ubuntu bash

但是我们假设想要实现,用户只需要点击一下就能拷贝的能力,那么怎么来实现呢? 效果如下:

img

解决办法

其实hexo提供了一种叫 tag 的能力,能让用户来定制化一些语法,来实现这种需求:

官方文档:

使用方法

语法

1
2
3
hexo.extend.tag.register(name, function(args, content){
// ...
}, options);

定义语法

我们假设我们的markdown文件里面使用:

1
2
3
<% copy %>
docker run -itd ubuntu bash
<% endcopy>

然后就能在文章渲染的时候就变成我们第一节的效果:

img

开发Tag

根据hexo的API,我们如下编码:

1
2
3
4
hexo.extend.tag.register('copy', (args, content) => {
console.log(`content:`, content)
return `<div style='color: red'>${content}</div>`
}, { ends: true })

使用这个Tag

在一篇文章中,我们用上面那个语法:

1
2
3
<% copy %>
docker run -itd ubuntu bash1
<% endcopy>

然后效果如下:

img

符合预期。

迭代这个tag指令

1
2
3
4
5
6
7
hexo.extend.tag.register('copy', (args, content) => {
console.log(`content:`, content)
return `<div style='color: red'>
<input id="copy-item" value="${content}" />&nbsp;&nbsp;
<button onClick="(()=>{var t = document.getElementById('copy-item'); t.select(); document.execCommand('Copy'); alert('copy success!');})()">Copy</button>
</div>`
}, { ends: true })

我们创建了一个input,然后右边加了一个Copy 按钮,当点击的时候,使用document.getElementById('copy-item'),然后调用select方法,最后执行document.execCommand('Copy')

问题修复

我们上面由于input的id固定死了,相当于我们一篇文章,可能有多个这个内容,所以我们不能写死。

例如文章里面:

1
2
3
4
5
6
7
<% copy %>
command1
<% endcopy>

<% copy %>
commmand2
<% endcopy>

所以我们加一个copyIndex,然后代码如下:

1
2
3
4
5
6
7
8
9
let copyIndex = 0;
hexo.extend.tag.register('copy', (args, content) => {
console.log(`content:`, content)
copyIndex++;
return `<div style='color: red'>
<input id="copy-item-${copyIndex}" readonly value="${content}" />&nbsp;&nbsp;
<button onClick="(()=>{var t = document.getElementById('copy-item-${copyIndex}'); t.select(); document.execCommand('Copy'); alert('copy success!');})()">Copy</button>
</div>`
}, { ends: true })

加些参数

假设我们想要加一下width这种参数:

1
2
3
<% copy width:500px %>
commmand2
<% endcopy>

那我们可以通过:

1
2
3
4
5
6
7
8
9
10
11
12
13
let copyIndex = 0;
hexo.extend.tag.register('copy', (args, content) => {
args = ctx.args.map(args, ['width'])
if(args.width){
console.log("width: " + args.width); // 这个我们可以放到css中
}
console.log(`content:`, content) // 调试用
copyIndex++;
return `<div style='color: red'>
<input id="copy-item-${copyIndex}" readonly value="${content}" />&nbsp;&nbsp;
<button onClick="(()=>{var t = document.getElementById('copy-item-${copyIndex}'); t.select(); document.execCommand('Copy'); alert('copy success!');})()">Copy</button>
</div>`
}, { ends: true })

样式调节&交互调节

最后调节一下CSS样式&友好提示,最终效果如下:

img

Hexo专栏

目前 Hexo 系列形成了一个小专栏,欢迎读者继续阅读: Hexo专栏地址


如果你有什么意见和建议,可以点击: 反馈地址 进行反馈。