Hugo Diary主题修改记录
Hugo Diary 主题修改记录。

前言

Hugo Diary 主题简约美观,但是一些细节不符合自己的要求,因此稍作调整并加以记录,修改的内容包括如下:

  • 正文行距调整
  • 表格显示优化
  • 目录优化
  • 滚动条美化
  • 代码块添加 Mac 红绿灯色块
  • 代码块添加复制按钮
  • 代码块添加语言显示
  • 字体修改
  • 首页文章列表布局调整

最终效果如下:

desktop

mobile

准备工作

主题没有 custom.scss 文件,自定义方式可以将 ~/themes/diary/assets/scss/journal.scss 文件复制到站点根目录下 ~/assets/scss 中,在其中直接更改,也可以复制后,在末尾添加 custom.scss 引用,然后在自定义文件中修改,这里采用第二种方式,文中 ~ 均代表博客根目录。

  1. 复制 journal.scss 文件到站点根目录下。
  2. 创建两个文件 custom.scss 用来放置自定义样式。
  3. 在复制的 ~/assets/scss/journal.scss 末尾添加代码引用自定义样式:
1@import "custom"

细节调整

整体细节调整如下:

  • 正文的行间距稍微扩大
  • 优化表格显示
  • 不同目录层级使用不同的列表标记
  • 目录背景色、阴影修改
  • 主页背景色修改 在 custom.scss 添加下面的代码:
 1// 主页背景色修改
 2body, .stream-container .post-list-container {
 3  background: #FCFAF3;
 4}
 5// 调整正文部分的行间距
 6p, li, body {
 7  line-height: 1.8;  // 根据需求调整此值
 8}
 9// 表格优化
10table{
11  display: table;
12  width: 100%;
13  empty-cells: show;
14}
15table th{
16  border: 1px solid #eee;
17  padding: 6px 12px;
18  background-color: lighten($color-accent, 35%);
19  body.night & {
20    background-color: lighten($color-accent, 10%);
21  }
22  width: 400px;
23}
24table td{
25  border: 1px solid #eee;
26  padding: 6px 12px;
27  width: 400px;
28}
29// 目录样式修改
30.toc{
31  background: #FFFFFF;
32  box-shadow:  0 2px 10px rgba(0, 0, 0, 0.1);
33}
34// 目录标题
35.toc-title {
36  font-size: large;
37    text-align: left;
38    font-weight: bold;
39    color: #4d1e01;
40    border-bottom: 1px solid $color-accent;
41}
42// 不同目录层级使用不同的列表标记
43.toc ul ul {
44  list-style-type: decimal;
45}
46
47.toc ul ul ul {
48  list-style-type: none;
49  padding-left: 10px;
50  margin-left: 5px;
51  border-left: 1px solid darkgrey;
52}
53
54.toc ul ul ul ul {
55  list-style-type: none;
56}
57// 不同目录层级使用不同的列表标记
58.toc ul ul {
59  list-style-type: decimal;
60}
61.toc ul ul ul {
62  list-style-type: disc;
63}
64.toc ul ul ul ul {
65  list-style-type: circle;
66}

滚动条美化

将滚动条滑块颜色改成主题强调色,并更改透明度,在 custom.scss 添加下面的代码:

 1// 全局自定义滚动条样式
 2* {
 3  &::-webkit-scrollbar {
 4    width: 8px; // 滚动条宽度
 5    height: 8px; // 滚动条高度
 6  }
 7
 8  &::-webkit-scrollbar-track {
 9    background: transparent; // 滚动条轨道背景色
10    border-radius: 5px;
11  }
12
13  &::-webkit-scrollbar-thumb {
14    background: rgba($color-accent, 0.1); // 滚动条滑块颜色
15    border-radius: 5px;
16  }
17
18  &::-webkit-scrollbar-thumb:hover {
19    background: rgba($color-accent, 0.5); // 滚动条滑块悬停颜色
20  }
21}

