目录

Hugo 白话文 | 添加友情链接

基友遍四海,友链不可少

本文介绍如何在 hugo 中添加友情链接

一、前言

使用 Hugo 搭建博客的你是否还在为没有友情链接而烦恼,阅读本文将为你制作属于自己的友情链接提供解决方案。

二、友情链接

2.1 效果

先看咋们的效果图

真实效果:

首页:

https://raw.githubusercontent.com/cityiron/tuchuang/master/blog/yqlj.jpg

点击后:

https://raw.githubusercontent.com/cityiron/tuchuang/master/blog/htl.yqlj.02.jpg

手机端:

https://raw.githubusercontent.com/cityiron/tuchuang/master/blog/htl.yqlj.03.jpg

2.2 制作过程

2.2.1 增加菜单栏

 1[languages]
 2  [languages.en]
 3    ......
 4    [languages.en.menu]
 5      ......
 6      [[languages.en.menu.main]]
 7        identifier = "friend"
 8        pre = ""
 9        post = ""
10        name = "Friend"
11        url = "/friend/"
12        title = ""
13        weight = 5
14      ......
15    [languages.en.params]
16      ......

首先在 menu 增加一个菜单项为 friend 表示友情链接,上面是多语言的版本,不是多语言也是一样的逻辑。

2.2.2 制作 shortcodes

2.2.2.1 创建 html

在你博客的路径 /xxx/blog/layouts/shortcodes/ 下创建 friend.html 文件。

 1{{ if .IsNamedParams }}
 2    {{- $src := .Get "logo" -}}
 3    {{- $small := .Get "logo_small" | default $src -}}
 4    {{- $large := .Get "logo_large" | default $src -}}
 5    <div class="flink" id="article-container">
 6      <div class="friend-list-div" >
 7        <div class="friend-div">
 8            <a target="_blank" href={{ .Get "url"  | safeURL }} title={{ .Get "name" }} >
 9                <img class="lazyload"
10                     src="/svg/loading.min.svg"
11                     data-src={{ $src | safeURL }}
12                     alt={{ .Get "name" }}
13                     data-sizes="auto"
14                     data-srcset="{{ $small | safeURL }}, {{ $src | safeURL }} 1.5x, {{ $large | safeURL }} 2x" />
15                <span class="friend-name">{{ .Get "name" }}</span>
16                <span class="friend-info">{{ .Get "word" }}</span>
17            </a>
18        </div>
19      </div>
20    </div>
21{{ end }}
  • .Get 是 hugo shortcodes 的用法,可以获取到属性
2.2.2.2 创建 scss

