Hugoでは外部サイトのデータを扱う場合、getJSON
やgetCSV
を使った方法しかありませんでしたが、ついにv0.91でGetRemote
が実装されました。
Release v0.91.0 · gohugoio/hugo
Hugo Pipes
GetRemoteの基本
基本の使い方はこんな感じで、html以外にも外部の画像、css、jsといったデータも取得できます。
{{ with resources.GetRemote "https://example.com" }}
{{ .Content }}
{{ end }}
エラーハンドリング
{{ with resources.GetRemote "https://gohugo.io/images/gohugoio-card-1.png" }}
{{ with .Err }}
{{ warnf "%s" . }}
{{ else }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}
{{ end }}
外部URLブログカードのショートコード
実際のコード
- unmarshalを使いたかったのですが、多くのサイトでパースエラーが起きてしまうので、正規表現を使うことにしました。
layouts/shortcodes/blog-card.html
{{- $url := (.Get 0) -}}
{{- with $result := resources.GetRemote $url -}}
{{- with $result.Err -}}
{{- warnf "%s" . -}}{{- . -}}
{{- else -}}
{{- $title := "" -}}
{{- $description := "" -}}
{{- $image := "" -}}
{{- with $findHead := index (findRE "<head>(.|\n)*?</head>" $result.Content) 0 -}}
{{- range $meta := findRE "<meta.*?>" $findHead -}}
{{- $name := replaceRE "<.*name=\"(.*?)\".*>" "$1" $meta -}}
{{- $property := replaceRE "<.*property=\"(.*?)\".*>" "$1" $meta -}}
{{- $content := replaceRE "<.*content=\"(.*?)\".*>" "$1" $meta -}}
{{- if eq $property "og:title" -}}
{{- $title = $content -}}
{{- else if eq $property "og:description" -}}
{{- $description = $content -}}
{{- else if eq $property "og:image" -}}
{{- $image = $content -}}
{{- end -}}
{{- if and (eq $description "") (eq $name "description") -}}
{{- $description = $content -}}
{{- end -}}
{{- end -}}
{{- if eq $title "" -}}
{{- with index (findRE "<title>(.*?)</title>" $findHead) 0 -}}
{{- $title = replaceRE "<title>(.*?)</title>" "$1" . -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $thumbnail_url := "" -}}
{{- if $image -}}
{{- with $thumbnail := resources.GetRemote $image -}}
{{- with $thumbnail.Err -}}
{{- warnf "%s" . -}}{{- . -}}
{{- else -}}
{{- $thumbnail_url = ($thumbnail.Fit (printf "200x200 center q%d webp" $.Site.Params.imageQuality)).Permalink -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- $thumbnail := resources.Get $.Site.Params.dafaultNoimage -}}
{{- $thumbnail_url = ($thumbnail.Fit (printf "200x200 center q%d webp" $.Site.Params.imageQuality)).Permalink -}}
{{- end -}}
<a href="{{- $url -}}" style="padding: 12px;border: solid 1px #eee;display: flex;text-decoration: none;color: #000;" onMouseOver="this.style.opacity='0.9'">
<div style="flex-shrink: 0;">
<img src="{{- $thumbnail_url -}}" alt="" width="100" height="100" style="object-fit: contain;">
</div>
<div style="margin-left: 10px;">
<h2 style="margin: 0;padding-bottom: 13px;border: none;font-size: 16px;">
{{- $title -}}
</h2>
<p style="margin: 0;font-size: 13px;word-break: break-word;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;">
{{- $description | plainify | safeHTML -}}
</p>
</div>
</a>
{{- end -}}
{{- end -}}
使い方
- 外部のurlを設定するだけ
- このサイトで使っているHugoブログテーマ「Salt」内でも実装済みです
{{< blog-card "https://hugo-theme-salt.okdyy75.com/" >}}
表示例
エンジニアに関する知識を記録・共有するためのサービス - Qiita
Zenn|エンジニアのための情報共有コミュニティ
はてなブックマーク
Hugoブログテーマ「Salt」
エラー時の表示例
ページが存在しない場合(500系など)
- その場でエラーメッセージが表示されます
{{< blog-card "https://example.com.invalid/" >}}
error calling resources.GetRemote: Get "https://example.com.invalid/": dial tcp: lookup example.com.invalid on 127.0.0.53:53: no such hostページが見つからない場合(400系など)
- 何も表示されません
{{< blog-card "https://example.com/test" >}}
metaタグにog:image
がない場合
- デフォルトのNoImage画像が表示されます
{{< blog-card "https://example.com" >}}
Example Domain
metaタグにog:image
が存在するが、リンク切れを起こしている場合
- リンク切れで表示されます。(
src=""
)
{{< blog-card "https://hugo-theme-salt.okdyy75.com/test.html" >}}