【HUGO】ショートコードでマークダウンに画像や動画の埋め込み

前回HUGOを用いてサイトを作成しました．
続きになりますので，ファイル構成などは前回を参考にしてください．
![【HUGO】フレームワークを用いた静的サイト作成](https://qiita.com/o_suke49/items/36209dadf04a6ebe5322)

まだ理解している途中ですので，私なりの解釈も入っています．ご了承ください．

# マークダウンに画像や動画を埋め込む
マークダウンには画像や動画を埋め込むためのコードがあります．以下のようにすると割となんでも埋め込めるらしい．
```markdown:md形式
<!--画像の埋め込み-->
<!-- 1つ目-->
<img src="画像のパスorURL" alt="画像の説明" title="タイトル">
<!-- 2つ目-->
![画像の説明](画像のパスorURL "タイトル")

<!--動画の埋め込み-->
<video src="動画の URL" controls width="600"></video>
```
`<video>`のcontrols属性は，それが存在する場合，再生や停止のためのユーザーインターフェイスを表示する。つまり
左が`controls`を書いてあるとき，右が`controls`を書いてないとき
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122091/2514eb3c-7487-8076-99e7-1bd485d13ec3.png" width = "300"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122091/8d260c26-4214-001e-005a-128a2b8859a6.png" width = "300">
となるわけです．試しにHUGOでcontrolsなしを書いてみたら上のようになり，動画の再生すらできませんでした．

さてサイトを作って画像を埋め込もうとマークダウンにて`<img>`を使ってみるとなぜか表示されない．
そして調べた結果，「ショートコード」に辿り着きました．

# ショートコード
### ショートコードとは
ショートコードとは、事前定義されたテンプレートを使用して Hugo がレンダリングするコンテンツファイル内の単純なスニペット．

つまり，「マークダウンという簡略化された形式にいちいちHTMLを書いて埋め込んでいくのは美しくないよね」で作られた，あらかじめHTMLの形を作っておいて必要なときに呼び出して画像や動画を埋め込めるようにするというものです．

## 元々あるショートコード
ショートコードは自作もできますが，元々備わっているものもあります．
例えば画像を埋め込みたいとなったとき以下のコードが使えます．
```markdown
{{< figure src="画像のパスorURL" title="画像タイトル" >}}
```
するとHUGOがこれを処理してくれて，出力するときに以下のHTMLに変えてくれます．
```HTML
<figure>
 <img src="elephant.jpg">
  <figcaption>An elephant at sunset</figcaption>
</figure>
```
他にもYoutubeを埋め込みたいときは
```markdown
{{< youtube w7Ft2ymGmfc >}}
```
アルファベットの羅列「w7Ft2ymGmfc」は動画のIDで，専用サイトから取得することができるので「youtube id」とかで調べてください．
詳しくは公式を
[参考] https://juggernautjp.info/content-management/shortcodes/


さて，あんまり`<img>`とかと変わらないんじゃないか，とは思いますが，私はタグが使えなかったので助かりました．\
でも何か引っ掛かります．

あらかじめ定義していないオプションは使えないのです．要はサイズの指定とかができない．そこで自作でショートコードを作っていきましょう．簡単に言えば，変換されたHTMLの中身を書き換えて仕まえばいいのです．

# 自作のショートコードを作る
### 画像を表示させるショートコード
まずはthemesじゃない方の，layoutsに以下のようなファイルを作ります．
今回は画像，動画，youtubeの埋め込み用を作ります．
```:ファイル構成
root/
　├ archetype/
　├ content/
　├ layouts/
　│　└ shortcodes/
　│　　　├ img.html
　│     ├ video.html
　│     └ youtube.html
　└ public/
```
まずはimg.htmlです．
```HTML:img.html
<!-- image -->
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }} {{ with .Get "alignment" }}class="{{ . }}"{{ end }}>
    {{ with .Get "link" }}<a href="{{ . }}">{{ end }}
      <img src="{{ .Get "src" }}" 
           {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }} 
           {{ if .Get "width" }}width="{{ .Get "width" }}"{{ end }}
           {{ if .Get "height" }}height="{{ .Get "height" }}"{{ end }} />
      {{ if .Get "link" }}</a>{{ end }}
      {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }}
        <figcaption class="cap">
          {{ if .Get "title" }}<h7>{{ .Get "title" }}</h7>{{ end }}
          {{ if or (.Get "caption") (.Get "attr") }}
            <p class="text">{{ .Get "caption" }}
              {{ with .Get "attrlink" }}<a href="{{ . }}">{{ end }}
              {{ .Get "attr" }}
              {{ if .Get "attrlink" }}</a>{{ end }}
            </p>
          {{ end }}
        </figcaption>
      {{ end }}
</figure>
```
これに対してマークダウンではこのように記述することでショートコードを使えます．
```markdown:blog_post1.md
{{< img src="画像の相対パス" title="画像のタイトル" caption="画像の説明" alignment="horizontal" width="300" >}}
```
何をしているか最初だけ解説します．
```HTML:img.html(抜粋)
{{ with .Get "class" }}class="{{ . }}"{{ end }}
```
`with`はこの後のパスから始めますよ．の合図みたいなもんです．`.Get`でその後の文字列で指定されたものを取得できます．ようは取得したclassで指定された文字列をclass="{.}"に入れますということ．ちなみに{.}はwithで指定された場所のその場所．例えば{.text}とかなっていたら，「class.text」という場所になる．`{{end}}`でしっかり閉じましょう．

```HTML:img.html(抜粋)
{{ if .Get "width" }}width="{{ .Get "width" }}"{{ end }}
```
これは「もし"width"を.Getする（取得する）ことができたら」
「width=」は「"(取得したwidth)"」になるということ．これも{{end}}でしっかり閉じます．

的なものをつらつら書いてHTMLを構成します．.Getでは取得したりしなかったりですので実際HTMLに変換されたときはもっとシンプルな形になると思います．これにより，HUGOでは画像の大きさが指定できない`![title](url)`だったものが豊かになります．また，これはscssを編集することで画像の見た目を変えることもできます．一例示しておきます．

先のimgの例では`class="text"`や`figcaption`タグが使われていました．それを以下のようにスタイルを指定することで画像群の見た目を変えることができます．(.~~はclassについて．~~はタグについてっぽい)
```scss
.horizontal{
 display: inline-flex;
 gap: 10px; /* 画像間のスペースを指定 */
 justify-content: center;
} 
figcaption{
 font-size: 18px;
}
.text{
 font-size: 13px;
}
```

### 動画を表示させるショートコード
```HTML:video.html
<div class="video-wrapper">
    <video 
        src="{{ .Get "path" }}" 
        title="{{ .Get "title" }}" 
        width="{{ .Get "width" | default "300" }}" 
        height="{{ .Get "height" | default "auto" }}" 
        controls = "true"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
        referrerpolicy="strict-origin-when-cross-origin" 
        allowfullscreen>
    </video>
    
    <div class="video-caption">
        {{ if .Get "title" }}<h7>{{ .Get "title" }}</h7><br>{{ end }}
        {{ if .Get "caption" }}<p class="text">{{ .Get "caption" }}</p>{{ end }}
    </div>
</div>
```
こっちは少し整理されていて見やすいですね．ちなみにこういうのはほとんどchatgtpに作ってもらいました．対するマークダウンは

```markdown:blog_post1.md
{{< video path="動画の相対パス" title="動画タイトル" caption="動画の説明" width="300" >}}
```

### youtubeを埋め込むショートコード
```youtube.html
<div class="video-wrapper">
    <iframe width="560" height="315" src="https://www.youtube.com/embed/{{ .Get "id" }}" 
    title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen>
    </iframe>
</div>
```

```markdown:blog_post1.md
{{< youtube id="y8FKLdnsOLs?si=YlDf7EKyUMc7QAFx" >}}
```
これは元とあんまり変わってませんが，個人的にidを丸投げするより`id=" "`の方がわかりやすいので，変更しました．今回は指定してませんが，widthやheightも変えることはできます．

ぜひHUGOでマークダウンをお使いの際は参考にして見てください．