样式基本上就是拿来用了,没改过

  • assets/css/_partial/_single/ 下面新建 _friend.scss 文件
  1#article-container {
  2 word-wrap: break-word;
  3 overflow-wrap: break-word
  4}
  5
  6#article-container a {
  7 color: #49b1f5
  8}
  9
 10#article-container a:hover {
 11 text-decoration: underline
 12}
 13
 14#article-container img {
 15 margin: 0 auto .8rem
 16}
 17
 18.flink#article-container .friend-list-div > .friend-div a .friend-info,
 19.flink#article-container .friend-list-div > .friend-div a .friend-name {
 20 overflow: hidden;
 21 -o-text-overflow: ellipsis;
 22 text-overflow: ellipsis;
 23 white-space: nowrap
 24}
 25
 26.flink#article-container .friend-list-div {
 27 overflow: auto;
 28 padding: 10px 10px 0;
 29 text-align: center;
 30}
 31.flink#article-container .friend-list-div > .friend-div {
 32 position: relative;
 33 float: left;
 34 overflow: hidden;
 35 margin: 15px 7px;
 36 width: calc(100% / 3 - 15px);
 37 height: 90px;
 38 border-radius: 8px;
 39 line-height: 17px;
 40 -webkit-transform: translateZ(0)
 41}
 42
 43@media screen and (max-width: 1100px) {
 44 .flink#article-container .friend-list-div > .friend-div {
 45  width: calc(50% - 15px) !important
 46 }
 47
 48@media screen and (max-width: 600px) {
 49 .flink#article-container .friend-list-div > .friend-div {
 50  width: calc(100% - 15px) !important
 51 }
 52}
 53}
 54
 55.flink#article-container .friend-list-div > .friend-div:hover {
 56 background: rgba(87, 142, 224, 0.15);
 57}
 58
 59.flink#article-container .friend-list-div > .friend-div:hover img {
 60 -webkit-transform: rotate(360deg);
 61 -moz-transform: rotate(360deg);
 62 -o-transform: rotate(360deg);
 63 -ms-transform: rotate(360deg);
 64 transform: rotate(360deg)
 65}
 66
 67.flink#article-container .friend-list-div > .friend-div:before {
 68 position: absolute;
 69 top: 0;
 70 right: 0;
 71 bottom: 0;
 72 left: 0;
 73 z-index: -1;
 74 background: var(--text-bg-hover);
 75 content: '';
 76 -webkit-transition: -webkit-transform .3s ease-out;
 77 -moz-transition: -moz-transform .3s ease-out;
 78 -o-transition: -o-transform .3s ease-out;
 79 -ms-transition: -ms-transform .3s ease-out;
 80 transition: transform .3s ease-out;
 81 -webkit-transform: scale(0);
 82 -moz-transform: scale(0);
 83 -o-transform: scale(0);
 84 -ms-transform: scale(0);
 85 transform: scale(0)
 86}
 87.flink#article-container .friend-list-div > .friend-div:hover:before,
 88.flink#article-container .friend-list-div > .friend-div:focus:before,
 89.flink#article-container .friend-list-div > .friend-div:active:before {
 90 -webkit-transform: scale(1);
 91 -moz-transform: scale(1);
 92 -o-transform: scale(1);
 93 -ms-transform: scale(1);
 94 transform: scale(1)
 95}
 96.flink#article-container .friend-list-div > .friend-div a {
 97 color: var(--font-color);
 98 text-decoration: none
 99}
100
101.flink#article-container .friend-list-div > .friend-div a img{
102 float: left;
103 margin: 15px 10px;
104 width: 60px;
105 height: 60px;
106 border-radius: 35px;
107 -webkit-transition: all .3s;
108 -moz-transition: all .3s;
109 -o-transition: all .3s;
110 -ms-transition: all .3s;
111 transition: all .3s
112}
113
114.flink#article-container .friend-list-div > .friend-div a .friend-name {
115 display: block;
116 padding: 16px 10px 0 0;
117 height: 40px;
118 font-weight: 700;
119 font-size: 20px
120}
121
122.flink#article-container .friend-list-div > .friend-div a .friend-info {
123 display: block;
124 padding: 1px 10px 1px 0;
125 height: 50px;
126 font-size: 13px
127}
  • assets/css/_page/ 下面新建 _single.scss 文件

