この記事はGMOペパボエンジニアアドベントカレンダー2021の4日目の記事です。

昨日は、akichanさんの「mackerel-plugin-sidekiqでキューのlatencyを計測できるようにした話」でした。 sidekiqのキューの状態を誤検知しにくくするようにした、mackerelプラグインを作成してコントリビュートするなんてすごいですね! 自分も自宅サーバーの監視にmackerelを使っているので、記事を読んでいつか自作プラグインを作りたいと思いました。

4日目の記事では、Hugoで作成しているブログのチューニングと、リッチなリンクを表示するショートコードを作成したので、その紹介をしたいと思います。

目次

Github ActionsのFTPデプロイを差分のみ行うようにして爆速にする

まず、自動デプロイのチューニングです。

過去にこの記事、「hugoを使って爆速でブログを作成する」で紹介していた自動デプロイの設定ですが、めちゃデプロイに時間がかかる・・・・ 時間がかかっているActionの様子

こんなに時間がかかっている理由は、毎回Hugoがビルドした成果物をすべてFTPでアップロードしているからです。 変更があった部分だけアップロードしてくれればいいのにと思って、いい方法ないかな〜と思っていたらありました。

同じActionsパッケージのV4.0以降は差分のみをFTPで上げてくれるようになっていたみたいです!!!

早速バージョンを上げていきましょう!!

FTP-Deploy-Actionのアップグレード

以前の記事で作成した./.github/workflows/deploy.ymlを変更していきます。

name: Deploy

on:
  push:
    branches:
      - main

jobs:

  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Setup Hugo
      uses: peaceiris/actions-hugo@v2
      with:
        hugo-version: '0.85.0'

    - name: Build
      run: hugo --minify

    - name: List output files
      run: ls public/

    - name: FTP-Deploy-Action
-      uses: SamKirkland/FTP-Deploy-Action@2.0.0   # FTPを使ってサーバーにDeployするアクションを実行
-      env:                                        
-        FTP_SERVER: ${{ secrets.FTP_SERVER }}     # FTPサーバーのURLを設定
-        FTP_USERNAME: ${{ secrets.FTP_USERNAME }} # FTPのユーザー名を設定
-        FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }} # FTPのパスワードを設定
-        LOCAL_DIR: public                           # どのディレクトリのデータをアップロードするか
-        REMOTE_DIR: /      # ロリポップ!FTPサーバのどのディレクトリにアップロードするか
+      uses: SamKirkland/FTP-Deploy-Action@4.0.0   # FTPを使ってサーバーにDeployするアクションを実行
+      with:                                        
+        server: ${{ secrets.FTP_SERVER }}     # FTPサーバーのURLを設定
+        username: ${{ secrets.FTP_USERNAME }} # FTPのユーザー名を設定
+        password: ${{ secrets.FTP_PASSWORD }} # FTPのパスワードを設定
+        local-dir: ./public/                  # どのディレクトリのデータをアップロードするか
+        server-dir: /                         # ロリポップ!FTPサーバのどのディレクトリにアップロードするか

変更の結果

これでコミットして、アクションの結果を見てみます!! 変更した初回のデプロイは今までと同じくらい時間がかかります。

変更後最初のActionの様子

このデプロイで、レンタルサーバーには.ftp-deploy-sync-state.jsonというものが作成されます。

これが、差分の情報などを持っているようなので削除しないようにしてください!!

差分の情報をサーバーが持った状態でもう一度アクションを回してみます!

変更後最初のActionの様子

爆速になりましたね!

5〜7分くらいかかっていたものが、3秒で終わりました。

OGP対応カードを表示するショートコードを追加する

2021/12/05追記

今回作成するショートコードは、スマホだと表示が崩れる、複数同ページに設置すると干渉するなど問題があったためこのブログでは使用していません。 後日改善して記事を書くつもりです。

続いて、OGP対応のリンクカードを表示するHugoのショートコードを自作したいと思います。

