从单一到多元:揭秘 Hexo Diversity 主题的运行原理

揭秘 Hexo Diversity 主题的运行原理
- 一、 引言
- 二、 Diversity 主题
- 2.1 Hexo 控制台命令
- 2.2 Hexo 核心 API
- 2.3 运行原理
- 2.3.1 多主题配置相关
- 2.3.2 多主题执行指令
- 2.4 版本演进
- 2.4.1 V1版本
- 2.4.2 V2版本
- 2.4.2.1 PC 端
- 2.4.2.2 Phone 端
- 2.5 后续展望
- 三、 总结
一、 引言
众所周知,Hexo 是一个快速、简洁且高效的博客框架。 它使用 Markdown 或 其他标记语言 解析文章,在几秒内,即可利用靓丽的主题生成静态网页。
目前 Hexo 拥有 400+ 的主题,使用者可以在众多的主题中进行选择;当然我们也可以使用任何兼容的模板引擎创建自己的主题,从而应用到个人博客中。
不过比较遗憾的是,这么多的美观、强大、可定制的主题之中,我们只能选择其中一个主题来生成自己的静态博客。
笔者在接触 Hexo 之后,也被它众多的主题所吸引,同时也在考虑如何让个人博客可以在众多的主题间切换呢?【小孩子才会选择,大人全都要】。
二、 Diversity 主题
随着接触越多的 Hexo 的核心 API 和源码,一个在多主题中自由切换的 Hexo 主题 应运而生,取名 Diversity,即多样性。
2.1 Hexo 控制台命令
在介绍 Diversity 主题的运行原理之前,我们先来看看 Hexo 的一些关键控制台命令,比如:
hexo generate: 生成静态文件(一般在public目录下)。hexo server:启动服务器。 默认情况下,访问网址为:http://localhost:4000/。hexo clean:清除缓存文件(db.json) 和已生成的静态文件 (一般在public目录下)。
2.2 Hexo 核心 API
翻看官方网站的 核心API概述 ,可以看到一个完整的 Hexo 实例运行流程如下:
- 初始化 :首先,需要新建一个
Hexo实例。 一个新的实例需要两个参数:网站根目录base_dir,以及包含初始化选项的对象。 接着执行init方法后,Hexo 会加载插件及配置文件。
var Hexo = require("hexo");
var hexo = new Hexo(process.cwd(), {});hexo.init().then(function () {// ...
});
-
加载文件 :Hexo 提供了两种方法来加载文件:
load和watch。load用于加载source文件夹中的所有文件以及主题数据。watch执行与load相同的操作,但还会开始连续监视文件更改。 -
执行指令 :任何控制台命令都可以通过在 Hexo 实例上使用
call方法来显式调用。这样的调用需要两个参数:控制台命令的名称和 一个选项参数。不同的控制台命令有不同的选项可用。
hexo.call("generate", {}).then(function () {// ...
});
- 退出 :无论控制台命令完成与否,都应调用
exit方法。 这样 Hexo 就能优雅地退出,并完成保存数据库等重要工作。
hexo.call("generate", args).then(() => hexo1.exit()).catch(err => hexo1.exit(err));
2.3 运行原理
通过上述 Hexo 核心 API 的了解,相信大家已经比较清楚 Hexo 实例的运行流程了。
那 Diversity 主题是如何实现多个主题自由切换的呢?
笔者的想法就是在我们运行Hexo的控制台命令时,可以针对Diversity主题中配置的多主题目录列表的每个主题,都创建一个 Hexo 实例并执行当前指令。
如下是 _config.diversity.yml 中的配置:
# 多主题目录列表
themes: [phase,landscape,light]
# 多主题服务器端口列表
# 不配置,默认从4001开始
#ports: [5000,5001,5002]
这个时候读者可能就要问了,那不同的主题是如何区分处理的呢?
2.3.1 多主题配置相关
不同主题的根配置 _config.xml 需要单独配置,在你的 Hexo 项目根目录,添加 config 目录,为上述多主题列表中的每个主题添加一个对应主题名的配置目录,并在该配置目录下添加对应的 _config.yml 【直接从你原来项目根目录下的 _config.yml 复制一份即可】,形如:
├─config
│ ├─landscape
│ │ ├─_config.yml
│ ├─light
│ │ ├─_config.yml
│ ├─phase
│ │ ├─_config.yml
修改上述各主题配置目录下的 _config.yml,以 landscape 举例:
- url: http://example.com
+ url: http://example.com/landscape- public_dir: public
+ public_dir: public/landscape- theme: other-theme
+ theme: landscape
只要按上述添加好配置,
当运行 generate 指令时,Diversity 主题可以针对不同的主题生成不同的静态页面【例如:landscape 的静态页面就将生成在 public/landscape】。
当运行 server 指令时,Diversity 主题可以针对不同的主题启动不同的Http服务【例如:landscape 的本地地址 http://localhost:4002/landscape】。
另外在你的 Hexo 项目根目录下,我们依旧可以添加不同主题独立的 _config.[theme].yml 文件,更多了解请查看官方《配置》