上述代码 background 的值是主题内置变量强调色的值,如果要应用于其他主题,可以将对应的值修改一下。

标签微调

分类页和标签页标签微调,缩小圆角大小,更改背景色,并去除边线。 在 custom.scss 中添加下面的代码:

 1// 标签样式更改
 2.rounded-pill{
 3  background: lighten($color-accent, 35%);
 4  border-radius: 10px !important;
 5  border: none;
 6  color: #000;
 7  &:hover{
 8    background: lighten($color-accent, 20%);
 9  }
10  body.night & {
11    background: #555;
12    color: black;
13    &:hover{
14      background: lighten($color-accent, 20%);
15    }
16  }
17}

代码块优化

代码块做了如下优化:

  • 右上角添加复制代码块按钮
  • 中间添加代码块语言显示
  • 左上角添加 MAC 红绿灯样式
  • 添加代码块折叠功能,代码块默认高度 300px ,超出显示按钮控制折叠展开

首先在 ~/layouts/partials/extended_head.html 中引入一个 js 文件:

1<script src="{{ "/js/codeblock-enhancements.js" | relURL }}" defer></script>

然后新建 ~/static/js/codeblock-enhancements.js 文件,写入代码:

  1document.addEventListener('DOMContentLoaded', function() {
  2  const codeBlocks = document.querySelectorAll('.highlight');
  3
  4  codeBlocks.forEach(function(highlight) {
  5    // 创建横条
  6    const toolbar = document.createElement('div');
  7    toolbar.className = 'code-toolbar';
  8    highlight.insertBefore(toolbar, highlight.firstChild);
  9
 10    // 添加 Mac 风格圆点
 11    const macDots = document.createElement('div');
 12    macDots.className = 'mac-dots';
 13    toolbar.appendChild(macDots);
 14
 15    // 检测语言
 16    let language = '';
 17    const possibleElements = [
 18      highlight,
 19      highlight.querySelector('code'),
 20      highlight.querySelector('pre > code'),
 21      highlight.querySelector('pre'),
 22      highlight.querySelector('td:nth-child(2) code')
 23    ];
 24
 25    for (const element of possibleElements) {
 26      if (element && element.className) {
 27        const elementLanguageClass = element.className.split(' ').find(cls => cls.startsWith('language-'));
 28        if (elementLanguageClass) {
 29          language = elementLanguageClass.replace('language-', '');
 30          break;
 31        }
 32      }
 33    }
 34
 35    // 添加语言显示
 36    if (language) {
 37      const languageDisplay = document.createElement('span');
 38      languageDisplay.className = 'language-display';
 39      languageDisplay.textContent = language;
 40      toolbar.appendChild(languageDisplay);
 41    }
 42
 43    // 添加复制按钮
 44    const copyButton = document.createElement('button');
 45    copyButton.className = 'copy-button';
 46    copyButton.innerHTML = '📋';
 47    copyButton.title = '复制代码';
 48    toolbar.appendChild(copyButton);
 49
 50    copyButton.addEventListener('click', function() {
 51      let codeText;
 52      const table = highlight.querySelector('table');
 53      if (table) {
 54        // 有行号的情况
 55        codeText = Array.from(table.querySelectorAll('td:last-child'))
 56          .map(td => td.textContent.replace(/\n$/, ''))  // 移除每行末尾的换行符
 57          .join('\n');
 58      } else {
 59        // 没有行号的情况
 60        const pre = highlight.querySelector('pre');
 61        codeText = pre.textContent;
 62      }
 63
 64      // 移除开头和结尾的空白字符,并确保只有一个换行符
 65      codeText = codeText.trim().replace(/\n+/g, '\n');
 66
 67      navigator.clipboard.writeText(codeText).then(function() {
 68        copyButton.innerHTML = '✅';
 69        setTimeout(function() {
 70          copyButton.innerHTML = '📋';
 71        }, 2000);
 72      }, function() {
 73        copyButton.innerHTML = '❌';
 74      });
 75    });
 76
 77    // 添加折叠功能
 78    if (highlight.offsetHeight > 300) {
 79      highlight.classList.add('collapsible');
 80      const expandButton = document.createElement('button');
 81      expandButton.className = 'expand-button';
 82      expandButton.innerHTML = '▼';
 83      highlight.appendChild(expandButton);
 84
 85      expandButton.addEventListener('click', function() {
 86        highlight.classList.toggle('expanded');
 87        expandButton.innerHTML = highlight.classList.contains('expanded') ? '▲' : '▼';
 88      });
 89    }
 90
 91    // 调整横条宽度
 92    function adjustToolbarWidth() {
 93      toolbar.style.width = `${highlight.offsetWidth}px`;
 94    }
 95
 96    // 初始调整和窗口大小变化时调整
 97    adjustToolbarWidth();
 98    window.addEventListener('resize', adjustToolbarWidth);
 99  });
100});

