やりたいこと

以下のようにコードブロックと併せてファイル名も表示したい。

test.txt
Hello, World!

Hugoのデフォルトのコードブロックにはファイル名を表示する機能がない。

また自分の使っているPaperModというテーマでもサポートされていない。

そこで自分でテンプレートを拡張してコードブロックのファイル名を表示できるようにしてみた。

なお、使用しているテーマによっては拡張せずともファイル名を表示できる可能性があるので、まずはそちらの確認をすることをおすすめする。

環境

  • Hugo 0.145.0
  • PaperMod (commit e2e1011bdecaf84d59c70fa42ff3d2c29c537b65)

テンプレートを作成

公式のGitHubにあるコードを参考にして作成した。

公式のコード

上記のコードではTailwindが使われていたが、自分のテーマではTailwindは使われていなかったので、Tailwindを使わずに.cssファイルを使ってスタイリングをする方式に変更した。

またcopydetailsopensummaryといった将来使わなそうな不要なオプションはメンテが面倒になりそうだったので削除した。

copyに関してはPaperModでコピー機能が実装されているので削除したが、使用しているテーマでコピー機能がサポートされていない場合は採用するのもありだと思う。

というわけで、以下のコードを/layouts/_markup/render-codeblock.htmlとして保存する。

Hugoはコードブロックを見つけるとrender-codeblock.htmlを呼び出すと事前取り決めてあるので、ファイル名も配置場所も一文字でも間違えたらダメなことに注意。

/layouts/_markup/render-codeblock.html
{{- /*
  Forked from https://github.com/gohugoio/hugo/blob/master/docs/layouts/_default/_markup/render-codeblock.html At 2025-04-13
  Use .css file instead of Tailwind
  Deleted copy, details, open, summary params
  */}}

{{/* prettier-ignore-start */}}
{{/*
Renders a highlighted code block using the given options and attributes.

In addition to the options available to the transform.Highlight function, you
may also specify the following parameters:

@param {string} [file] The file name to display above the rendered code.

@returns {template.HTML}

{{/* prettier-ignore-end */}}

{{- $file := or .Attributes.file "" }}
{{- $ext := strings.TrimPrefix "." (path.Ext $file) }}
{{- $lang := or .Type $ext "text" }}
{{- if in (slice "html" "gotmpl") $lang }}
  {{- $lang = "go-html-template" }}
{{- end }}
{{- if eq $lang "md" }}
  {{- $lang = "text" }}
{{- end }}

<div
  class="codeblock-wrapper">
  {{- with $file }}
    <div
      class="codeblock-file">
      {{ . }}
    </div>
  {{- end }}

  <div>
    {{- transform.Highlight (strings.TrimSpace .Inner) $lang .Options }}
  </div>
</div>

CSSファイルを作成

PaperMod用のスタイリングの一例が以下。

PaperModの場合は/assets/css/extended配下にCSSファイルを配置することで自動でCSSファイルが読み込まれるが、テーマによってカスタムCSSの読み込み方は異なるので自分のテーマのドキュメントを確認してほしい。

/assets/css/extended/codeblock.css
.highlight {
  margin: 0 !important; /* Override */
}

.codeblock-wrapper {
  display: flex;
  flex-direction: column;
  margin: var(--content-gap) 0;
}

.codeblock-wrapper .codeblock-file {
  background-color: rgb(60, 61, 67);
  color: rgb(196, 196, 197);
  font-size: 0.9em;
  border-radius: 6px 6px 0 0;
  padding: 2px 16px;
  font-family: monospace;
  width: fit-content;
}

コードブロックの呼び出し

以下のようにしてfileパラメータを指定することで、ファイル名を表示できる。

test.txt
```txt {file="test.txt"}
Hello, World!
```

一言

最近テーマの拡張をしまくっているのでコードが秘伝のタレ化してしまっている気がするが、未来の自分はちゃんとメンテするんだろうか?