博客装修小记一

博客装修小记一

前言 #

Book这个主题干净简约,但博客不是该主题的主要用例,只有很少的功能。但只要稍加修改、添加细节,就能让博客在简洁中而不失精致。想到以后一定还会有修改添置,就先记录为**“装修小记”之“一”**吧。以下将显示效果和相应代码一同放出。这里也提供了一篇样式预览博文,以便总体审阅:样式 | Style

装修过程中,有时也忘了代码出处,因此,将相关的链接统一列至文末的参考链接章节,在文内就不再一一赘述。

主题颜色变更 #

改变/themes/hugo-book/assets/_defaults.scss--color-link--color-visited-link的值即可。

鼠标选中颜色 #

默认跟浏览器设置走,可以指定颜色,在博客内浏览拾取更加美观。效果:

鼠标选中颜色 鼠标选中颜色

/*/themes/hugo-book/assets/_custom.scss*/
::selection {
  background: var(--color-visited-link);
}

站点信息和版权标识 #

在全站底部添加站点信息和版权标识。效果如下:

站点信息和版权标识 站点信息和版权标识

<!-- /themes/hugo-book/layouts/partials/docs/inject/body.html -->
<footer class="footer">
    <div class="footer-content">
      <!-- year -->
      <p>&copy; {{ now.Format "2006" }} {{ .Site.Title }}. <a href="{{ .Site.BaseURL}}docs/about">Some rights reserved</a></p>
      <!-- copyright -->
      <p class="footer-message">
        Powered by <a href="https://gohugo.io" target="_blank" rel="noopener noreferrer">Hugo</a> 
        - theme <a href="https://github.com/alex-shpak/hugo-book" target="_blank" rel="noopener noreferrer">Book</a>.
      </p>
    </div>
  </footer>
/*/themes/hugo-book/assets/_custom.scss*/
.footer {
  background-color: var(--body-background);
  padding: 20px 0;
  text-align: center;
  font-size: x-small;
  color: #adb5bd;
}
.footer-content p {
  margin: 0;
}
.footer-message {
  margin-top: 10px;
  font-size: x-small;
  color: #adb5bd;
}

回到顶部按钮 #

在全站右下角添加圆形一键回到顶部按钮。

<!-- /themes/hugo-book/layouts/partials/docs/top.html --> 
<style>
    #backtop {
        color: var(--color-visited-link);
        position: fixed;
        right: 25px;
        bottom: 25px;
        width: 25px;
        height: 25px;
        z-index: 999998;
    }
</style>

<div id="backtop">
    <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-circle-up" class="svg-inline--fa fa-chevron-circle-up fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
        <path fill="currentColor" d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z">
        </path>
    </svg>
</div>

<script>
    var timer = null;
    backtop.onclick = function () {
        cancelAnimationFrame(timer);
        //获取当前毫秒数
        var startTime = +new Date();
        //获取当前页面的滚动高度
        var b = document.body.scrollTop || document.documentElement.scrollTop;
        var d = 500;
        var c = b;
        timer = requestAnimationFrame(function func() {
            var t = d - Math.max(0, startTime - (+new Date()) + d);
            document.documentElement.scrollTop = document.body.scrollTop = t * (-c) / d + b;
            timer = requestAnimationFrame(func);
            if (t == d) {
                cancelAnimationFrame(timer);
            }
        });
    }
</script>
<!-- /themes/hugo-book/layouts/_default/baseof.html -->
{{ partial "docs/top.html" . }} <!-- 末尾添加该行 -->

文章顶部添加Banner #

在文章顶部添加banner,这是全站为数不多的大幅面图片装饰,效果如下:

文章顶部添加Banner 文章顶部添加Banner

<!-- /themes/hugo-book/layouts/partials/docs/banner.html -->
{{ with .Params.banner }}
  <div class="book-banner">
    <img src="{{ . | relURL }}" alt="Banner Image" class="banner-image" />
  </div>
{{ end }}
/*/themes/hugo-book/assets/_custom.scss*/
.book-banner {
  margin: 15px 0;
  text-align: center;
}

