eallion

大大的小蜗牛

机会总是垂青于有准备的人!
mastodon
github
twitter
steam
telegram
keybase
email

Hugo 外部連結跳轉提示頁面

前言#

這兩天看到「秦大叔」的部落格文章《網站重啟》提到,因為部落格評論中別人留下的域名過期被黃網連結到了黃網,從而導致因涉黃問題而喝茶。可見在大陸目前的網絡環境下,這種可大可小的口袋罪收得越來越緊。

為了合規和自我審查,我對部落格做了 2 件事,一是把評論系統遷移到了 Giscus,這提高了一定的評論門檻,讓評論處於半關閉狀態;二是清理了一些部落格中的連結,讓剩下的連結通過跳轉頁面跳轉。剛好看到「空白」大佬更新了部落格《HUGO 外鏈跳轉到中間頁》,直接把樣式抄過來,算是完成了一件 Todo list。

PS:我覺得正經的個人網站可以備案。但如果你想做不正經的,那你要做的是完全的身份隔離,而不是僅僅不備案卻暴露很多關聯的交叉實名信息。沒有爹味,愛聽不聽。

定義#

外鏈:全稱為外部連結,又稱導入連結。就是指從互聯網上別的網站導入到自己網站的連結。以下簡稱「外鏈」。

3 個文件創建跳轉頁面#

我的設計思路與「空白」的第一版 JS 的方式不太一樣,我利用 Hugo 內置模板 _markuprender-link.html,在 Hugo 構建時就把外鏈用 Hugo 內置的 base64Encode 命令進行 base64 編碼,充分利用了 SSG 的特性。

1. 新建或者修改 render-link.html#

_markup/render-link.html 是 Hugo 渲染連結的內置模板。
如果部落格選用的主題沒有自定義 render-link.html,那需要自己新建一個此文件,如果主題已經自定義過連結渲染的,那就可以直接修改此文件。
文件位於 Hugo 項目根目錄的 layouts 目錄:

layouts/
└── _default/
    └── _markup/
        ├── render-codeblock-bash.html
        ├── render-codeblock.html
        ├── render-heading.html
        ├── render-image.html
        ├── render-image.rss.xml
        └── render-link.html    # < --- 此文件

我用的文件內容:

$domainList 相當於一個白名單。

{{- $domainList := slice "www.eallion.com" "github.com" "twitter.com" -}}
{{- $parsedDestination := urls.Parse .Destination -}}
{{- $host := $parsedDestination.Host -}}
{{- $matched := false -}}
{{- range $domainList -}}
    {{- if strings.HasSuffix $host . -}}
        {{- $matched = true -}}
        {{- break -}}
    {{- end -}}
{{- end -}}
{{- if $matched -}}
    <a href="/go/?target={{ .Destination }}" target="_blank" rel="noopener noreferrer">{{ .Text | safeHTML}}</a>
{{- else -}}
    <a href="/go/?target={{ .Destination | base64Encode }}" target="_blank" rel="noopener noreferrer">{{ .Text | safeHTML}}</a>
{{- end -}}

PS:DoIt 主題只需要修改 layouts/partials/plugin/link.html 文件。

Tips:利用 render-link.html 可以讓部落格實現新窗口打開,即 taget="_blank"。很多亞洲用戶都在搜索這個技巧呢。

2. 新建 layout 模板 go.html#

新建一個頁面模板,如:go.html,位於 Hugo 項目根目錄的 layouts/_default/go.html
一個最簡單的辦法是複製 single.html 並重命名為 go.html

layouts/
└── _default/
    └── go.html    # < --- 此文件

下面是我的內容,把 HTML CSS 和 JS 放置到了同一個頁面中,方便維護。除了需要注意 <div class="redirect-all"> 元素位於自己的模板的位置,基本上是開箱即用。

{{- define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end -}}