2.3.2 多主题执行指令
在 Diversity 主题的 script 目录新增 index.js,用于处理多主题执行指令。
主题目录中的
script目录为脚本文件夹。 在启动时,Hexo 会加载此文件夹内的 JavaScript 文件。 请参见 plugins. 以获得更多信息。
我们来看看核心的处理逻辑:
- 首先,从Hexo的主题配置中获取多主题目录列表;
const themeConfig = hexo.config.theme_config;
const themes = themeConfig.themes;
- 然后,获取hexo执行的控制台命令;
// 获取控制台命令的别名
const { alias } = hexo.extend.console;
// 获取hexo执行命令
const cmd = alias[hexo.env.cmd];
// 当前项目根目录
const cwd = process.cwd();
hexo.log.info('Cmd =', cmd);themeConfig.cmd = cmd;
- 最后,遍历多主题目录列表
themes,针对每个主题创建一个 Hexo 实例并执行当前的控制台命令。每个主题都有对应的_config.yml,可从上面的介绍了解到,位于项目根目录的config目录中的主题名目录下。
// 多主题目录配置的数组索引
let index = 0;
// 循环处理配置的多主题列表
themes.forEach(function(theme) {themeConfig.index = index;if (Util.isMatchCmd(cmd)) {hexo.log.info('Theme', (index + 1), '=', theme);const {args} = hexo.env;const fileName = '_config.yml';args.output = path_1.join(cwd, 'config', theme);if (!Util.isExist(args.output, fileName)) {hexo.log.error('Please add the [' + fileName + '] file in [' + args.output + '].');return;}args.config = path_1.join(args.output, fileName);const hexo1 = new Hexo(cwd, args);require('./config')(hexo1, themeConfig);hexo1.init().then(() => require('./helper')(hexo1, themeName)).then(() => require('./generator')(hexo1, themeName)).then(() => hexo1.call(cmd, args)).then(() => hexo1.exit()).catch(err => hexo1.exit(err));} // 下一个主题index++;
});
2.4 版本演进
2.4.1 V1版本
主题选择页:

鼠标左右拖拽滚动展示:

鼠标滚轮前后滚动展示:

已配置的主题,鼠标悬停自动翻转展示详情:

主题直达按钮,用于跳转对应主题博客页面:

主题来源按钮,用于跳转对应的主题开源项目:

2.4.2 V2版本
2.4.2.1 PC 端
个人博客页【尚未设置过默认主题】:

主题选择页:

设置默认主题【当然V1 版本中的拖动和滚动展示同样支持,这里就不展示了】:

取消默认主题,并重新设置新的默认主题:

已有默认主题,直接重新设置默认主题:

