Hugo adalah static site generator yang paling ampuh, walaupun dokumentasinya terkadang sedikit membingungkan dan membutuhkan waktu untuk dipelajari 1. Salah satu yang menarik yang ingin saya bahas disini adalah bagaimana hugo memproses resources. Pada pembahasan ini kita akan menggunakan resource gambar sebagai contoh.

Lokasi Resource

Untuk memproses sebuah resource file di hugo, file harus disimpan di lokasi tertentu agar hugo dapat mengaksesnya. Lokasi untuk menyimpa resource diantaranya:

Di folder assets pada root direktori projek (website)

~/yakalee
 .
 └── assets
     ├── gambar2.jpg
     └── images
         └── gambar1.jpg

File gambar bisa di tempatkan dimanapun asalkan masih di dalam folder assets, biasanya gambar yang disimpan disini digunakan untuk asset gambar template atau Global asset. Dan untuk memanggil atau menggunakan salah satu gambar menggunakan sintak berikut.

{{ $gambar := resources.Get "images/gambar.jpg" }}

Seperti yang disebutkan semua gambar yang berada di folder ini bersifat global. bisa diakses dimanapun baik di template maupun di postingan ataupun section.

Di folder content pada root directory projek (website)

~/yakalee
 .
 └── content
     ├── golang
     │   └── postingan-halo-dunia
     │       ├── halo.jpg
     │       └── index.md
     ├── hugo
     │   └── postingan-tanpa-gambar.md
     ├── linux
     │   ├── _index.md
     │   └── linux.jpg
     └── posts
         └── gambar.jpg

Hampir sama dengan gambar yang di folder assets, bedanya gambar ini lebih terstruktur menurut foldernya.

  • Jika ingin menggunakan gambar di postingan, maka gambar harus ditempatkan di folder postingan. seperti contoh postingan pada section golang.
  • Jika ingin menggunakan gambar di section, maka gambar harus di tempatkan di folder section. Seperti contoh pada section linux

Untuk mengaksesnya, sintaknya agak mirip dengan yang di folder assets. Tapi harus diperhatikan cara mengaksesnya.

{{ $gambar := .Resources.Get "gambar.jpg" }}

Gambar harus diakses dari halaman itu sendiri (baik section/postingan) dengan menggunakan tanda titik (.) dan huruf R Kapital dan nama gambar yang diakses langsung ditulis namanya tanpa lokasi path.

Diluar project atau remote (hostingan luar)

Ketika kita tidak ingin menyimpan gambar di folder project, kita bisa menggunakan gambar dari remote. Contohnya seperti dari google search atau hostingan gambar lainnya yang sudah ada di internet.

Untuk mengaksesnya kita hanya membutuhkan alamat url gambar tersebut menggunakan sintak berikut.

{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}

Jika kita menggunakan gambar dari remote hosting, gambar tersebut akan didownload oleh hugo dan disimpan di folder assets ketika blog/situs di build.

Cara ini jarang digunakan, saya sendiri tidak pernah menggunakannya. Lebih baik download gambar secara manual dan gunakan dua cara sebelumnya. Jadi ketika menjalankan perintah hugo serve atau build hugo tidak kelamaan nunggu download.

Method Pada resources

Ketika kita mengakses resources kita menggunakan method (atau fungsi dalam objek tersebut). Dari salah satu contoh sintak diatas:

{{ $image := resources.Get "images/gambar.jpg" }}

resources dari sintak diatas mewakili koleksi dari objek, sama halnya juga dengan .Resources. Resources bisa dalam bentuk file resource apapun, gambar, video, dokumen, dll. Tapi dalam pembahasan ini kita ambil contoh gambar sebagai resourcenya 2. Untuk mengakses kumpulan objek tersebut kita menggunakan method seperti:

Get, Untuk mengakses resource sesuai nama filenya

{{ $gambar := .Resources.Get "gambar.jpg" }}

Nilai yang dikembalikan oleh method ini adalah sebuah objek file sesuai nama yang di berikan pada parameter (pada contoh diatas yaitu gambar.jpg).

GetMatch, Untuk mengakses resource mengunakan wildcard.

{{ $gambar := .Resources.GetMatch "*.jpg" }}

Nilai yang dikembalikan oleh method ini juga sebuah objek file, tetapi hanya file pertama yang cocok dengan parameter wildcard yang diberikan (pada contoh diatas yaitu file dengan ekstensi .jpg atau gambar). Kita juga bisa menggunakan seperti halnya Get dengan menuliskan nama lengkap filenya tanpa menggunakan wildcard.

Match, Untuk mengakses koleksi resource menggunakan wildcard.

{{ $kumpulangambar := .Resources.Match "*.jpg" }}

Nilai yang dikembalikan oleh method ini adalah koleksi objek file, sama seperti GetMatch method ini dapat digunakan menggunakan wildcard, tapi nilainya berupa kumpulan (koleksi) objek file atau slice array. Pada contoh diatas semua file yang namanya berakhiran .jpg akan akan disimpan dalam variabel $kumpulangambar.

ByType, Untuk mengakses semua resource berdasarkan tipe.

{{ $kumpulangambar := .Resources.ByType "image" }}

Nilai yang dikembalikan oleh method ini adalah koleksi objek file, hampir sama dengan Match, bedanya tanpa menggunakan wildcard dan objeknya berdasarkan tipe dari objek file tersebut. Contoh diatas akan mengembalikan koleksi file dengan tipe image yang bisa berupa jpg, png, jpeg, webp, dan objek gambar lainnya jadi satu dan disimpan dalam variabel $kumpulangambar.