.banner-image {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

在文章的.md文件Front matter中配置banner: https://banner链接,如:

---
title: 我在数字时代做了一个电子日历,让油画和照片可以被装进去
date: 2023-09-06
linktitle: 我在数字时代做了一个电子日历,让油画和照片可以被装进去
banner: 'https://img.osnsyc.top/6ef503.png'
---

banner值为空,则无banner显示。

文章标题下划线 #

给文章大标题下增加主题色下划线装饰条,分割标题区域的元素。见该节文章顶部添加Banner配图。

<!-- /themes/hugo-book/layouts/posts/single.html -->
  <h1>
    {{ partial "docs/title.html" . }}
  </h1>
  <div class="header-underline"></div> <!-- 添加此行 -->
  {{ partial "docs/post-meta" . }}
/*/themes/hugo-book/assets/_custom.scss*/
.header-underline {
  display: inline-block;
  margin-top: 15px;
  margin-bottom: 20px;
  width: 150px;
  border-bottom: 3px solid var(--color-link);
}

带标签的文章列表 #

自动更新近15条文章,列表形式呈现。纯链接列表不美观,标题后显示彩色标签与灰色日期。效果:

<!-- /themes/hugo-book/layouts/shortcodes/archive.html -->
<ul>
    {{ range (first 15 (where .Site.RegularPages "Type" "posts")) }}
      <li>
        <a href="{{ .RelPermalink}}">{{ .Title }}</a> 
        {{range (first 3 (.Params.tags))}}
          {{ $tagColor := substr (md5 .) 0 6}}
          <!-- hex code attach opacity to end of code, 33 is 20% opacity  -->
          <!-- to add link here, you'd need to search Taxonomies for url, but it doesn't have chinese tag -->
          <div class="tag" style="--tag-color: #{{$tagColor}}33" >{{ . }}</div>
        {{end }}
        <div class="archive">- {{.Date.Format "2006-01-02"}}</div>
      </li>
    {{ end }}
  </ul>
/*/themes/hugo-book/assets/_custom.scss*/
.archive {
  display: inline;
  color: var(--gray-500);
  font-size: 0.75em;
}

.md文件中键入{{< archive >}}显示列表。

上一篇下一篇导航 #

posts类别的博文末尾自动添加上一篇下一篇导航,效果:

文末导航 文末导航

<!-- /themes/hugo-book/layouts/posts/single.html -->
<!-- </article>下,{{ end }}上添加如下 -->
<div class="post-nav">
  {{ with .Prev }}
    <a href="{{ .RelPermalink }}?utm_source=nav" >前一篇 {{ .Title | truncate 10 "..."}}</a>
  {{ end }}
  {{ with .Next }}
    <a href="{{ .RelPermalink }}?utm_source=nav" >{{ .Title | truncate 10 "..."}} 后一篇</a>
  {{ end }}
</div>
/*/themes/hugo-book/assets/_custom.scss*/
.post-nav {
  display: flex;
  justify-content: space-between;
  gap: 4px;
}

随机阅读博文 #

点击链接,随机导航至该博客内的一篇博文。效果见该节上一篇下一篇导航配图。

<!-- /themes/hugo-book/layouts/partials/docs/random.html -->
<script>
  function goToRandomPost() {
    const pages = [
      {{ range ((where .Site.RegularPages "Type" "posts")) }}
      "{{ .RelPermalink }}?utm_source=random",
      {{ end -}}
    ];
    const rand = Math.floor(Math.random() * pages.length);
    window.location.href = pages[rand];
  }
</script>
<!-- /themes/hugo-book/layouts/posts/single.html -->
{{ partial "docs/random" . }}
<a class="random" onclick='goToRandomPost()'>随机阅读</a>

书影音卡片 #

以下三章的功能卡片类似:书影音卡片站内链接卡片可播放音乐卡片,统一了风格。很多静态博客使用了豆瓣或者Neodb的api,但豆瓣api不稳定,而Neodb的条目信息不够全。我预计自己不会过多使用多媒体卡片,因此卡片信息全部手动填写,也算增加稳定性吧,只要该博客还在,就不会出现图裂的不良观感。这个卡片也可以套用上任何信息,比如产品评价。效果如下:

凉糕评价: 9
两兄弟经常跟父亲一起钓鱼。潺潺河水,静静午后,成了父子间最难忘的时刻。父亲是一个老牧师,常常在镇上布道,大儿子诺曼(克莱格•谢佛 Craig Sheffer 饰)正是继承了父亲的事业——他擅长讲课,大学毕业后回到家乡传道授业。小儿子保罗(布拉德•皮特 Brad Pitt 饰)却有着迥异的性格——他热爱自由,有一套奇特的钓鱼方法。然而,令人担心的是他迷上了赌博,并因此欠钱遭打。诺曼结婚后收到一封芝加哥大学的聘用书,他离家前往芝加哥之前,和父亲、弟弟一同在大河边再次享受钓鱼时光。他劝保罗跟他一起离开这里,然而保罗痴迷钓鱼,不愿离去。怎料,这竟是最后的相聚。
Movie
<!-- /themes/hugo-book/layouts/shortcodes/dbcard.html -->
{{ $title := .Get "title" }}
{{ $url := .Get "url" }}
{{ $cover := .Get "cover" }}
{{ $rating := .Get "rating" }}
{{ $numericRating := 0 }}
{{ if $rating }}
  {{ $numericRating = float $rating }}
{{ end }}
{{ $brief := .Get "brief" }}
{{ $category := .Get "category" }}

<div class="db-card">
    <div class="db-card-subject">
        <div class="db-card-post">
            <img loading="lazy" decoding="async" referrerpolicy="no-referrer" src="{{ $cover }}">
        </div>
        <div class="db-card-content">
            <div class="db-card-title">
                <a href="{{ $url }}" class="cute" target="_blank" rel="noreferrer">{{ $title }}</a>
            </div>
            {{ if .Params.rating }}
            <div class="rating">
                <span class="rating_nums">{{ .Site.Title }}评价:</span>
                <span class="allstardark">
                    {{ $numericRating := default 0 (float $rating) }}
                    <span class="allstarlight" style="width:{{ mul 10 $numericRating }}%"></span>
                </span>
                <span class="rating_nums">{{ $numericRating }}</span>
            </div>
            {{ end }}
            <div class="db-card-abstract">{{ $brief }}</div>
        </div>
    </div>
    <div class="db-card-cate">{{ $category }}</div>
</div>
/*/themes/hugo-book/assets/_custom.scss*/
/* db-card -------- start*/
.db-card {
  max-width: $card-width;
  margin: 1em auto;
  position: relative;
  display: flex;
  background: #fdfdfd;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .25);
}
.db-card-subject {
  display: flex;
  align-items: flex-start;
  line-height: 1.6;
  padding: 12px;
  position: relative;
}
.dark .db-card {
  background: #252627;
}
.db-card-content {
  flex: 1 1 auto;
}
.db-card-post {
  width: 30%;
  max-width: 120px;
  margin-right: 15px;
  display: flex;
  flex: 0 0 auto;
}
.db-card-title {
  margin-bottom: 5px;
  font-size: medium;
}
.db-card-title a {
  text-decoration: none !important;
}
.db-card-abstract,
.db-card-comment {
  font-size: x-small;
  overflow: auto;
  max-height: 4rem;
  scrollbar-width: none;  /* Firefox */
}
/* Hide scrollbar for Chrome, Safari and Opera */
.db-card-abstract::-webkit-scrollbar {
  display: none;
}
.db-card-cate {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--color-link);
  color: white;
  padding: 1px 8px;
  font-size: x-small;
  font-style: italic;
  border-radius: 0 8px 0 8px;
  text-transform: capitalize;
}
.db-card-post img {
  width: 100%;
  border-radius: 4px;
  -o-object-fit: cover;
  object-fit: cover;
}
.rating {
  margin: 0 0 5px;
  font-size: x-small;
  line-height: 1;
  display: flex;
  align-items: center;
}
.rating .allstardark {
  position: relative;
  color: var(--color-link);
  height: 16px;
  width: 80px;
  background-size: auto 100%;
  margin-right: 8px;
  background-repeat: repeat;
  background-image: url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjxwYXRoIGQ9Ik05MDguMSAzNTMuMWwtMjUzLjktMzYuOUw1NDAuNyA4Ni4xYy0zLjEtNi4zLTguMi0xMS40LTE0LjUtMTQuNS0xNS44LTcuOC0zNS0xLjMtNDIuOSAxNC41TDM2OS44IDMxNi4ybC0yNTMuOSAzNi45Yy03IDEtMTMuNCA0LjMtMTguMyA5LjMtMTIuMyAxMi43LTEyLjEgMzIuOS42IDQ1LjNsMTgzLjcgMTc5LjEtNDMuNCAyNTIuOWMtMS4yIDYuOS0uMSAxNC4xIDMuMiAyMC4zIDguMiAxNS42IDI3LjYgMjEuNyA0My4yIDEzLjRMNTEyIDc1NGwyMjcuMSAxMTkuNGM2LjIgMy4zIDEzLjQgNC40IDIwLjMgMy4yIDE3LjQtMyAyOS4xLTE5LjUgMjYuMS0zNi45bC00My40LTI1Mi45IDE4My43LTE3OS4xYzUtNC45IDguMy0xMS4zIDkuMy0xOC4zIDIuNy0xNy41LTkuNS0zMy43LTI3LTM2LjN6TTY2NC44IDU2MS42bDM2LjEgMjEwLjNMNTEyIDY3Mi43IDMyMy4xIDc3MmwzNi4xLTIxMC4zLTE1Mi44LTE0OUw0MTcuNiAzODIgNTEyIDE5MC43IDYwNi40IDM4MmwyMTEuMiAzMC43LTE1Mi44IDE0OC45eiIgZmlsbD0iI2Y5OWIwMSIvPjwvc3ZnPg==);
}
.rating .allstarlight {
  position: absolute;
  left: 0;
  color: var(--color-link);
  height: 16px;
  overflow: hidden;
  background-size: auto 100%;
  background-repeat: repeat;
  background-image: url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiPjxwYXRoIGQ9Ik05MDguMSAzNTMuMWwtMjUzLjktMzYuOUw1NDAuNyA4Ni4xYy0zLjEtNi4zLTguMi0xMS40LTE0LjUtMTQuNS0xNS44LTcuOC0zNS0xLjMtNDIuOSAxNC41TDM2OS44IDMxNi4ybC0yNTMuOSAzNi45Yy03IDEtMTMuNCA0LjMtMTguMyA5LjMtMTIuMyAxMi43LTEyLjEgMzIuOS42IDQ1LjNsMTgzLjcgMTc5LjEtNDMuNCAyNTIuOWMtMS4yIDYuOS0uMSAxNC4xIDMuMiAyMC4zIDguMiAxNS42IDI3LjYgMjEuNyA0My4yIDEzLjRMNTEyIDc1NGwyMjcuMSAxMTkuNGM2LjIgMy4zIDEzLjQgNC40IDIwLjMgMy4yIDE3LjQtMyAyOS4xLTE5LjUgMjYuMS0zNi45bC00My40LTI1Mi45IDE4My43LTE3OS4xYzUtNC45IDguMy0xMS4zIDkuMy0xOC4zIDIuNy0xNy41LTkuNS0zMy43LTI3LTM2LjN6IiBmaWxsPSIjZjk5YjAxIi8+PC9zdmc+);
}
@media (max-width: 550px) {
  .db-card {
    width: 95%;
  }
  .db-card-comment {
    display: none;
  }
}
/* db-card -------- end */

