在捣鼓自己的主题时,有一些时候会在主题配置文件(或 Hexo 配置文件)中插入大量的 HTML 代码。虽然功能是实现了,但是会导致很多问题:
- 配置文件冗长
- HTML 内容无代码高亮,不方便格式化
- 拓展性
为了解决这个问题,我的想法是通过注册勾子实现主题配置的动态加载。
编写脚本并注册勾子
默认地,Hexo 会在 Hexo 命令执行时加载博客项目 scripts 文件夹下的所有脚本。
请不要在 scripts 文件夹下放置执行不了的非脚本文件。
我们在 scripts 文件夹中编写 dynamic_config.js 脚本:
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
| const fs = require('fs'); const path = require('path');
function loadHtmlToConfig({filePath, configPath, failureMsg}) { try { const fullPath = path.join(hexo.base_dir, filePath);
if (!fs.existsSync(fullPath)) { throw new Error(`文件不存在:${fullPath}`); }
const htmlContent = fs.readFileSync(fullPath, 'utf8');
setNestedConfig(hexo.theme.config, configPath, htmlContent);
hexo.log.debug(`✅ 动态配置加载成功 ${configPath}`); } catch (error) { hexo.log.warn(`⚠️ ${failureMsg}:${error.message},使用主题默认内容`); } }
function setNestedConfig(obj, path, value) { const keys = path.split('.'); const lastKey = keys.pop();
const targetObj = keys.reduce((acc, key) => { if (!acc[key]) acc[key] = {}; return acc[key]; }, obj);
if (targetObj[lastKey]) { targetObj[lastKey] = value; } }
hexo.extend.filter.register('before_generate', () => {
const dynamicConfigList = [ { filePath: 'source/_data/dynamic_configs/announcement.html', configPath: 'aside.card_announcement.content', failureMsg: '读取侧边栏公告HTML文件失败' }, { filePath: 'source/_data/dynamic_configs/footer.html', configPath: 'footer.custom_text', failureMsg: '读取页脚自定义文本HTML文件失败' } ];
dynamicConfigList.forEach(loadHtmlToConfig);
}, 1);
|
根据上面代码的提示,自行修改或拓展勾子函数 hexo.extend.filter.register 即可。比如像第一个 aside 的例子。原本我们在 _config.butterfly.yml 的某项配置为:
1 2 3 4 5 6 7
| aside: card_announcement: enable: true content: | 很长很长很长的内容 ...... 有很多很多行
|
我们可以把这些内容剪切出来放在某一个位置里,比如将内容粘贴到 source/_data/dynamic_configs/announcement.html 文件中即可。 failureMsg 随意写,用于在日志中给出相应的提示。
经测试,这个动态配置甚至可以热更新,HTML 内容修改后会实时反馈到页面中。当然,目前这个脚本还在试用中,如有任何问题,欢迎在评论区进行交流和讨论。
本文参考