当前位置: 首页 > news >正文

从零构建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是比较明确的,我使用过bootstrapvuetifyant design等前端组件库,
学习一个新的CSS库应该不会太难。而关于hugo主题相关技术,目前已知的是需要golang的html/template
的一些语法知识,剩下的可以在过程中查阅官方文档。

最终我参考一些已有的主题,以及tailwindcss的示例站点,画了简单的页面布局图,
包含logo、导航菜单、多语言切换、黑色主题切换、文章列表、术语展示块、底部社交媒体链接、底部版权声明等

theme prototype

基于原型图,梳理了主要的功能

  • 基础功能:导航及菜单,列表页,文章页面,右侧分类列表以及分类的列表页、详情页
  • 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 basic example site

至此我们有了简单的可以运行的初始主题和示例站点,后面我将基于该原始主题进行扩展和改写。

相关文章:

从零构建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中如何定义父子组件&#xff0c;由子组件给父组件传值 核心代码 如何使用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快&#xff1f; Spa…...

PCIE Order Set

1 Training Sequence Training Sequence是由Order Set(OS) 组成&#xff0c;它们主要是用于bit aligment&#xff0c;symbol aligment&#xff0c;交换物理层的参数。当data_rate 2.5GT or 5GT 它们不会被扰码(scramble)&#xff0c;当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项目。

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

【Flink状态管理(二)各状态初始化入口】状态初始化流程详解与源码剖析

文章目录 1. 状态初始化总流程梳理2.创建StreamOperatorStateContext3. StateInitializationContext的接口设计。4. 状态初始化举例&#xff1a;UDF状态初始化 在TaskManager中启动Task线程后&#xff0c;会调用StreamTask.invoke()方法触发当前Task中算子的执行&#xff0c;在…...

python+flask人口普查数据的应用研究及实现django

作为一款人口普查数据的应用研究及实现&#xff0c;面向的是大多数学者&#xff0c;软件的界面设计简洁清晰&#xff0c;用户可轻松掌握使用技巧。在调查之后&#xff0c;获得用户以下需求&#xff1a; &#xff08;1&#xff09;用户注册登录后&#xff0c;可进入系统解锁更多…...

C语言:函数

C语言&#xff1a;函数 函数的概念库函数自定义函数实参与形参return语句数组做参数声明与定义externstatic 嵌套调用 函数的概念 在C语言中&#xff0c;存在一个函数的概念&#xff0c;有人也将其翻译为子程序。 在数学中&#xff0c;函数是一个完成特定功能的公式&#xff0…...

jmeter-问题一:关于线程组,线程数,用户数详解

文章目录 jmeter参数介绍1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 场景一&#xff1a;当你的线程组中线程数为1,循环为1场景二&#xff1a;当你的线程组中线程数为2&#xff0c;循环为1场景三&#xff1a;当你的线程组中线程数为1&#xff…...

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 进行测试 附&#xff1a;ConfigurationProperties 注解的介绍及使用 一、什么是 SDK 1. 定义&#xff1a;软件开发工具包 Software Development Kit 2. 用于开发特定软件或应用程序的工…...

CSS transition(过渡效果)详解

CSS过渡效果&#xff08;Transition&#xff09;是一种在CSS3中引入的动画效果&#xff0c;它允许开发者在元素状态变化时&#xff08;如鼠标悬停、类更改等&#xff09;平滑地改变CSS属性值&#xff0c;从而创建出平滑的动画效果。过渡效果可以应用于多种CSS属性&#xff0c;如…...

Android13多媒体框架概览

Android13多媒体框架概览 Android 多媒体框架 Android 多媒体框架旨在为 Java 服务提供可靠的接口。它是一个系统&#xff0c;包括多媒体应用程序、框架、OpenCore 引擎、音频/视频/输入的硬件设备&#xff0c;输出设备以及一些核心动态库&#xff0c;比如 libmedia、libmedi…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...