使用示例,在.md文件中使用:

{{< dbcard
    url="https://book.douban.com/subject/1291204/"
    cover="https://img1.doubanio.com/view/subject/s/public/s1789059.jpg"
    title="哥德尔、艾舍尔、巴赫:集异璧之大成"
    brief="集异璧-GEB,是数学家哥德尔、版画家艾舍尔、音乐家巴赫三个名字的前缀。《哥德尔、艾舍尔、巴赫:集异璧之大成》是在英语世界中有极高评价的科普著作。曾获得普利策文学奖。它通过对哥德尔的数理逻辑,艾舍尔的版画和巴赫的音乐三者的综合阐述,引人入胜地介绍了数理逻辑学、可计算理论、人工智能学、语言学、遗传学、音乐、绘画的理论等方面,构思精巧、含义深刻、视野广阔、富于哲学韵味。"
    category="Book"
>}}

站内链接卡片 #

效果:

我在数字时代做了一个电子日历,让油画和照片可以被装进去
project
home-server
坐在椅子上发呆时,忽然注意到桌面的台历还停留在上一个月。在这个数字时代,实体日历似乎跟不上我们匆匆的步伐,我们更多地依赖...
内链
<!-- /themes/hugo-book/layouts/shortcodes/innerlink.html -->
{{$URL := .Get 0}}
{{ with .Site.GetPage $URL }}
{{ with .Params.feature }}
	{{ $.Scratch.Set "feature" . }}
{{ else }}
	{{ with findRE `!\[(.*?)\]\((.*?)\)` .RawContent }}
		{{ range first 1 . }}
			{{ $url := replaceRE `!\[(.*?)\]\((.*?)\)` "$2" . }}
			{{$.Scratch.Set "feature" $url }}
		{{ end }}
	{{ else }}
		{{ $.Scratch.Set "feature" false }}
	{{ end }}
{{ end }}