GetRemote, Untuk mengakses resource dari remote,

{{ $image := resources.GetRemote "https://contoh.com/gambar.jpg" }}

Contoh Penggunaan

Resource yang paling umum digunakan ketika membuat postingan adalah gambar, jadi disini contohnya adalah mengakses gambar yang disimpan dalam folder content. Contoh ini dibuat sesederhana mungkin, untuk yang lebih lengkapnya nanti akan di bahas pada pemrosesan gambar.

Untuk membuat meta og:image head

Meta pada head tag html adalah salah satu hal yang umum dibicarakan ketika melakukan optimasi seo, menggunakan tag og:image memungkinkan gambar tersebut sebagai default tampilan tumbnail di sosial media.

Setelah kita memahami cara mengakses resource, kita bisa mengunakannya untuk mensetting tag meta og:image seperti berikut.

{{- $imgs:= .Resources.ByType "image" -}}
{{- if and .IsPage (eq (len $imgs) 0) -}}{{- $imgs = .Parent.Resources.ByType "image" -}}{{- end -}}
{{- with (index $imgs 0 ) -}}<meta property="og:image" content="{{ .RelPermalink }}" >{{- end -}}
  • Baris pertama, kita mencoba mengakses koleksi resource gambar menggunakan method ByType pada sebuah halaman baik itu Post ataupun section.
  • Baris kedua, kita membuat kondisi jika halaman adalah Post dan di post tersebut tidak memiliki resource gambar maka gunakan gambar dari section dimana post tersebut di simpan. Jika halaman adalah halaman section maka baris ini akan di lewati.
  • Baris terakhir, kita menggunakan gambar pertama di koleksi dan menggunakan link ke resource sebagai nilai atribut content pada tag og:image

Pada contoh diatas menggunakan method ByType karena kita tidak tahu gambar dengan nama dan extensi apa di folder tersebut. Yang kita tahu untuk melengkapi tag og:image adalah sebuah gambar tidak peduli ekstensinya jpg,png, svg, dll.

Selanjutnya kita juga tidak tahu apakah di setiap postingan memiliki resource gambar seperti postingan yang dibuat ini. Kasus seperti inilah kondisi tersebut digunakan, jadi nantinya jika kalian share postingan ini, maka default thumbnail di postingan sosial media akan menggunakan gambar dari section dimana postingan ini disimpan. Pada kasus ini adalah gambar pada section hugo.

Untuk shortcode atau render hook

Contoh lain yaitu menggunakan mengkostumisasi output didalam postingan menggunakan shortcode. Dari pada kita menuliskan semua kode dibawah ini untuk menyesuaikan tag agar tampilan gambar sesuai dengan spesifikasi yang kita inginkan. Kita bisa menambahkan kode ini sebagai shortcode atau markdown render hook. sehingga kita bisa menuliskan sintak gambar dengan normal sintak markdown, dan ketika hugo build situs kita, formatnya sesuai yang kita definisikan di render hook.

{{ $image := newScratch }}
{{- if strings.HasPrefix .Destination "http" }}
{{- $image.Set "data" (resources.GetRemote .Destination) -}}
{{- else -}}
{{- $image.Set "data" (.Page.Resources.GetMatch .Destination) -}}
{{- end -}}
{{- $src:= ($image.Get "data") -}}

<figure class="img">
  <a href="{{.Destination}}" title="{{ .Title }}">
       {{- if eq (printf "%s" $src.MediaType) "image/svg+xml" -}}
        <img class="svg-image" src="{{ $src.Permalink }}" layout="responsive" loading="lazy" title="{{ .Title }}" alt="{{ .Text }}">
       {{- else -}}
        <img class="image" src="{{ $src.Permalink }}" layout="responsive" loading="lazy" title="{{ .Title }}" alt="{{ .Text }}">
       {{- end -}}
    <figcaption>{{- .Title | default .Text -}}</figcaption>
  </a>
</figure>
Code Snippet 1: kode render hook render-image.html

Pada kode diatas kita menggunakan hugo Scratch yang sama halnya dengan map digolang (map[string]interface{}), dan menyimpan resource dalam key(kunci) string data.

Kemudian memeriksa apakah alamat gambar yang ditulis di markdown terdapat awalan http, jika awalannya ada http maka kita menggunakan method GetRemote jika tidak maka gunakan GetMatch. Atau kalian bisa menggunakan method Get juga sama saja.

Kemudian kita buat tag untuk menampilkan gambar dan caption sesuai dengan spesifikasi HTML5. disitu kita juga mengunakan kondisi jika tipe gambarnya svg, saya ingin menggunakan attribut class svg-image untuk styling-nya, kalau bukan svg pakai attribut class image.

Saya menggunakan class berbeda untuk gambar svg karena terkadang background gambar svg yang transparan kurang cocok di dark mode.

Ide Lain untuk menggunakan resource gambar

  • Membuat halaman galeri gambar menggunakan method Match atau ByType.
  • Menggunakan resource gambar sebagai cover atau thumbnail untuk setiap artikel di list artikel menggunakan method Get atau GetMatch

Referensi


  1. Image Processing | Hugo <2022-06-26 Min> ↩︎

  2. Page Resources | Hugo <2022-06-26 Min> ↩︎