然后在 custom.scss 中添加样式代码:

  1// 代码块样式
  2.highlight {
  3  position: relative;
  4  margin-bottom: 1em;
  5  background-color: #2d2d2d;
  6  border-radius: 6px;
  7  overflow: hidden;
  8}
  9
 10.code-toolbar {
 11  display: flex;
 12  align-items: center;
 13  justify-content: space-between;
 14  background-color: #1e1e1e;
 15  padding: 8px 16px;
 16  border-top-left-radius: 6px;
 17  border-top-right-radius: 6px;
 18}
 19
 20.mac-dots {
 21  width: 12px;
 22  height: 12px;
 23  border-radius: 50%;
 24  background: #fc625d;
 25  box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
 26}
 27
 28.language-display {
 29  font-size: 0.9em;
 30  color: #a0a0a0;
 31}
 32
 33.copy-button {
 34  background-color: transparent;
 35  border: none;
 36  cursor: pointer;
 37  font-size: 1.2em;
 38  color: #a0a0a0;
 39  padding: 0;
 40  line-height: 1;
 41
 42  &:hover {
 43    color: #ffffff;
 44  }
 45}
 46
 47.highlight pre {
 48  margin: 0;
 49  padding: 1em;
 50  overflow-x: auto;
 51  border-top-right-radius: 0;
 52  border-top-left-radius: 0;
 53  // background: rgba(46,46,46, 1) !important;
 54  // color: rgba(255,255,255, 1);
 55}
 56
 57.collapsible pre {
 58  max-height: 300px;
 59  overflow-y: hidden;
 60}
 61
 62.collapsible::after {
 63  content: '';
 64  position: absolute;
 65  bottom: 0;
 66  left: 0;
 67  right: 0;
 68  height: 30px;
 69  background: linear-gradient(to bottom, rgba(45,45,45,0), rgba(45,45,45,1));
 70  pointer-events: none;
 71}
 72
 73.collapsible.expanded pre {
 74  max-height: none;
 75}
 76
 77.collapsible.expanded::after {
 78  display: none;
 79}
 80
 81.expand-button {
 82  position: absolute;
 83  bottom: 0;
 84  left: 50%;
 85  transform: translateX(-50%);
 86  padding: 2px 8px;
 87  background-color: transparent;
 88  border: none;
 89  border-top-left-radius: 6px;
 90  border-top-right-radius: 6px;
 91  cursor: pointer;
 92  font-size: 1em;
 93  color: #a0a0a0;
 94
 95  &:hover {
 96    background-color: rgba(255, 255, 255, 0.1);
 97    color: #ffffff;
 98  }
 99}