{{- define "content" -}}
    {{- $params := .Scratch.Get "params" -}}
    <style>
        .redirect-all {
            position: relative;
            box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px;
            border-radius: 10px;
            color: #666;
            word-break: break-all;
            max-width: 800px;
            height: 400px;
            text-align: center;
            font-size: 0.85rem;
            overflow: hidden;
            margin: 100px auto 0;
            background: #fff url(/assets/images/redirect/redirect-light.webp) no-repeat center center / cover;
            @include breakpoint('small') {
                aspect-ratio: 2 / 1;
                height: auto;
            }
        }

        .redirect-nrong {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 1.5rem 1rem
        }

        .redirect-title {
            font-size: 1.25rem;
            font-weight: bold;
            color: #222;
            margin-bottom: 0.5rem;
        }

        .redirect-info {
            margin-top: 6px;
        }

        .redirect-tis {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 20px;
            margin-top: 1rem;
            margin-bottom: 2px;
            flex-wrap: wrap;
        }

        .redirect-button {
            display: flex;
            align-items: center;
            border-radius: 3px;
            border: none;
            background: #006bee;
            height: 32px;
            padding: 0 14px;
            cursor: pointer;
            outline: 0;
        }

        .redirect-button a {
            color: #fff !important;
        }

        [theme=dark] .redirect-all {
                background: #fff url(/assets/images/redirect/redirect-dark.webp) no-repeat center center / cover;
                color: #999;
            }

        [theme=dark] .redirect-title {
                color: #ddd;
            }
    </style>

    <div class="page single special">

        {{- /* Content */ -}}
        <div class="content" id="content">
            <div class="redirect-all">
                <div class="redirect-nrong">
                    <div class="redirect-title">即將離開{{ .Site.Title }},跳轉到以下外部連結</div>
                    <a href="" target="_self" rel="noopener noreferrer" id="redirect-link"><span id="redirect-link">未指定重定向目標。</span></a>
                    <div class="redirect-info">請自行識別該連結是否安全,請注意您的帳號和財產安全。</div>
                    <div class="redirect-tis">
                        <div class="redirect-button"><a href='' target="_self" id='direct-link' rel="noopener noreferrer">立即前往</a></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const params = new URLSearchParams(window.location.search);
        const encodedTarget = params.get('target');
        const target = atob(encodedTarget); // 使用 atob 進行 Base64 解碼

        if (target) {

            const decodedTarget = decodeURIComponent(target);

            document.getElementById('direct-link').href = decodedTarget;
            document.getElementById('redirect-link').textContent = '' + decodedTarget; // 在新增的元素中顯示原地址
            document.getElementById('redirect-link').href = decodedTarget;

        } else {
            const redirectMessageElement = document.getElementById('redirect-link');
            redirectMessageElement.textContent = '未指定重定向目標。';
        }
        </script>
{{- end -}}

3. 新建 go.md 調用模板#

在 Hugo 項目的 content 目錄新建一個文件,名為 go.mdgo 就會是中轉頁面的連結 path。
go.md 文件的 Front matter 要選擇剛才新建的對應模板,如果模板名稱是go.html 那 layout 或者 type 都要選擇 go

---
title: "Redirect"
layout: "go"
type: "go"
... ...
---
4. 背景圖#

背景圖放在 static 的目錄下:
或者自己能正確引用的位置,如 CDN,並修改 <style> 中的 background url。
另外需要適配自己主題的 Dark mode。

  • static/assets/images/redirect/redirect-light.webp
  • static/assets/images/redirect/redirect-dark.webp

其他注意事項#

這個方法,只能渲染本部落格所有 Markdown 內容文檔,即 content 目錄下的 .md 文件。
如果習慣用 {{ Shortcodes }} 發文,或者頁面有自定義的 html 連結,需要自己做連結 path 的 base64 兼容,這個模板能解析 href="/go/?target={{ base64Encode }}" 部落格內這一類連結,白名單除外。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。