Update Notes

恭喜你找到了隐藏页面:本站更新笔记。
这里不仅有版本更新记录,还会有一些折腾的笔记和教学。
如果能帮到你,我会很高兴!
(站长不是程序员,没有任何程序基础,纯属素人瞎摸,随时欢迎提出意见或建议并帮助我…!)

当前部署在

Netlify

当前使用的工具

Hugo v0.88.1+extended darwin/amd64

更新笔记

5.6
  • 增加代码高亮,但是代码复制按钮怎么都加不上,chatGPT都帮不了我
  • 修正一些本页笔记中的代码
  • 过了一下W3C,没毛病,很爽
  • 增加了适配bilibili的短代码视频插入
  • 增加RSS,可以在侧边栏或干脆点此订阅
    • 顺便更改本页为index.md文章页,方便RSS读取
    • 更改RSS输出为全文,使用Papermod的rss.xml为模版(怎会如此)
    • 如果不想要某些页面输出RSS,可以将那个页面设置为_index.md作为目录页
  • 将尾注的build小图更改为短代码
  • 增加一些双向认证链接,但并没有全部生效
  • 增加「文章最后更新日期」,并修复Netlify特有的时间bug
  • 新增留言表单,就在本页末尾,使用Netlify自带的服务
  • 这个RSS图标为啥会在hover的时候出现一圈边框呢?! 解决不了,先不用了
  • 搬运了一些教程,请爱护原作者
  • 开启Hugo自带的emoji,虽然很丑 🤷‍♂️
5.5
  • 更新飞书图标,但还没美化 美化了,直接换了IconPark
  • 更改custom.css的路径,使其脱离原主题文件夹(终于全部自定义内容脱离完毕!)
  • 新增此Update页面
  • 写了点教学……就整理在本页下面
  • 增加运行天数 参考
  • 更改选中时的底色
  • 修复了链接mouseover时后面会多出一个空格的bug!感谢大佬们
5.4
  • 更改标题字体为"Tilt Neon",为了国内访问速度,将字体下载后放在了css/fonts文件夹……
  • Font Awesome的版本为最新,更换读取Kit包
  • 更改部署至Netlify
5.3
5.2
5.1
  • 新增网站内容
5.0
  • 重新开始制作此网站,用Hugo构建
  • 在Vercel上部署完毕并公开

修改Hugo主题时的通用注意事项

  1. 建议将所有修改过的文件均放在layouts或static目录中,以便日后升级theme时不造成妨碍。
    所有的html相关文件均在Hugo的根目录/themes/主题名/layouts目录下。此目录下的全部文件均可直接复制至根目录/layouts/下,Hugo在发布时会将根目录/layouts/里的内容替换掉主题自带的themes/主题名/layouts/里的文件。
    同理,新建的文件也可以直接在根目录/layouts/下建立。
  2. CSS文件的路径不同。自定义的css文件需要放在根目录/static/css/下,才能正常覆盖掉主题自带的css。
    JS文件、图片等同CSS,分别在jsimg文件夹下。

这样一来就可以无痛无脑更新主题,而不用担心自己的自定义内容全消失了。


给网站添加OpenGraph标签

这样做可以方便在SNS上进行图片及内容的预览,让网址被分享时更美观易用。主要代码来自FUJI Theme,不仅有og,还有twitter card! 就像这样:

og sample

理论上所有不带OG标签的主题都适用,此处就以「hugo-creative-portfolio-theme」主题为例。

  1. /layouts/partials/head.html的任意一处增加以下内容:
<!-- og -->
{{ partial "opengraph.html" . }}
  1. /layouts/partials/目录下增加opengraph.html,并写入以下内容:
<!-- 整个都是从FUJI theme复制的!标题等有略微修改 -->
<!-- 更改Home的OG标题,避免输出2个相同标题 by 猫鱼 -->
{{- if .IsHome -}}
<meta property="og:title" content="{{ .Site.Title }}" />
<meta name="twitter:title" content="{{ .Site.Title }}" />
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{- else -}}
<meta property="og:title" content="{{ .Title }} - {{ .Site.Title }}" />
<meta name="twitter:title" content="{{ .Title }} - {{ .Site.Title }}" />
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{- end -}}
<!-- end -->