100
101// 调整 Hugo 行号样式
102.highlight table {
103  width: 100%;
104  border-spacing: 0;
105}
106
107.highlight td {
108  padding: 0;
109}
110
111.highlight .lntd:first-child {
112  width: 10px;
113  user-select: none;
114}
115
116.highlight .lnt {
117  margin-right: 0.4em;
118  padding: 0 0.4em 0 0.4em;
119  color: #7f7f7f;
120}
121
122.highlight .ln {
123  margin-right: 0.4em;
124  padding: 0 0.4em 0 0.4em;
125}
126
127// 确保行号和代码在同一行
128.highlight .lntable {
129  display: table;
130  width: 100%;
131  margin: 0;
132  padding: 0;
133}
134
135.highlight .lntd {
136  display: table-cell;
137  vertical-align: top;
138}

js 代码中第 78 行可以设置代码块的最大高度

更改字体

这里给出两个中文字体样式,一个是霞鹜文楷,一个是鸿蒙字体,英文字体使用 Nunito。英文字体的修改可以找一个不带中文的,然后第一个字体设置为英文字体,第二个设置为中文,字体的地址如下:

首先引入字体 CSS 样式,需要在其他 CSS 样式前引用,所以直接将主题目录下的 ~/themes/diary/layouts/partials/head.html 复制到主题根目录同名文件夹下,然后在 <head> 下引用,二选一直接放到开头:

1// 霞鹜文楷
2<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lxgw-wenkai-screen-webfont@1.1.0/style.css" />
3// 鸿蒙字体
4<link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css" />
5// Nunoti
6<link rel="preconnect" href="https://fonts.googleapis.com">
7<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8<link href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap" rel="stylesheet">

journal.scss 中更改字体设置,选择对应的字体替换:

1$default-font-list: Nunoti, HarmonyOS_Regular, -apple-system, BlinkMacSystemFont,"Segoe UI", Roboto, "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
2$default-font-list: Nunoti, "LXGW WenKai Screen", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";

调整首页文章列表布局

将首页文章列表布局调整为卡片样式,并且根据奇偶数交错显示文章封面图,移动设备仍然将封面图显示在文章信息上方,样式参考 Hexo Butterfly ,在 custom.scsss 中添加如下代码:

  1// 首页文章列表布局调整
  2.stream-container {
  3  .post-list-container {
  4    padding: 20px;
  5
  6    > * {
  7      .post-item-wrapper {
  8        margin: 0 auto 20px;
  9        width: 95%;
 10        max-width: 800px;
 11        border-radius: 10px;
 12        overflow: hidden;
 13        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
 14        transition: transform 0.3s ease, box-shadow 0.3s ease;
 15        background-color: #fff;
 16
 17        &:hover {
 18          transform: translateY(-5px);
 19          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
 20        }
 21
 22        .post-item {
 23          margin: 0;
 24          padding: 0;
 25          display: flex;
 26          align-items: stretch;
 27          border-bottom: none;
 28
 29          .post-item-image-wrapper {
 30            flex: 0 0 35%;
 31            max-width: 280px;
 32            margin: 0;
 33            overflow: hidden;
 34
 35            .post-item-image {
 36              width: 100%;
 37              height: 100%;
 38              object-fit: cover;
 39              transition: transform 0.3s ease;
 40            }
 41          }
 42
 43          &:hover {
 44            .post-item-image {
 45              transform: scale(1.05);
 46            }
 47          }
 48
 49          .post-item-info-wrapper {
 50            flex: 1;
 51            padding: 20px;
 52            display: flex;
 53            flex-direction: column;
 54            justify-content: center;
 55
 56            .post-item-title {
 57              margin-bottom: 10px;
 58              font-size: 1.3em;
 59            }
 60
 61            .post-item-summary {
 62              margin-bottom: 15px;
 63              display: -webkit-box;
 64              -webkit-line-clamp: 3;
 65              -webkit-box-orient: vertical;
 66              overflow: hidden;
 67            }
 68          }
 69        }
 70      }
 71
 72      // 奇数项文章,图片在左边(默认情况)
 73      &:nth-child(odd) {
 74        .post-item-wrapper .post-item {
 75          flex-direction: row;
 76        }
 77      }
 78
 79      // 偶数项文章,图片在右边
 80      &:nth-child(even) {
 81        .post-item-wrapper .post-item {
 82          flex-direction: row-reverse;
 83
 84          .post-item-image-wrapper {
 85            margin-left: 0;
 86            margin-right: 0;
 87          }
 88        }
 89      }
 90    }
 91  }
 92}
 93
 94// 暗色模式调整
 95body.night {
 96  .stream-container {
 97    .post-list-container > * {
 98      .post-item-wrapper {
 99        background-color: #2d2d2d;
100        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
101
102        &:hover {
103          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);
104        }
105
106        .post-item {
107          border-bottom: none;
108        }
109      }
110    }
111  }
112}
113
114// 针对移动设备的调整
115@media screen and (max-width: $single-column-max-width) {
116  .stream-container {
117    .post-list-container {
118      padding: 10px;
119
120      > * {
121        .post-item-wrapper {
122          width: 100%;
123          margin-bottom: 15px;
124
125          .post-item {
126            flex-direction: column !important; // 强制垂直布局
127
128            .post-item-image-wrapper {
129              flex: none;
130              max-width: none;
131              width: 100%;
132              height: 200px;
133              order: -1; // 确保图片始终在上方
134            }
135
136            .post-item-info-wrapper {
137              padding: 15px;
138
139              .post-item-title {
140                font-size: 1.2em;
141              }
142            }
143          }
144        }
145      }
146    }
147  }
148}