<div class="post-preview">
  <div class="post-preview--meta" style="width:100%;">
    <div class="post-preview--middle">
      <div class="post-preview--title">
        <a target="_blank" href="{{ .RelPermalink }}">{{ .Title }}</a>
      </div>
      <time class="post-preview--date">{{ .Date.Format ( default "2006-01-02") }}</time>
      {{ if .Params.tags }}
        {{range (first 3 (.Params.tags))}}
        {{ $tagColor := substr (md5 .) 0 6}}
        <!-- hex code attach opacity to end of code, 33 is 20% opacity  -->
        <!-- to add link here, you'd need to search Taxonomies for url, but it doesn't have chinese tag -->
        <div class="tag" style="--tag-color: #{{$tagColor}}33" >{{ . }}</div>        
        {{end }}
      {{ end }}
      <section class="post-preview--excerpt">
        {{ .Summary | truncate 60 "..."}}
      </section>
    </div>
  </div>
  <div class="post-preview-cate">内链</div>
</div>
{{ end }}
/*/themes/hugo-book/assets/_custom.scss*/
/* post-preview --------*/
.post-preview {
  max-width: $card-width;
  margin: 1em auto;
  position: relative;
  display: flex;
  background: #fdfdfd;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .25);
}
.post-preview--meta {
  display: flex;
  align-items:flex-start;
  width: 100%;
  padding: 15px;
  overflow: auto;
  position:relative;
}
.post-preview--middle {
  line-height: 28px;
}
.post-preview--title {
  font-size: medium !important;
  margin: 0 !important;
}
.post-preview--title a {
  text-decoration: none;
}
.post-preview--date {
  font-size: x-small;
  color: #999;
}
.post-preview--excerpt {
  font-size: x-small;
  line-height: 1.825;
  max-height: 2.5rem;
  overflow: auto;
  scrollbar-width: none;  /* Firefox */
}
.post-preview--excerpt p {
  display: inline;
  margin: 0;
}
.post-preview--excerpt::-webkit-scrollbar {
  display: none;
}
.post-preview--image {
  object-fit: cover;
  height: auto;
  width: 25%;
  float: right;
  padding-right: 15px;
}
.post-preview-cate {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--color-link);
  color: white;
  padding: 1px 8px;
  font-size: x-small;
  font-style: italic;
  border-radius: 0 8px 0 8px;
  text-transform: capitalize;
}
@media (max-width:550px) {
  .post-preview {
    width: 95%;
  }
  .post-preview--meta {
    padding: 15px;
  }
  .post-preview--image {
    height: 120px !important;
  }
  .post-preview--middle {
    line-height: 19px;
  }
}
.dark .post-preview {
  background: #3b3d42;
}
/* post-preview --- end */

