PIYO - Tech & Life -

Hugoブログのタグをカラフルにしてみました

Hugo ブログ

GW中にブログの見た目をだいぶいじりました。

ブログ書こうにもなんとなくテンションがあがらないのを見た目を変えることで無理やりテンションを上げるという作戦です。

久しぶりだったこともありローカルサーバーを動かすところですら苦労したのですがそれはまた後日メモするとして、今日は新しい見た目でちょっとだけ頑張った、タグ表示の色付けの部分を紹介したいと思います。

記事中のタグ部分をHugoで処理するときには、タグの配列をループしてその中身(タグ本体)に対してHTMLを書くような感じで定義します。

たとえばこんな感じで、ulの中にliを並べたりします。

{{ $params := .Params }}
{{ range $key, $value := $.Site.Taxonomies }}
{{ if isset $params $key }}
<ul class="taglist">
  {{ range (index $params $key) }}
  <li class="tagitem">
    <i class="fa fa-tag"></i>
    {{ . }}
  </li>
  {{ end }}
</ul>
{{ end }}

ただし、この方法だと全てのタグが同じ見た目になってしまいますよね。

今回の見た目の変更では、タグ用の色を何色か用意してある程度ランダムに割り振るということを行いました。ただし、同じタグはいつも必ず同じ色になるようにしなければいけません。ビルドするたびにタグの色が変わっては行けないし、あるタグが別の記事に紐付いたときに色が変わるようではいけません。つまりただランダムに色を割り振るだけではダメということです。

タグを唯一識別する情報はタグ名です。なので、タグ名からあるロジックで色を割り振ることができれば良いと考えました。

タグの実装

Tailwindの導入

そしてココから先は割と力技でいきました。

まずタグの見た目には、Tailwind CSSというユーティリティ用のクラスがたくさん定義されているCSSフレームワークを用いました。

このフレームワークには背景色用のclassがいくつか定義されていて、グレースケール系を除くと、

  • red
  • orange
  • yellow
  • green
  • teal
  • blue
  • indigo
  • purple
  • pink

の9種類です。

また、それぞれにbg-red-600bg-green-100のように数値で色の段階を指定できます。

参考) https://tailwindcss.com/docs/background-color/#app

今回はこれらの9色にタグを割り振ることにしました。

<span class="text-xs mr-2 py-1 px-2 items-center bg-red-600 text-red-100 leading-none rounded-full flex inline-flex">
  <i class="fa fa-tag" aria-hidden="true"></i>
  タグだよ
</span>

Tailwindの他のクラスも駆使して↑のようなHTMLを書くと、↓のようなタグを出せます。

タグ名から色名にマッピングする

タグ名をキーとして、なんらかの計算を駆使して色名にマッピングすることができれば、あとは表示するのは簡単です。

9色に分けるという点から、整数を9で割った余りを使うのがよさそうだと考えました。つまり、タグ名を何らかの整数値に変換した上で9で割った余りを得て、その数値を色名配列のインデックスとして用いることで色名を得るというアイデアです。

そして、Hugoではこれをなんとか実現できましたので、コードを紹介します。

まず最初に紹介したようなループでタグを書き出す部分ですが、ここは大きく変わらずに↓のようになります。

{{ $params := .Params }}
{{ range $key, $value := $.Site.Taxonomies }}
{{ if isset $params $key }}
{{ range (index $params $key) }}

<a href="{{ $.Site.BaseURL }}tags/{{ . | urlize }}" class="text-xs">
  <span class="mr-2 py-1 px-2 items-center bg-{{ $variant }}-600 text-{{ $variant }}-100 leading-none rounded-full flex inline-flex">
  <i class="fa fa-tag mr-1" aria-hidden="true"></i>
  {{ . }}
  </span>
</a>

{{ end }}
{{ end }}
{{ end }}

HTMLになっている箇所の大部分が先程紹介したタグ定義の部分です。ここで注目してもらいたいのが、bg-{{ $variant }}-600 text-{{ $variant }}-100のところです。

$variantという変数にTailwindの色名が適切に割り振られることで、色違いのタグを実現できます。

次に、その$variantを計算するところです。

{{ $colors := slice "red" "orange" "yellow" "green" "teal" "blue" "indigo" "purple" "pink" }}

{{ $val := ((md5 .) | replaceRE "[0a-z]" "") }}
{{ $val = substr $val 0 5 | int }}
{{ $mod := mod $val (len $colors)}}
{{ $variant := index $colors $mod }}

コードの意図は上のから順にこうです。

  • 色の配列を定義
  • タグ名のmd5ハッシュを計算し、その結果から0とアルファベットを除去
  • ↑の結果の先頭5桁を整数に変換する
  • ↑の整数を $colorsの要素数(9)で割った余りを得る
  • ↑の余りをインデックスとして$colorsから色名を得る

Hugoのこのあたりの関数を使いました。

コード全体はこんな感じになりました。

{{ $colors := slice "red" "orange" "yellow" "green" "teal" "blue" "indigo" "purple" "pink" }}

{{ $params := .Params }}
{{ range $key, $value := $.Site.Taxonomies }}
{{ if isset $params $key }}
{{ range (index $params $key) }}

{{ $val := ((md5 .) | replaceRE "[0a-z]" "") }}
{{ $val = substr $val 0 5 | int }}
{{ $mod := mod $val (len $colors)}}
{{ $variant := index $colors $mod }}

<a href="{{ $.Site.BaseURL }}tags/{{ . | urlize }}" class="text-xs">
  <span class="mr-2 py-1 px-2 items-center bg-{{ $variant }}-600 text-{{ $variant }}-100 leading-none rounded-full flex inline-flex">
  <i class="fa fa-tag mr-1" aria-hidden="true"></i>
  {{ . }}
  </span>
</a>
{{ end }}
{{ end }}
{{ end }}

おしまい。