从单一到多元:揭秘 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实验一&#…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...