把主题 /themes/loveIt/assets/css/_page/_single.scss 的文件拷贝到博客项目指定目录,关键在于添加一行 @import "../_partial/_single/_friend";

  1@import "../_partial/_single/toc";
  2@import "../_partial/_single/_friend";
  3
  4.single {
  5  .single-title {
  6    margin: 1rem 0 .5rem;
  7    font-size: 1.6rem;
  8    font-weight: bold;
  9    line-height: 140%;
 10  }
 11
 12  .single-subtitle {
 13    margin: .4rem 0;
 14    font-size: 1.2rem;
 15    font-weight: normal;
 16    font-style: italic;
 17    line-height: 100%;
 18  }
 19
 20  .post-meta {
 21    font-size: .875rem;
 22    color: $global-font-secondary-color;
 23
 24    span {
 25      display: inline-block;
 26    }
 27
 28    [theme=dark] & {
 29      color: $global-font-secondary-color-dark;
 30    }
 31
 32    @include link(false, true);
 33
 34    .author {
 35      font-size: 1.05rem;
 36    }
 37  }
 38
 39  .featured-image {
 40    margin: .5rem 0 1rem 0;
 41
 42    img {
 43      display: block;
 44      max-width: 100%;
 45      height: auto;
 46      margin: 0 auto;
 47      overflow: hidden;
 48    }
 49
 50    img.lazyloaded {
 51      width: 100%;
 52    }
 53  }
 54
 55  .content {
 56    > h2 {
 57      font-size: 1.5rem;
 58
 59      & code {
 60        font-size: 1.25rem;
 61      }
 62    }
 63
 64    > h3 {
 65      font-size: 1.375rem;
 66
 67      & code {
 68        font-size: 1.125rem;
 69      }
 70    }
 71
 72    > h4 {
 73      font-size: 1.25rem;
 74
 75      & code {
 76        font-size: 1rem;
 77      }
 78    }
 79
 80    > h5 {
 81      font-size: 1.125rem;
 82    }
 83
 84    > h6 {
 85      font-size: 1rem;
 86    }
 87
 88    h2,
 89    h3,
 90    h4,
 91    h5,
 92    h6 {
 93      font-weight: bold;
 94      margin: 1.2rem 0;
 95
 96      [theme=dark] & {
 97        font-weight: bolder;
 98      }
 99    }
100
101    > h2,
102    > h3,
103    > h4,
104    > h5,
105    > h6 {
106      > .header-mark::before {
107        content: "|";
108        margin-right: .3125rem;
109        color: $single-link-color;
110
111        [theme=dark] & {
112          color: $single-link-color-dark;
113        }
114      }
115    }
116
117    > h2 > .header-mark::before {
118      content: "#";
119    }
120
121    p {
122      margin: .5rem 0;
123    }
124
125    b, strong {
126      font-weight: bold;
127
128      [theme=dark] & {
129        color: #ddd;
130      }
131    }
132
133    @include link(false, false);
134
135    a {
136      @include overflow-wrap(break-word);
137
138      [theme=dark] & b, [theme=dark] & strong {
139        color: $single-link-color-dark;
140      }
141    }
142
143    [theme=dark] a:hover b, [theme=dark] a:hover strong {
144      color: $single-link-hover-color-dark;
145    }
146
147    ul, ol {
148      margin: .5rem 0;
149      padding-left: 2.5rem;
150    }
151
152    ul {
153      list-style-type: disc;
154    }
155
156    ruby {
157      background: $code-background-color;
158
159      rt {
160        color: $global-font-secondary-color;
161      }
162
163      [theme=dark] & {
164        background: $code-background-color-dark;
165
166        rt {
167          color: $global-font-secondary-color-dark;
168        }
169      }
170    }
171
172    .table-wrapper {
173      overflow-x: auto;
174
175      &::-webkit-scrollbar {
176        background-color: $table-background-color;
177
178        [theme=dark] & {
179          background-color: $table-background-color-dark;
180        }
181      }
182
183      > table {
184        width: 100%;
185        max-width: 100%;
186        margin: .625rem 0;
187        border-spacing: 0;
188        background: $table-background-color;
189        border-collapse: collapse;
190
191        [theme=dark] & {
192          background: $table-background-color-dark;
193        }
194
195        thead {
196          background: $table-thead-color;
197
198          [theme=dark] & {
199            background-color: $table-thead-color-dark;
200          }
201        }
202
203        th, td {
204          padding: .3rem 1rem;
205          border: 1px solid darken($table-thead-color, 2%);
206
207          [theme=dark] & {
208            border-color: darken($table-thead-color-dark, 2%);
209          }
210        }
211      }
212    }
213
214    img {
215      max-width: 100%;
216      min-height: 1em;
217    }
218
219    figure {
220      margin: .5rem;
221      text-align: center;
222
223      .image-caption:not(:empty) {
224        min-width: 20%;
225        max-width: 80%;
226        display: inline-block;
227        padding: .5rem;
228        margin: 0 auto;
229        font-size: .875rem;
230        color: #969696;
231      }
232
233      img {
234        display: block;
235        height: auto;
236        margin: 0 auto;
237        overflow: hidden;
238      }
239    }
240
241    .lazyloading {
242      @include object-fit(none);
243    }
244
245    blockquote {
246      display: block;
247      border-left: .5rem solid $blockquote-color;
248      background-color: rgba($blockquote-color, .2);
249      padding: .25rem .75rem;
250      margin: 1rem 0;
251
252      [theme=dark] & {
253        border-left-color: $blockquote-color-dark;
254        background-color: rgba($blockquote-color-dark, .2);
255      }
256    }
257
258    .footnotes {
259      color: $global-font-secondary-color;
260
261      [theme=dark] & {
262        color: $global-font-secondary-color-dark;
263      }
264
265      p {
266        margin: .25rem 0;
267      }
268    }
269
270    @import "../_partial/_single/code";
271    @import "../_partial/_single/instagram";
272    @import "../_partial/_single/admonition";
273    @import "../_partial/_single/echarts";
274    @import "../_partial/_single/mapbox";
275    @import "../_partial/_single/music";
276    @import "../_partial/_single/bilibili";
277
278    hr {
279      margin: 1rem 0;
280      position: relative;
281      border-top: 1px dashed $global-border-color;
282      border-bottom: none;
283
284      [theme=dark] & {
285        border-top: 1px dashed $global-border-color-dark;
286      }
287    }
288
289    kbd {
290      display: inline-block;
291      padding: .25rem;
292      background-color: $global-background-color;
293      border: 1px solid $global-border-color;
294      border-bottom-color: $global-border-color;
295      @include border-radius(3px);
296      @include box-shadow(inset 0 -1px 0 $global-border-color);
297      font-size: .8rem;
298      font-family: $code-font-family;
299      color: $code-color;
300
301      [theme=dark] & {
302        background-color: $global-background-color-dark;
303        border: 1px solid $global-border-color-dark;
304        border-bottom-color: $global-border-color-dark;
305        @include box-shadow(inset 0 -1px 0 $global-border-color-dark);
306        color: $code-color-dark;
307      }
308    }
309
310    .typeit {
311      .code {
312        padding: .375rem;
313        font-size: .875rem;
314        font-family: $code-font-family;
315        font-weight: bold;
316        word-break: break-all;
317      }
318    }
319
320    .version {
321      height: 1.25em;
322      vertical-align: text-bottom;
323    }
324  }
325
326  @import "../_partial/_single/footer";
327  @import "../_partial/_single/comment";
328}
329
330.lg-toolbar .lg-icon::after {
331  color: #999;
332}

