Contents

Insert partner/friend page in hugo

Introduction

Hugo, as a static website generator, has many features we want but lacks some functionalities. Fortunately, Hugo supports custom HTML and CSS, allowing us to add desired features to our website. The following guide explains how to add a custom partner/friend page in Hugo.

Adding Partner/Friend Cards

Using a card format instead of traditional hyperlinks to partner websites is both visually appealing and practical.

https://raw.githubusercontent.com/Josh-test-lab/website-assets-repository/refs/heads/main/posts/Insert%20partner%20or%20friend%20page%20in%20hugo/friend_page_before_and_after.png
The left image shows the hyperlink format, while the right image displays the card format.

Creating the friend.html File

In the website’s root directory, navigate to /layouts/shortcodes/ and create a new file named friend.html. Then, insert the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{ if .IsNamedParams }}
    {{- $src := .Get "logo" -}}
    {{- $small := .Get "logo_small" | default $src -}}
    {{- $large := .Get "logo_large" | default $src -}}
    <div class="friend-div">
        <a target="_blank" href={{ .Get "url" | safeURL }} title={{ .Get "name" }} >
        <img class="lazyload"
            src="/svg/loading.min.svg"
            data-src={{ $src | safeURL }}
            alt={{ .Get "name" }}
        data-sizes="auto"
        data-srcset="{{ $small | safeURL }}, {{ $src | safeURL }} 1.5x, {{ $large | safeURL }} 2x" />
        <span class="friend-name">{{ .Get "name" }}</span>
        <span class="friend-info">{{ .Get "word" }}</span>
        </a>
    </div>
{{ end }}

Create the _friend.scss File

In the website’s root directory, navigate to /assets/css/_partial/_single/ and create a new file named _friend.scss. Then, insert the following content:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#article-container {
    word-wrap: break-word;
    overflow-wrap: break-word
}

#article-container a {
    color: #49b1f5
}

#article-container a:hover {
    text-decoration: underline
}

#article-container img {
    margin: 0 auto .8rem
}

.flink#article-container .friend-list-div > .friend-div a .friend-info,
.flink#article-container .friend-list-div > .friend-div a .friend-name {
    overflow: hidden;
    -o-text-overflow: ellipsis;
    text-overflow: ellipsis;
    white-space: nowrap
}

.flink#article-container .friend-list-div {
    overflow: auto;
    padding: 10px 10px 0;
    text-align: center;
}
.flink#article-container .friend-list-div > .friend-div {
    position: relative;
    float: left;
    overflow: hidden;
    margin: 15px 7px;
    width: calc(100% / 3 - 15px);
    height: 90px;
    border-radius: 8px;
    line-height: 17px;
    -webkit-transform: translateZ(0)
}

@media screen and (max-width: 1100px) {
    .flink#article-container .friend-list-div > .friend-div {
    width: calc(50% - 15px) !important
    }

    @media screen and (max-width: 600px) {
        .flink#article-container .friend-list-div > .friend-div {
        width: calc(100% - 15px) !important
        }
    }
}

.flink#article-container .friend-list-div > .friend-div:hover {
    background: rgba(87, 142, 224, 0.15);
}

.flink#article-container .friend-list-div > .friend-div:hover img {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    transform: rotate(360deg)
}

.flink#article-container .friend-list-div > .friend-div:before {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    background: var(--text-bg-hover);
    content: '';
    -webkit-transition: -webkit-transform .3s ease-out;
    -moz-transition: -moz-transform .3s ease-out;
    -o-transition: -o-transform .3s ease-out;
    -ms-transition: -ms-transform .3s ease-out;
    transition: transform .3s ease-out;
    -webkit-transform: scale(0);
    -moz-transform: scale(0);
    -o-transform: scale(0);
    -ms-transform: scale(0);
    transform: scale(0)
}
.flink#article-container .friend-list-div > .friend-div:hover:before,
.flink#article-container .friend-list-div > .friend-div:focus:before,
.flink#article-container .friend-list-div > .friend-div:active:before {
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -o-transform: scale(1);
    -ms-transform: scale(1);
    transform: scale(1)
}
.flink#article-container .friend-list-div > .friend-div a {
    color: var(--font-color);
    text-decoration: none
}