使用示例,在.md文件中使用:

{{<innerlink "eink-calendar">}}

可播放音乐卡片 #

使用了APlayerMetingJS,点击可播放音频,细节配置方法可以移步两个项目的仓库,效果如下:

<!-- /themes/hugo-book/layouts/shortcodes/music.html -->
{{- $scratch := .Page.Scratch.Get "scratch" -}}
<!-- require APlayer -->
<link rel="stylesheet" href="{{ "/APlayer.min.css" | relURL }}">
<style type="text/css">.dark-theme .aplayer{background:#212121}.dark-theme .aplayer.aplayer-withlist .aplayer-info{border-bottom-color:#5c5c5c}.dark-theme .aplayer.aplayer-fixed .aplayer-list{border-color:#5c5c5c}.dark-theme .aplayer .aplayer-body{background-color:#212121}.dark-theme .aplayer .aplayer-info{border-top-color:#212121}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-title{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-author{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time{color:#eee}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path{fill:#eee}.dark-theme .aplayer .aplayer-list{background-color:#212121}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb{background-color:#999}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb:hover{background-color:#bbb}.dark-theme .aplayer .aplayer-list li{color:#fff;border-top-color:#666}.dark-theme .aplayer .aplayer-list li:hover{background:#4e4e4e}.dark-theme .aplayer .aplayer-list li.aplayer-list-light{background:#6c6c6c}.dark-theme .aplayer .aplayer-list li .aplayer-list-index{color:#ddd}.dark-theme .aplayer .aplayer-list li .aplayer-list-author{color:#ddd}.dark-theme .aplayer .aplayer-lrc{text-shadow:-1px -1px 0 #666}.dark-theme .aplayer .aplayer-lrc:before{background:-moz-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:-webkit-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:linear-gradient(to bottom, #212121 0%, rgba(33,33,33,0) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#212121', endColorstr='#00212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc:after{background:-moz-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:-webkit-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:linear-gradient(to bottom, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#00212121', endColorstr='#cc212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc p{color:#fff}.dark-theme .aplayer .aplayer-miniswitcher{background:#484848}.dark-theme .aplayer .aplayer-miniswitcher .aplayer-icon path{fill:#eee}</style>
<script src="https://fastly.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script>
  var meting_api='https://api.injahow.cn/meting/?server=:server&type=:type&id=:id&auth=:auth&r=:r';
</script>
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/Meting.min.js"></script>

{{- if .IsNamedParams -}}
    {{- if .Get "url" -}}
        <meting-js url="{{ .Get `url` }}" name="{{ .Get `name` }}" artist="{{ .Get `artist` }}" cover="{{ .Get `cover` }}" theme="{{ .Get `theme` | default `#2980b9` }}"
        {{- with .Get "fixed" }} fixed="{{ . }}"{{ end -}}
        {{- with .Get "mini" }} mini="{{ . }}"{{ end -}}
        {{- with .Get "autoplay" }} autoplay="{{ . }}"{{ end -}}
        {{- with .Get "volume" }} volume="{{ . }}"{{ end -}}
        {{- with .Get "mutex" }} mutex="{{ . }}"{{ end -}}
        ></meting-js>
    {{- else if .Get "auto" -}}
        <meting-js auto="{{ .Get `auto` }}" theme="{{ .Get `theme` | default `#2980b9` }}"
        {{- with .Get "fixed" }} fixed="{{ . }}"{{ end -}}
        {{- with .Get "mini" }} mini="{{ . }}"{{ end -}}
        {{- with .Get "autoplay" }} autoplay="{{ . }}"{{ end -}}
        {{- with .Get "loop" }} loop="{{ . }}"{{ end -}}
        {{- with .Get "order" }} order="{{ . }}"{{ end -}}
        {{- with .Get "volume" }} volume="{{ . }}"{{ end -}}
        {{- with .Get "mutex" }} mutex="{{ . }}"{{ end -}}
        {{- with .Get "list-folded" }} list-folded="{{ . }}"{{ end -}}
        {{- with .Get "list-max-height" }} list-max-height="{{ . }}"{{ end -}}
        ></meting-js>
    {{- else -}}
        <meting-js server="{{ .Get `server` }}" type="{{ .Get `type` }}" id="{{ .Get `id` }}" theme="{{ .Get `theme` | default `#2980b9` }}"
        {{- with .Get "fixed" }} fixed="{{ . }}"{{ end -}}
        {{- with .Get "mini" }} mini="{{ . }}"{{ end -}}
        {{- with .Get "autoplay" }} autoplay="{{ . }}"{{ end -}}
        {{- with .Get "loop" }} loop="{{ . }}"{{ end -}}
        {{- with .Get "order" }} order="{{ . }}"{{ end -}}
        {{- with .Get "volume" }} volume="{{ . }}"{{ end -}}
        {{- with .Get "mutex" }} mutex="{{ . }}"{{ end -}}
        {{- with .Get "list-folded" }} list-folded="{{ . }}"{{ end -}}
        {{- with .Get "list-max-height" }} list-max-height="{{ . }}"{{ end -}}
        ></meting-js>
    {{- end -}}
{{- else if strings.HasSuffix (.Get 0) "http" -}}
    <meting-js auto="{{ .Get 0 }}" theme="#2980b9"></meting-js>
{{- else -}}
    <meting-js server="{{ .Get 0 }}" type="{{ .Get 1 }}" id="{{ .Get 2 }}" theme="#2980b9"></meting-js>
{{- end -}}
{{- $scratch.Set "music" true -}}

下载APlayer.min.cssAPlayer.min.css放入/static文件夹内,并修改样式:

/* /static/APlayer.min.css */
.aplayer {
    max-width: 75%;
    background: #fdfdfd;
    font-family: Arial, Helvetica, sans-serif;
    margin: 1em auto;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .25);
    border-radius: 8px;
    overflow: hidden;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    line-height: normal;
    position: relative
}
.aplayer.aplayer-withlrc .aplayer-pic {
    height: 120px;
    width: 120px;
}
.aplayer.aplayer-withlrc .aplayer-info {
    margin-left: 130px;
    height: 120px;
    padding: 10px 7px 0
}