2.4.2.2 Phone 端
个人博客页【尚未设置过默认主题】:

主题选择页:

左右箭头切换滚动展示,左滑右滑切换滚动展示:

设置默认主题:

2.5 后续展望
本篇博文截止,Diversity 主题的版本是 2.2.6。
后续该项目将会持续更新中,包括但不限于首页,友链,留言,关于等等。
三、 总结
Diversity 主题 解决了 Hexo 站点只能在线接入一个主题运行的痛点,使用者可以在配置的主题中自由切换展示。
如果你也有兴趣,不妨来试试接入 Diversity 吧!!!
有任何的问题,欢迎来评论区和我讨论!
相关文章:
从单一到多元:揭秘 Hexo Diversity 主题的运行原理
揭秘 Hexo Diversity 主题的运行原理 一、 引言二、 Diversity 主题2.1 Hexo 控制台命令2.2 Hexo 核心 API2.3 运行原理2.3.1 多主题配置相关2.3.2 多主题执行指令 2.4 版本演进2.4.1 V1版本2.4.2 V2版本2.4.2.1 PC 端2.4.2.2 Phone 端 2.5 后续展望 三、 总结 一、 引言 众所…...
软考中级(系统集成项目管理工程师)案例分析计算题-笔记
案例分析计算题必拿分!! 1.成本进度管理 初中数学题,整了一堆缩写,容易给人绕晕 知道英文全称后就好理解了名词汇总: 英文缩写英文全称含义公式PVPlanned Value (计划值)按照计划到当前时间点需要花费的钱根据题目自…...
Docker打包自己项目推到Docker hub仓库(windows10)
一、启用Hyper-V和容器特性 1.应用和功能 2.点击程序和功能 3.启用或关闭Windows功能 4.开启Hyper-V 和 容器特性 记得重启生效!!! 二、安装WSL2:写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/143057041 三…...
CesiumJS 案例 P20:监听鼠标滚轮、监听鼠标左键按下与松开、监听鼠标右键按下与松开、监听鼠标左击落点
CesiumJS CesiumJS 是一个开源的 JavaScript 库,它用于在网页中创建和控制 3D 地球仪(地图) CesiumJS 官网:https://www.cesium.com/ CesiumJS 下载地址:https://www.cesium.com/platform/cesiumjs/ CesiumJS API 文…...
如何使用Web-Check和cpolar实现安全的远程网站监测与管理
文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本期给大家分享一个网站检测工具Web-Check,能帮你全面了解网…...
随机生成100组N个数并对比,C++,python,matlab,pair,std::piecewise_construct
随机生成100组N个数,数的范围是1到35,并检查是否包含目标数组的数字 python版本 import numpy as np def count_groups_containing_obj(N, obj):# 随机生成100组N个数,数的范围是1到35groups np.random.randint(1, 36, size(1000, N))#pri…...
python爬虫获取数据后的数据提取
文章目录 python爬虫中的数据提取1.Json格式数据的数据提取2.Html格式数据提取之bs4解析器如何使用快速使用对象的种类Tagname和attributes属性NavigableString(字符串)BeautifulSoupComment 子节点.contents.children.descendants 父节点.parent.parents 节点内容.string.stri…...
前段(vue)
目录 跨域是什么? SprinBoot跨域的三种解决方法 JavaScript 有 8 种数据类型, 金额的用什么类型。 前段 区别 JQuery使用$.ajax()实现异步请求 Vue 父子组件间的三种通信方式 Vue2 和 Vue3 存在多方面的区别。 跨域是什么? 跨域是指…...
pairwise算法之rank svm
众所周知,point-wise/pair-wise/list-wise是机器学习领域中重要的几种建模方法。比如,最常见的分类算法使用了point-wise,即一条样本对应一个label(0/1),根据多条正负样本,使用交叉熵(cross entropy&#x…...
SAP RFC 用户安全授权
一、SAP 通讯用户 对于RFC接口的用户,使用五种用户类型之一的“通讯”类型,这种类型的用户没有登陆SAPGUI的权限。 二、对调用的RFC授权 在通讯用户内部,权限对象:S_RFC中,限制进一步可以调用的RFC函数授权ÿ…...
记录新建wordpress站的实践踩坑:wordpress 上传源码新建站因权限问题导致无法访问、配置新站建站向导以及插件主题上传配置的解决办法
官方文档:How to install WordPress – Advanced Administration Handbook | Developer.WordPress.org 但是没写权限问题,可以下载到 wordpress官方包。 把下载的wordpresscn的包解压并上传到服务器目录下,但是因为是root上传导致了权限问题…...
为啥学习数据结构和算法
基础知识就像是一座大楼的地基,它决定了我们的技术高度。而要想快速做出点事情,前提条件一定是基础能力过硬,“内功”要到位。 想要通关大厂面试,千万别让数据结构和算法拖了后腿 我们学任何知识都是为了“用”的,是为…...
Java - 免费图文识别_Java_免费_图片转文字_文字识别_spring ai_spring ai alibaba
本文主要是介绍借助阿里云免费的大模型额度来做高质量的图转文识别,图片转文字,或者文字识别都可以使用,比传统的OCR模式要直接和高效很多 。 本文使用的技术是spring ai qwen vl 。 Qwen vl有 100万Token 免费额度,可以用来免费…...
《JVM第6课》本地方法栈
文章目录 1 什么是本地方法1.1 本地方法的好处1.2 声明本地方法1.3 实现本地方法1. 生成头文件2. 编写C语言实现3. 编译C代码4. 运行Java程序 1.4 使用JNA1.5 总结 2 本地方法栈2.1 特点2.2 本地方法栈与Java虚拟机栈的区别2.3 本地方法栈的工作流程2.4 总结 无痛快速学习入门J…...
3.1 快速启动Flink集群
文章目录 1. 环境配置2. 本地启动3. 集群启动4. 向集群提交作业4.1 提交作业概述4.2 添加打包插件4.3 将项目打包4.4 在Web UI上提交作业4.5 命令行提交作业 在本实战中,我们将快速启动Apache Flink 1.13.0集群,并在Hadoop集群环境中提交作业。首先&…...
如何设计一个毫秒级的接口?
设计一个毫秒级的接口需要考虑多个方面,包括网络延迟、服务器性能、代码效率、数据库查询优化等。以下是一些建议,帮助你设计一个毫秒级的接口: 网络优化: 使用HTTP/2或更高版本,以减少连接建立和传输的开销。尽可能减…...
从语义实施工程师到大数据开发工程师的职业转型
在信息技术行业,随着数据驱动决策的流行和企业对大数据需求的急剧增加,越来越多的专业人士开始考虑将他们的技能转移到大数据领域。本文将探讨如何从一个语义实施工程师转变为一个大数据开发工程师。两者虽然都与数据密切相关,但在技术重点和…...
关联容器笔记
关联容器总结 有序关联容器 键值的顺序自动排序,键值必须支持 < 操作符 底层数据结构 使用平衡树,比如(红黑树)增删查的平均时间复杂度接近 O(logn) 种类 std::set:集合,包含唯一的键元素。 std…...
在阿里云快速启动Umami玩转网页分析
阿里云计算巢提供了Umami快速部署能力,使用者不需要自己下载代码,不需要自己安装复杂的依赖,不需要了解底层技术,只需要在控制台图形界面点击几下鼠标就可以快速部署并启动Umami,非技术同学也能轻松搞定。 什么是Umam…...
Linux练习作业
1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器,对主dns服务器进行数据备份 环境准备 主从服务器都需要进行的操作#关闭防火墙、SELinnux systemctl stop firewalld setenforce 0#软件安装 yum install bind -y实验一&#…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