.flink#article-container .friend-list-div > .friend-div a img{
    float: left;
    margin: 15px 10px;
    width: 60px;
    height: 60px;
    border-radius: 35px;
    -webkit-transition: all .3s;
    -moz-transition: all .3s;
    -o-transition: all .3s;
    -ms-transition: all .3s;
    transition: all .3s
}

.flink#article-container .friend-list-div > .friend-div a .friend-name {
    display: block;
    padding: 16px 10px 0 0;
    height: 40px;
    font-weight: 700;
    font-size: 20px
}

.flink#article-container .friend-list-div > .friend-div a .friend-info {
    display: block;
    padding: 1px 10px 1px 0;
    height: 50px;
    font-size: 13px
}

Import the Code in _single.scss

In the website’s root directory, navigate to /assets/css/_page/, locate the _single.scss file, and insert the following content:

1
@import "../_partial/_single/friend";

Using Partner/Friend Cards

After completing the above steps, we can use the following shortcodes to insert partner/friend cards in different articles.

1
2
3
4
5
6
7
8
<div class="flink" id="article-container">
<div class="friend-list-div" >

{{< friend name="Partner 1 Name" url="Partner 1 Website URL" logo="Partner 1 Logo URL" word="Partner 1 Description" >}}
{{< friend name="Partner 2 Name" url="Partner 2 Website URL" logo="Partner 2 Logo URL" word="Partner 2 Description" >}}

</div>
</div>
Note
  1. Remember to include two </div> tags when writing the shortcodes.
  2. The Partner 1 Logo URL can be replaced with any image URL, but a 1:1 ratio (square) is recommended.

The displayed effect is as follows.

Adding a Partner Page

Now, we can create a page specifically to store partner/friend cards. Of course, the following steps are not mandatory to follow exactly as I have; you can create your own style for the page.

Creating the Card Storage Page

In the website’s root directory, navigate to /content/ and create a /friend/ folder (subdirectory). Inside this folder, add the index.zh-tw.md and index.en.md markdown files for the webpages.

Note
If your website is single-language, you only need to add index.your-language-code.md. If your website supports multiple languages, add the corresponding index.your-language-code.md files for each language supported by your site.

Create the friend_page.html File

In the website’s root directory, navigate to /layouts/shortcodes/ and create a new file named friend_page.html. Then, insert the following content:

1
2
3
4
5
6
7
8
9
{{- $language := .Site.Language.Lang -}}
{{- $page := .Site.GetPage "page" (printf "/friend/index.%s.md" $language) -}}
{{- if $page -}}
  <div class="friend-content">
    {{- $page.Content -}}  <!-- Load the corresponding language's friend page content -->
  </div>
{{- else -}}
  <p>Cannot load friend page.</p>
{{- end -}}

The above effect means that by using

1
{{< friend_page >}}

Hugo will automatically select the appropriate language and display the corresponding partner page from the /content/friend/ directory in the website’s root.

Conclusion

Actually, I am not very familiar with Hugo’s shortcode, but perhaps because I am experienced with other programming languages, I was able to solve the bugs I encountered during this implementation. Website beautification tests the hands-on ability of every website operator, and being able to create both beautiful and functional features really brings a sense of accomplishment.

Environment

  • Hugo 0.144.2
  • LoveIt theme (version from GitHub on February 21, 2025)

References

License

Some content of this article is reproduced, adapted, and forwarded with the permission of the original author, Stilig, as referenced in the source. The rest of the content is original.

The content of this article is partially reproduced, adapted, and forwarded with the permission of the original author, Stilig, as referenced in the source. Authorized images.