{{- if .Description -}}
<meta property="og:description" content="{{ .Description }}" />
<meta name="twitter:description" content="{{ .Description }}" />
{{- else if .Params.description -}}
<meta property="og:description" content="{{ .Params.description }}" />
<meta name="twitter:description" content="{{ .Params.description }}" />
{{- else -}}
{{- if .IsPage -}}
<meta property="og:description" content="{{ .Summary }}" />
<meta name="twitter:description" content="{{ .Summary }}" />
{{- end -}}
{{- end -}}

{{- if .Params.image -}}
<meta property="og:image" content="{{ .Params.image | absURL }}" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="{{ .Params.image | absURL }}" />
{{- else if .Site.Params.og -}}
<meta property="og:image" content="{{ .Site.Params.og | absURL }}" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="{{ .Site.Params.og | absURL }}" />
{{- else -}}
<meta name="twitter:card" content="summary" />
{{- end -}}

{{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
{{- if .IsPage -}}
{{- if not .PublishDate.IsZero -}}
<meta property="article:published_time" {{ .PublishDate.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{- else if not .Date.IsZero -}}
<meta property="article:published_time" {{ .Date.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{- end -}}
{{- if not .Lastmod.IsZero -}}
<meta property="article:modified_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{- end -}}
{{- else -}}
{{- if not .Date.IsZero -}}
<meta property="og:updated_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{- end -}}
{{- end -}}
  1. config.toml增加og参数:
# 增加OG图片
  og = "/img/你的图片名.jpg"

这样就完成了。这个主题不自带OG,作为作品集来说缺少了很重要的部分,因此添加上了。


在「hugo-creative-portfolio-theme」主题中取消默认的文件夹路径「portfolio/」,将地址栏固定为「/」

访问网站后地址栏显示「cat-fish.net」而非「cat-fish.net/portfolio」,感觉好多了!

将地址栏固定为「/」

根据此Commit进行修改。 如果没有main.html,可以自己新建一个。

⚠注意:原文中将protfolio全部改为artical并新增了main.html、之后又将原portfolio文件夹改名为artical。如果你像我一样不想更改文件夹名,可以将main.html里的{{ range (site.GetPage "artical").Pages }}改为{{ range (site.GetPage "portfolio").Pages }}

(此处的page可以定义到任何一个page从而让它在首页显示出来,相当于替代了config.toml里的index=true

修复首页OG中标题重复的问题

这样更改后首页的标题可能会出现重复title的问题(即文章标题和网站标题重复),原主题根本没有OG,所以也没有遇到这个问题,我自行修复了!可以在<head>里或opengraph.html里这样更改:

<!-- 更改Home的OG标题,避免输出2个相同标题 by 猫鱼 https://cat-fish.net/ -->
{{- if .IsHome -}}
<meta property="og:title" content="{{ .Site.Title }}" />
<meta name="twitter:title" content="{{ .Site.Title }}" />
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{- else -}}
<meta property="og:title" content="{{ .Title }} - {{ .Site.Title }}" />
<meta name="twitter:title" content="{{ .Title }} - {{ .Site.Title }}" />
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{- end -}}
<!-- end -->

这样就可以避免首页出现重复的标题了。

PS:如果你按照本站的这篇添加了OpenGraph图片预览功能,则不用再处理标题重复的问题,因为那篇里已经修改完毕了。


修正正文内容的所有链接均被打开新窗口的问题

根据这篇文章,可以自动在有外链(正文内带有http及https开头的地址)时,在外链的文字后面加上一个打开新窗口的小箭头图示。

但是,根据原文直接做的话,正文内不管是不是外链的地址,都会被打开新窗口。 这样就没有小箭头存在的意义了,所以需要把它解决一下。方法如下:

layouts/_default/_markup/render-link.html里的内容替换成如下:

{{- if strings.HasPrefix .Destination "http" -}}<a href="{{- .Destination | safeURL -}}"{{ with .Title}} title="{{- . -}}"{{ end }} target="_blank" rel="noopener">{{- .Text | safeHTML -}}<span style="white-space: nowrap;"><svg width=".7em" height=".7em" viewBox="0 0 21 21" xmlns="http://www.w3.org/2000/svg"><path d="m13 3l3.293 3.293l-7 7l1.414 1.414l7-7L21 11V3z" fill="currentColor"/><path d="M19 19H5V5h7l-2-2H5c-1.103 0-2 .897-2 2v14c0 1.103.897 2 2 2h14c1.103 0 2-.897 2-2v-5l-2-2v7z" fill="currentColor"></svg></span></a>{{- else -}}<a href="{{- .Destination | safeURL -}}"{{ with .Title}} title="{{- . -}}"{{ end }}>{{- .Text | safeHTML -}}</a>{{- end }}

增加了一个判断,只有当链接是外链时才打开新窗口并增加小箭头图示,反之则渲染成普通的链接即可。使用Markdown写的内容也都适用。例如:

[文字链接](https://cat-fish.net) #这条会被加上小箭头并打开新窗口
[文字链接](/update/) #这条就是普通的链接

⚠注意: 代码中的小箭头图示用的是原文的图示(方块形)。如果需要使用本站的圆形图示,可以参考IconPark的用法,和Font Awesome很类似,但更简单,非常推荐。

PS: 代码已更新(2024/5/6),加上注释的话会多一个空格,我真是服了这HTML,把注释杀了就好了。顺便优化成了单行代码。


增加代码高亮功能

根据Hugo的官方文档,可以启用自带的Chroma代码高亮功能。
(我有不加载过多js文件的PTSD,所以没有选择js渲染)

  1. config.toml里添加如下设置:
# 增加代码高亮,来自hugo官方
[markup]
[markup.highlight]
  anchorLineNos = false
  codeFences = true #代码框,默认启用
  guessSyntax = true #自动推测代码类别
  hl_Lines = ''
  hl_inline = false
  lineAnchors = ''
  lineNoStart = 1
  lineNos = false
  lineNumbersInTable = true
  noClasses = true #是否启用自带样式,默认为是
  noHl = false
  style = 'monokailight' #样式主题
  tabWidth = 4
  1. 由于我的guessSyntax没有自动识别出任何代码(怎会如此),因此需要自己指定一下代码类型。在任意可写Markdown的地方这样写:
```html
// ... 代码放这里面
```

```后面直接增加想要指定的代码种类就行。有效的类型列表在这里
这样就能直接使用Hugo自带的快速高亮了!

自定义代码框的高亮样式

对Chroma自带的高亮样式不满意?可以自定义。参考Hugo文档
方法:

  1. 禁用Chroma自带的样式:
noClasses = false
  1. 在命令行里输入以下命令,下载CSS文件:
hugo gen chromastyles --style=monokailight > syntax.css

记得将monokailight改为你想下载的css主题名字。
下载后的文件会在Hugo根目录里。

  1. 将下载的synatx.css挪动到static/css下。

  2. <head>里适当的位置引用这个css:

<link href="{{ "css/syntax.css" | absURL }}" rel="stylesheet">

完成!修改这个CSS文件即可自定义自己的样式了。

顺便一提……
因为我用的monokailight这个主题的高亮对于展示html+hugo简码不是很友好,把一大堆东西都误标记成错误代码了,所以我很直接的改了一下报错的背景色,让它显得不那么显眼……鸵鸟式处理。

调整代码框的相对位置

原本代码框的位置有点微妙,看了一下是mk写的东西自动带<p>,导致代码框上面有一个空行,下面又空间不足。所以调一下就好了,在css里插入:

pre { margin:-15px 0 20px 0; }

即可。具体的参数可以根据自己的需求调整。


添加bilibili短代码播放器

短代码播放器总是需要一个的。
参考这篇教学添加了播放器,只需要写一个短代码就好了。

添加shortcodes短代码
  1. layouts/shortcodes/里新建一个叫bilibili.html的文件,并写入以下代码:
<!-- 语法规则
    1. 匿名模式
        <bilibili BV1Wg411t7EE 233>
    2. 具名模式
        <bilibili 
            src="https://www.bilibili.com/video/BV1RK41117eY/" 
            page="332"
        >
-->

<!-- 获取第一个参数 作为视频地址 -->
{{- $dest := ( .Get 0) -}}

<!-- 如果是具名模式, 获取 src -->
{{ if .IsNamedParams }}
    {{ $dest = (.Get "src") }}
{{ end }}

<!-- 判断是否为 全路径, 是则获取视频ID -->
{{ if (hasPrefix $dest "http" )}}
    <!-- https://www.bilibili.com/video/BV1RK41117eY/ -->
    {{ $dest = (strings.TrimPrefix "http" $dest ) }}

    <!-- 解析 URL -->
    {{ $url := urls.Parse $dest }}

    <!-- /video/BV1RK41117eY/ -->
    {{ $dest = $url.Path }}

    <!-- BV1RK41117eY -->
    {{ $dest = (path.BaseName $dest) }}
{{ end }}


<!-- 获取专辑中的视频 ID -->
{{- $page := (.Get 1) -}}

{{ if .IsNamedParams }}
    {{ $page = (.Get "page") }}
{{ end }}

<!-- 默认值为 1 -->
{{ if (not $page) }}
    {{ $page = 1 }}
{{ end }}


<!-- 嵌入 bilibili 播放框 -->
<div style="margin: 10px 0 20px 0;">
  <!-- <h3>视频ID: {{ $dest }} - {{ $page }} </h3> -->
  <div style="position:relative; padding-bottom:75%; width:100%; height:0">
    <iframe src="//player.bilibili.com/player.html?bvid={{ $dest }}&page={{ $page }}&autoplay=0&muted=true"       
        scrolling="no" border="0"
        frameborder="no" 
        framespacing="0" 
        allowfullscreen="true" 
        style="position:absolute; height: 100%; width: 100%;">
    </iframe>
  </div>
</div>
  1. 在需要插入视频的地方写:
{{< bilibili BV号 分集号 >}}

或者这么写:

{{< bilibili src="视频地址" page="分集号" >}}

就完成了,非常简单。bilibili可以替换成任何词,只要能对应就行。

默认静音+不自动播放

在原文的基础上增加了静音与不自动播放,我最讨厌自动播放了,必须干掉它才能安心睡觉。
办法很简单,在iframe src地址里加上&autoplay=0&muted=true就可以了。(上面的代码里已经加上了)

不过话说回来,我也不喜欢iframe这个标签就是了……而且bili的播放器好丑……


添加文章最后更新日期,并修复Netlify的日期bug

参考这篇文章,给所有页面(除了About和Contact这种不需要更新日期的)的底部添加了最后更新日期。对于作品集来说非常有用!
但是,果然也遇到了Netlify的构建会导致文章的修改时间失效的问题。本地预览时正确的,但部署上去后就全变成部署的日期了。这样不就没有意义了嘛……
好在找到了这篇文章里提供的方法解决了这个bug。
如果你像我一样不知道去哪找netlify.toml,可以参考这篇文章来自己建立一个文件,并把它上传到GitHub。
……好吧,我把全部的步骤写一下,免得出现一大堆404:

添加文章的最后更新日期
  1. 将以下代码添加进single.html中合适的部分(通常在{{ .Content }}{{ .main }}后面),或者任意你想显示的地方:
{{ if ne (.Lastmod.Format "2006-01-02") (.Date.Format "2006-01-02") }}
<p>最后更新于: {{ .Lastmod.Year }}/{{ printf "%d" .Lastmod.Month }}/{{ .Lastmod.Day }}</p>
{{ end }}
  1. 设置config.toml文件
enableGitInfo = true
[frontmatter]
  lastmod = [":git", "lastmod", ":fileModTime"]

本地能正确显示的话就是成功了。

修正Netlify部署时的时间错误bug
  1. 如果你没有netlify.toml,那就在Hugo的根目录新建一个,并写入以下设置:
[build]
publish = "public"
# command = "hugo --gc --minify" 修改时间bug
command = '''find content -name '*.md' | while read file; do touch -d "$(git log -1 --format="@%ct" "$file")" "$file"; done; hugo --gc --minify'''

[context.production.environment]
HUGO_VERSION = "0.88.1" #请根据自己的 Hugo 版本进行修改
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"

[context.split1]
command = "hugo --gc --minify --enableGitInfo"

[context.split1.environment]
HUGO_VERSION = "0.88.1" #请根据自己的 Hugo 版本进行修改
HUGO_ENV = "production"

[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"

[context.deploy-preview.environment]
HUGO_VERSION = "0.88.1" #请根据自己的 Hugo 版本进行修改

[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"

[context.branch-deploy.environment]
HUGO_VERSION = "0.88.1" #请根据自己的 Hugo 版本进行修改

[context.next.environment]
HUGO_ENABLEGITINFO = "true"
  1. 将它和Hugo的其他文件一起上传到GitHub就行了,Netlify会自动部署的,这样部署后的日期也是正确的了。

使用Netlify自带的服务建立留言表单

Netlify很好心的提供基础的表单服务,免费用户一个月可以收100封,支持自定义成功页面,自定义邮件提醒,支持防spam机器人,支持ajax提交等,十分nice!心动不如行动,马上整一个玩玩。
例子就在本页末尾,以下代码均以此为例。

建立基础HTML表单
  1. 登入Netlify后台,找到「Forms」,点击「Enable」启用表单功能。
  2. 在任意需要插入表单的地方写入以下代码(也可以做成短代码):
<form
  name="update-page-form"
  method="POST"
  netlify-honeypot="bot-field"
  data-netlify="true"
>
  <!-- 蜜罐领域 -->
  <p class="hidden">
    <label>
      Don’t fill this out if you’re human: <input name="bot-field" />
    </label>
  </p>
  <div class="chat-input">
    <input type="text" name="message" placeholder="如果有任何bug或想说的...">
    <button type="submit">Send</button>
  </div>
</form>

以上代码默认开启了防spam功能(机翻:蜜罐领域),没有特殊问题的话建议保留。
表单是纯HTML的,各个字段都可以自己更改,注意必须要有name="自定义字段",不然后台读不到内容。

  1. 在css里增加如下样式:
.chat-input {
    display: flex;
    align-items: center;
    width: 100%;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 8px;
    margin: 50px 0 20px 0;
}
.chat-input input {
    flex: 1;
    border: none;
    outline: none;
    font-size: 14px;
    padding:0 0 0 8px;
}
.chat-input button {
    background-color: #ef5285;
    color: white;
    border: none;
    border-radius: 5px;
    padding: 8px 12px;
    margin-left: 8px;
    cursor: pointer;
}
.chat-input button:hover {
    background-color: #c7254e;
}

颜色等可以自己更改。大功告成!

自定义发送成功页面
  1. 在Hugo里新建一个页面。根据主题不同,方法也不同,这里仅写出针对「hugo-creative-portfolio-theme」主题的方法:
  • 复制about文件夹,并将其改名为success
  • layouts/下新建success/list.html,并写入以下代码:
{{ define "main" }}
<div class="col-xs-12 col-sm-8 col-md-9 content-column white-background">
{{ partial "mobile_nav_toggle.html" . }}
<div class="row">
  <div class="col-lg-8">
    <div class="content-column-content">
       <h1>{{ .Title }}</h1>
       {{ .Content }}
       <button onclick="goBack()" class="btn btn-ghost">Back</button>
        <script>
        function goBack() {
          window.history.back();
        }
        </script>
    </div>
  </div>
</div>
</div>
{{ end }}
  • 打开success/_index.md,编辑内容
  • 在浏览器里输入(hugo的根目录,一般是localhost:1313)/success,确认页面是否能显示
  1. 确认页面能显示后,将form action="/success"插入到表单中:
<form
    name="update-page-form"
    action="/success"
    method="POST"
    netlify-honeypot="bot-field"
    data-netlify="true"
>
  ...
</form>

到这里就全部完成啦!

⚠注意:必须部署后才会生效,本地按发送是没用的。

启用邮件通知及自定义邮件通知的标题
  1. 在Netlify后台Forms > Form notifications > Form submission notifications处选择Add notification > Email notification,在里面写上邮件地址等
  2. 然后在Custom email subject line处自由编辑即可
  3. 更多变量可查看官方文档

Netlify Status


Last update: 2024 / 5 / 22
Running for 0 days.