网站访问量

主题自带了谷歌分析和微软的 Clarity,但是还是推荐使用其他的服务。这里可以使用 Umami ,后台能看到访问的详细记录,搭建方法可以参考访问之前的文章。 前台的展示可以使用不蒜子计数。

Umami

首先在 ~/layouts\partials\extended_head.html 中添加 js 引入:

1{{ if .Site.Params.umami -}}
2<script 
3    defer 
4    src="https://umami.grew.cc/myscript" 
5    data-website-id="b2daf838-b6d4-4783-a157-e2fbe0cc225d"
6    data-domains="blog.grew.cc"
7></script>
8{{- end }}

注释

上述参数可以直接复制 umami 的跟踪代码,可以加一行 data-domains ,设置成自己的域名,这样可以防止本地调试时的访问被统计进去。

最后在站点配置文件中 [params] 下加入配置开关,注意配置格式

1umami = true

不蒜子

这个前台展示可以使用杜老师说建的 API,提高国内访问速度,访问地址:杜老师说自建国内不蒜子 API

首先在 ~/layouts\partials\extended_head.html 中添加 js 引入:

1{{/*  busuanzi统计  */}}
2{{ if .Site.Params.busuanzi -}}
3<script async src="https://npm.elemecdn.com/penndu@1.0.0/bsz.js"></script>
4{{- end }}

然后在页脚添加本站访问量,在文章详情页添加本文访问量,Diary 主题页脚是 copyright.html

将主题目录下的 copyright.htmlsingle.html 复制到站点相同路径下,然后在 copyright.html 中添加:

1{{ if .Site.Params.busuanzi -}}
2<br>
3<span id="busuanzi_container_site_pv">本站总访问量 <span id="busuanzi_value_site_pv"></span> 次</span>&nbsp;
4<span id="busuanzi_container_site_pv">本站总访客数 <span id="busuanzi_value_site_uv"></span> 人</span>
5{{- end }}

single.html59 行,阅读时间配置后面添加:

1{{ if .Site.Params.busuanzi -}}
2<br>
3<span id="busuanzi_container_page_pv">本文阅读量 <span id="busuanzi_value_page_pv"></span> 次</span>&nbsp;
4<span id="busuanzi_container_page_pv">本文访客数 <span id="busuanzi_value_page_uv"></span> 人</span>
5{{- end }}

最后在站点配置文件中 [params] 下添加开关,同 umami 一样:

1busuanzi = true

参考


最后修改于 2024-08-12