使用示例,在.md文件中使用:

{{< music auto="https://music.163.com/song?id=1811946808">}}

图片限宽、居中与图注 #

限宽80%,并居中。效果:

这是图注:GrocyCompanionCN 这是图注:GrocyCompanionCN

/* /themes/hugo-book/assets/_markdown.scss */
  img {
    max-width: 80%;
    height: auto;
    display: block;
    margin: auto;
    text-align: center;
  }

图片下方添加图注,图注按照markdown格式自动拾取:[图注](图片链接)

<!-- /themes/hugo-book/layouts/_default/_markup/render-image.html -->
{{- if .Page.Site.Params.BookPortableLinks -}}
  {{- template "portable-image" . -}}
{{- else -}}
  {{- if .Text}}
    <div class="image-caption">
      <img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title }}title="{{ . }}"{{ end }}/>
      {{ .Text}}
    </div>
  {{- else -}}
    <img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title }}title="{{ . }}"{{ end }}/> 
  {{- end -}}
{{- end -}}
/* /themes/hugo-book/assets/_custom.scss */
.image-caption {
  font-size: small;
  margin-top: 2px;
  color: gray;
  text-align: center;
}

图片轮播 #

效果:

banner swiper
<!-- /themes/hugo-book/layouts/shortcodes/swiper.html -->
{{ $caption := .Get "caption" }}
{{ $images := .Get "img" }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/css/swiper.min.css">
<!-- Swiper -->
<div class="swiper-container">
    <div class="swiper-wrapper">
        {{ $itItems := split $images "," }}
        {{range $itItems }}
        <div class="swiper-slide">
            <img src="{{.}}" alt="">
        </div>
        {{end}}
    </div>
    <!-- Add Pagination -->
    <div class="swiper-pagination"></div>
    <div class="image-caption">{{ $caption }}</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/3.4.2/js/swiper.min.js"></script>
    <!-- Initialize Swiper -->
    <script>
    var swiper = new Swiper('.swiper-container', {
        pagination: '.swiper-pagination',
        paginationClickable: true,
    //自动调节高度
    autoHeight: true,
    //键盘左右方向键控制
    keyboardControl : true,
    //鼠标滑轮控制
    mousewheelControl : true,
    autoplay : 5000,
    lazyLoading : true,
    lazyLoadingInPrevNext : true,
    //无限循环
    loop : true,
    });
    </script>
/* /themes/hugo-book/assets/_custom.scss */
.swiper-container {
  max-width: 800px !important;
  margin: auto;
}
.swiper-slide {
  text-align: center;
  font-size: 18px;
  background-color: #fff;
  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}

使用示例,在.md文件中使用:

{{< swiper caption="banner swiper" img="https://img.osnsyc.top/c18921c.png,https://img.osnsyc.top/fff816.png,https://img.osnsyc.top/af557a.png" >}}

代码块主题与限高 #

主题设置。

# /hugo.toml
[markup]
  [markup.highlight]
      style = 'paraiso-dark'     # style demos https://pygments.org/demo/

代码块限高,我设置的限高30行,根据需求自行修改。

/* /themes/hugo-book/assets/_markdown.scss */
  pre {
    direction: ltr;
    unicode-bidi: embed;
    padding: $padding-16;
    background: var(--gray-100);
    border-radius: $border-radius;
    overflow-x: auto;
    max-height: 30em; //限高30行

    code {
      padding: 0;
      background: none;
    }
  }

效果如下:

void UpdateEink(){
  HTTPClient http;
  http.begin("https://YOUR_SITE.COM");
  int httpCode = http.GET();
  if(httpCode > 0) {
      if(httpCode == HTTP_CODE_OK) {
          int len = http.getSize();
          // create buffer for read
          uint8_t buff[1280] = { 0 };
          // get tcp stream
          WiFiClient * stream = http.getStreamPtr();
          // read all data from server
          int numData = 0;
          String headString = "";
          while(http.connected() && (len > 0 || len == -1)) {
              // get available data size
              size_t size = stream->available();
              int c = 0;
              if(size) {
                  // read up to 1280 byte
                  c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
                  String responseString((char*)buff, c);
                  responseString = headString + responseString;
                  String temp = ""; 
                  for (int i = 0; i < responseString.length(); i++) {
                    char cAti = responseString.charAt(i);
                    if (cAti == ',') { 
                      if (numData < 67200){
                        gImage_5in65f_part1[numData] = temp.toInt();
                      } else if(numData == 67200){
                        DEV_Module_Init();
                        EPD_5IN65F_Init();                              
                        EPD_5IN65F_Display_begin();
                        EPD_5IN65F_Display_sendData(gImage_5in65f_part1);
                        gImage_5in65f_part1[numData-67200] = temp.toInt();
                      } else if(numData > 67200 && numData < 134399){
                        gImage_5in65f_part1[numData-67200] = temp.toInt();
                      } else if(numData == 134399){
                        gImage_5in65f_part1[numData-67200] = temp.toInt();
                        EPD_5IN65F_Display_sendData(gImage_5in65f_part1);
                        EPD_5IN65F_Display_end();
                        EPD_5IN65F_Sleep();
                      }
                      temp = "";
                      numData++;
                    } else {
                      temp += cAti;
                    }
                  }
                  if (temp.length() > 0) { // 处理最后一个数字
                    headString = temp;
                  } else{
                    headString = "";
                  }
                  if(len > 0) {
                      len -= c;
                  }
                }
          }
      }
  }
  http.end();
}

站点年龄、文章数与字数统计 #

添加站点年龄、文章数与字数统计,修改<ul>...</ul>内的样式以定义显示格式,效果如下:

  • 博客已存活 12 天,总文章数 9 篇,总计字数 41043 字。
<!-- /themes/hugo-book/layouts/shortcodes/sitecount.html -->
{{- $scratch := newScratch -}}
{{- range (where .Site.RegularPages "Section" "posts") -}}
  {{- $scratch.Add "total" .WordCount -}}
{{- end -}}
{{- $siteStart := time "2024-11-23" -}}
{{- $daysAlive := div (sub (now.Unix) $siteStart.Unix) 86400 -}}
{{- $totalWords := $scratch.Get "total" -}}

<ul>
  <li>博客已存活 {{ $daysAlive }} 天,总文章数 {{ len (where .Site.RegularPages "Section" "posts") }} 篇,总计字数 {{ $totalWords }} 字。</li>
</ul>

使用示例,在.md文件中使用:

{{< sitecount >}}

参考链接 #

前一篇 样式 | Style 随机阅读 Hugo博客快速搭建... 后一篇