まず、OGPとは「Open Graph Protcol」のことで正しくサイトに設定しておくと、ツイッターなどでリッチなリンクカードを下の画像のように表示できるようになります。 ogp対応サイトのTwitterでの表示の様子

このようなリッチなリンクカードを自分のブログでも表示できるようにしたい!!

準備

ということで、Hugoで作ったこのブログにショートコードを追加して表示できるようにしてみます。

早速ショートコードを以下のようにlayouts/shortcodes/ogp.htmlを作ります。

<div id="ogp-card" class="card main-content-wrap" style="width: 80%;" data-link="test">
  <a class="ogp-a" href="{{ .Get 0 }}" target="_blank" >
    <div class="container">
        <div class="row pt-2">
          <div class="col h4 text-primary" id="site-name">
          </div>
        </div>
        <div class="row">
            <div class="col h6 text-secondary" id="url">
              {{ .Get 0}}
            </div>
          </div>
        <div class="row pt-2">
          <div class="col-8">
            <div class="row">
                <div class="col h3 text-body fw-bold" id="title"></div>
            </div>
            <div class="row h6 d-none d-md-block text-body">
                <div class="col" id="description"></div>
            </div>
          </div>
          <div class="col">
              <img id="eye-catch" src="">
          </div>
        </div>
      </div>
  </a>
</div>
<script type="text/javascript">
getOgp({{ .Get 0}})
</script>

続いて、Headで以下のものを読み込めるように追記してください。

<head>
    ....
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <script src="http://自分のサイト/js/OGP.js"></script>
    ...
</head>

続いて、カード内の要素を書き換えるJSです。

static/js/OGP.js

function getOgp(url) {
    let request = new XMLHttpRequest();
    request.open('GET', `あとで設置するAPI?url=${url}`, true);
    request.onload = function () {
        // レスポンスが返ってきた時の処理
        const res = JSON.parse(this.response);
        
        let dom1 = document.getElementById("site-name");
        dom1.textContent = res.site_name;
        let dom3 = document.getElementById("title");
        dom3.textContent = res.title;
        let dom4 = document.getElementById("description");
        dom4.textContent = res.description;
        let img = document.getElementById("eye-catch");
        img.src = res.image;
    }
  
  // リクエストをURLに送信
  request.send();
   
}

最後に、OGPの情報を返してくれるAPIを自分で作ってサーバーに置いておきます。

<?php
    require_once('./OpenGraph.php');
    
    $url = $_GET['url'];
    $graph = OpenGraph::fetch($url);

    // 文字化け対策
    $title_check = utf8_decode($graph->title);
    if(mb_detect_encoding($title_check) == 'UTF-8'){
      $graph->title = $title_check;
      $graph->site_name =  utf8_decode($graph->site_name);
      $graph->description  =  utf8_decode($graph->description );
    }
    
    $ogpdata = [
        "site_name" => $graph->site_name,
        "url" => $graph->url,
        "title" => $graph->title,
        "description" => $graph->description,
        "image" => $graph->image
        ];
    echo json_encode($ogpdata);
?>

上記APIを実際に設置する際は、エスケープ処理などしっかりするようにしてください。

プラスで、先程作ったPHPファイルと同じディレクトリにこの、OpenGraph.phpもおいておいてください。 これをおくことで、OGPを簡単に解析できます。

これで、準備はOKです。

記事でショートコードを使ってみる

記事内で、以下のように記述すると使えると思います。

{{< ogp "linkカードに表示したいURL" > }}

実際に使ってみると以下のような感じです。 完成したショートコードのプレビュー

いい感じに表示できてますね。

おわりに

今回デプロイで差分だけを上げることで、デプロイにかかる時間を大幅に減らすことができました。

また、自身のブログでリッチなリンクカードを作成して表示することができました。 本来はAPIなど使わずに、hugoのビルド時に置き換えられるようにするのがいいのですが今回はとりあえずこの状態で、後々改善する課題としたいと思います。

最後まで読んでいただきありがとうございました。

参考にさせていただいたサイト