2.3 添加内容

content/friend 下新建 index.语言.md

1---
2hiddenFromSearch: true
3---
4{{< friend name="Z字骚年" url="https://zouyx.github.io/" logo="https://avatars.githubusercontent.com/u/3828072?v=4&s=160" word="Joe Zou's Blog" >}}
5{{< friend name="张其" url="https://blog.csdn.net/u010927340" logo="https://avatars3.githubusercontent.com/u/12484497?v=4&s=160" word="张其的博客" >}}
  • 头部 --- 是必须的,如果直接加内容会出现如下错误:
1ERROR 2020/12/08 19:16:14 Rebuild failed:                                                     │@1154] - Unable to reconnect to ZooKeeper service, session 0x10001c32b1e001e has expired, clos                                                                                              │ing socket connection
2ERROR 2020/12/08 19:16:14 "/Users/tc/Documents/workspace_2020/blog/content/friend/index.tc.md:│2020-12-08 01:13:40,558 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@519] - EventT
31:1": unmarshal failed: invalid character '{' looking for beginning of object key string

避免

  • friend 介绍

参数都是在 html 中通过 .Get 获取的,比较简单直观,直接看 创建 html 部分即可。

三、参考

https://gohugo.io/templates/shortcode-templates/

https://github.com/kkkgo/hugo-friendlinks/

https://blog.233so.com/2020/04/friend-link-shortcodes-for-hugo-loveit/