从零构建Hugo主题 - I
这是一个系列博客,记录了我从零开始构建Hugo主题https://github.com/tomowang/hugo-theme-tailwind的过程。全系列包括四篇文章,这是第一篇:
- I. 主要介绍我构建Hugo主题的背景,我对主题的功能想法,以及开发环境的搭建
- II. Hugo主题的主要目录结构,需要了解的技术,以及我创建的主题的主体框架
- III. Hugo主题的其他功能,包括黑色主题,响应式设计,多语言,代码高亮,构建管道等
- IV. 该部分描述非代码相关的内容,包括持续集成(CI),如何提交至官方主题站点,以及SEO相关的数据等
背景
我是一名开发者,在过往十多年的开发经历中,我接触到各种技术,如前端、后端、大数据、机器学习等。
当我期望将我的个人开发尝试或者生活经历对外分享的时候,我萌生了构建博客站点的想法。
在我最初的博客选型中,有不少候选项,如WordPress,Hexo,Jekyll等等,最终我选择了hugo静态页面生成的模式,
并且为我的博客站点挑选了一个还不错的域名tomo.dev。
选择hugo的原因很简单,hugo是用golang
开发的,安装和构建速度很快,开源,有着完善社区,
并且有着丰富的官方文档,同时hugo有较多开源主题。当然为自己的站点挑选主题一直是个头疼的事情,
在浏览了官方主题站点中众多的主题后,我最终选择一款名为hello friend
的主题。
hello friend
有着较为简洁的页面结构,不算复杂的代码,并且支持黑白主题切换以及响应式设计,
最终我写下了我的第一篇博客:https://tomo.dev/posts/blog-using-hugo/。
在之后的博客撰写过程中,我在hello friend
主题中加了一些功能,调整了一些页面结构,
比如在底部导航加了我的GitHub地址,调整了部分JavaScript代码并加了一些新的三方JavaScript库。
我的文章都是用中文撰写,博客上线两年后一直没什么流量。在2023下半年的时候,
我开始接触web站点推广方面的工作,如SEO等,于是我想着怎么将我的博客翻译成英文并做些SEO尝试。
但是hello friend
主题本身不支持多语言,且其代码不再维护(不过后来发现有个后继者hello friend ng
)。
同时我脱离前端开发有段时间,了解到tailwindcss
比较火,想跟上前端新趋势的步伐,
于是便萌生了自己构建主题的想法。
功能
构建主题和使用主题是完全两种模式。使用主题时,大部分时候只需要了解简单的配置,熟悉markdown
语法就可以了。
但是构建主题相当于开发一个小型的产品或者插件,我需要回答这样的一些问题:
- 主题的风格和布局是什么的?
- 有哪些功能?
- 需要什么样的技术能力?
- 如何发布、推广并让更多人使用?
我不是产品经理,也不是设计师,但是市面上有不少开源的主题我可以参考。我期望我的主题像hello friend
一样有着简洁的布局,同时尽量少地使用复杂前端技术,并且容易扩展,SEO友好。
关于技术,tailwindcss
是比较明确的,我使用过bootstrap
,vuetify
,ant design
等前端组件库,
学习一个新的CSS库应该不会太难。而关于hugo主题相关技术,目前已知的是需要golang的html/template
的一些语法知识,剩下的可以在过程中查阅官方文档。
最终我参考一些已有的主题,以及tailwindcss
的示例站点,画了简单的页面布局图,
包含logo、导航菜单、多语言切换、黑色主题切换、文章列表、术语展示块、底部社交媒体链接、底部版权声明等
基于原型图,梳理了主要的功能
- 基础功能:导航及菜单,列表页,文章页面,右侧分类列表以及分类的列表页、详情页
- Darkmode - 黑色主题切换
- 响应式设计
- 多语言
- 图片处理
- 底部导航的社交媒体链接
以及其他支撑这些功能以及开源项目的隐藏需求:
- 持续集成
- 文档,配置示例
- lighthouse评分
- 其他
- short code的尝试
- Google Analytics 配置
- 用户评论功能
- Social tag
- 代码块复制功能
然后需要给主题一个名称,浏览了下官方主题列表,最后我选择了hugo-theme-tailwind
。
事实证明好的名字会给项目带来额外的一些曝光和流量。
初始化github仓库,提交了第一个#d833043。
开发环境准备
为了构建新的Hugo主题,我们需要hugo,nodejs。工具的安装不是这系列文章的重点,可以参考一些官方文档:
- hugo - https://gohugo.io/installation/
- nodejs环境 - 我使用的是fnm及pnpm
有了hugo命令,在仓库的目录下执行如下命令:
hugo new theme hugo-theme-tailwind
该命令会在当前目录创建文件夹themes/hugo-theme-tailwind
,我们需要将其移动到我们的仓库中,同时移除主题自带的内容content
目录。
mv themes/hugo-theme-tailwind/* .
rm -rf themes/
rm -rf content
下载官方提供的示例站点内容到主题的exampleSite
目录下
git clone https://github.com/gohugoio/hugoBasicExample.git exampleSite
rm -rf exampleSite/.git
在示例站点的配置文件中添加主题配置:theme = "hugo-theme-tailwind"
,
然后运行命令
hugo server -s exampleSite --gc --themesDir=../..
该命令会启动hugo服务,可以测试最原始的主题展示情况,示例日志输出如下:
Start building sites …| EN
-------------------+-----Pages | 41Paginator pages | 0Non-page files | 0Static files | 2Processed images | 0Aliases | 9Sitemaps | 1Cleaned | 0Built in 13175 ms
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
访问http://localhost:1313/,可以见到如下图的简单页面
至此我们有了简单的可以运行的初始主题和示例站点,后面我将基于该原始主题进行扩展和改写。
相关文章:

从零构建Hugo主题 - I
这是一个系列博客,记录了我从零开始构建Hugo主题https://github.com/tomowang/hugo-theme-tailwind的过程。全系列包括四篇文章,这是第一篇: I. 主要介绍我构建Hugo主题的背景,我对主题的功能想法,以及开发环境的搭建…...

【HarmonyOS应用开发】HTTP数据请求(十四)
文章末尾含相关内容源代码 一、概述 日常生活中我们使用应用程序看新闻、发送消息等,都需要连接到互联网,从服务端获取数据。例如,新闻应用可以从新闻服务器中获取最新的热点新闻,从而给用户打造更加丰富、更加实用的体验。 那么…...
MongoDB聚合: $sortByCount
$sortByCount聚合根据指定表达式的值对输入文档进行分组,然后计算每个不同分组中的文档数。 每个输出文档包含两个字段:一个是包含不同分组值的_id字段,另一个是包含属于该分组或类别的文档数量的计数字段。 文档按计数降序排序。 语法 {…...
FY-SA-20237·8-AI‘sIQ
Translated from the Scientific American, July/August 2023 issue. AI’s IQ ChatGPT aced a test but showed that intelligence cannot be measure by IQ alone. —— By Eka Roivainen 翻译:ChatGPT在一项测试中取得了优异的成绩,但也表明智力不能…...

react将选中文本自动滑动到容器可视区域内
// 自动滚动到可视区域内useEffect(() > {const target ref;const wrapper wrapperRef?.current;if (target && wrapperRef) {const rect target.getBoundingClientRect();const wrapperRect wrapper.getBoundingClientRect();const isVisible rect.bottom &l…...
Rust语言入门小结(第1篇)
Rust是一种新兴编程语言,既有高级语言的风格,又有底层语言级别的性能;是对于实时性、安全性要求高的应用开发的理想语言。 笔者的自学记录,供参考 环境搭建与第一个Rust程序 以Linux环境为例 # 下载并安装 curl --proto https -…...

前端实现支付跳转以及回跳
// 支付地址 const baseURL http://pcapi-xiaotuxian-front-devtest.itheima.net/ const backURL http://127.0.0.1:5173/paycallback const redirectUrl encodeURIComponent(backURL) const payUrl ${baseURL}pay/aliPay?orderId${route.query.id}&redirect${redirec…...
黑豹程序员-封装组件-Vue3 setup方式子组件传值给父组件
需求 封装组件 需要使用到Vue3中如何定义父子组件,由子组件给父组件传值 核心代码 如何使用emits 组件 <template><button click"sendData">点击按钮</button> </template><script setup> import {ref, defineEmits}…...

PySpark(三)RDD持久化、共享变量、Spark内核制度,Spark Shuffle、Spark执行流程
目录 RDD持久化 RDD 的数据是过程数据 RDD 缓存 RDD CheckPoint 共享变量 广播变量 累加器 Spark 内核调度 DAG DAG 的宽窄依赖和阶段划分 内存迭代计算 Spark是怎么做内存计算的? DAG的作用?Stage阶段划分的作用? Spark为什么比MapReduce快? Spa…...

PCIE Order Set
1 Training Sequence Training Sequence是由Order Set(OS) 组成,它们主要是用于bit aligment,symbol aligment,交换物理层的参数。当data_rate 2.5GT or 5GT 它们不会被扰码(scramble),当date_rate 8GT or higher 根据特殊的规则…...
nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析(下)
目录 7. 实现一个UDP健康检测功能7.1 功能定义7.2 定义一个新的健康检测类型7.3 增加udp特定的健康检测需要的配置指令7.3.1 ngx_http_upstream_check_srv_conf_s结构体的扩展7.3.2 check_udp_send的实现7.3.3 check_udp_expect的实现7.3.4 16进制解码代码的实现7.4 ngx_http_u…...

基于SSM的网络在线考试系统(有报告)。Javaee项目。ssm项目。
演示视频: 基于SSM的网络在线考试系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring …...

【Flink状态管理(二)各状态初始化入口】状态初始化流程详解与源码剖析
文章目录 1. 状态初始化总流程梳理2.创建StreamOperatorStateContext3. StateInitializationContext的接口设计。4. 状态初始化举例:UDF状态初始化 在TaskManager中启动Task线程后,会调用StreamTask.invoke()方法触发当前Task中算子的执行,在…...

python+flask人口普查数据的应用研究及实现django
作为一款人口普查数据的应用研究及实现,面向的是大多数学者,软件的界面设计简洁清晰,用户可轻松掌握使用技巧。在调查之后,获得用户以下需求: (1)用户注册登录后,可进入系统解锁更多…...
C语言:函数
C语言:函数 函数的概念库函数自定义函数实参与形参return语句数组做参数声明与定义externstatic 嵌套调用 函数的概念 在C语言中,存在一个函数的概念,有人也将其翻译为子程序。 在数学中,函数是一个完成特定功能的公式࿰…...

jmeter-问题一:关于线程组,线程数,用户数详解
文章目录 jmeter参数介绍1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 场景一:当你的线程组中线程数为1,循环为1场景二:当你的线程组中线程数为2,循环为1场景三:当你的线程组中线程数为1ÿ…...
golang 通过 cgo 调用 C++ 库
思路 将 C 库包装成 C 库 -> golang 通过 cgo 调用 C 库 C 相关文件 目录列表 include/ some.h C 库头文件some_wrapper.h < 用于将 C 库包装成 C 库的头文件 lib/ libsome.a C 库 src/ some_wrapper.cpp < 用于将 C 库包装成 C 库的源码文件 源码示例 some.h…...

使用 IDEA 开发一个简单易用的 SDK
目录 一、什么是 SDK 二、为什么要开发 SDK 三、开发 SDK 的详细步骤 四、导入 SDK 进行测试 附:ConfigurationProperties 注解的介绍及使用 一、什么是 SDK 1. 定义:软件开发工具包 Software Development Kit 2. 用于开发特定软件或应用程序的工…...
CSS transition(过渡效果)详解
CSS过渡效果(Transition)是一种在CSS3中引入的动画效果,它允许开发者在元素状态变化时(如鼠标悬停、类更改等)平滑地改变CSS属性值,从而创建出平滑的动画效果。过渡效果可以应用于多种CSS属性,如…...

Android13多媒体框架概览
Android13多媒体框架概览 Android 多媒体框架 Android 多媒体框架旨在为 Java 服务提供可靠的接口。它是一个系统,包括多媒体应用程序、框架、OpenCore 引擎、音频/视频/输入的硬件设备,输出设备以及一些核心动态库,比如 libmedia、libmedi…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...