Membuat Jekyll Custom Tags dengan Liquid Tags
Latar Belakang Masalah
Seiring berjalannya waktu, jumlah post di BanditHijo Blog ini semakin banyak.
Saya pun sudah beberapa kali merubah beberapa style untuk beberapa komponen terutama komponen seperti tampilan terminal prompt atau code block. Masih mencari-cari style seperti apa yang pas dan mudah untuk dipahami.
Ketika style baru ditemukan, maka style yang lama juga mau tidak mau harus ikut diubah.
Sangat ribet sekali bukan?
Belum lagi, bentuk dari stylenya adalah HTML yang bercampur dengan Markdown di dalam post.
Misal seperti ini,
1Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam neque quod, debitis maxime nostrum quibusdam.2Harum ullam repudiandae beatae nesciunt ea ipsam nisi? Quasi quae aliquid ratione vel blanditiis vitae.34<pre>5$ <b>sudo pacman -Syu</b>6$ <b>sudo pacman -S ruby</b>7</pre>89Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla doloribus, labore dicta dolore magnam maiores.10Inventore expedita minus accusantium deserunt ipsum pariatur magni, cum reiciendis maxime.11Aperiam incidunt tempora natus?1213<!-- INFORMATION -->14<div class="blockquote-blue">15<div class="blockquote-blue-title"><img src="/assets/img/logo/logo_note.svg">Informasi</div>16<p markdown=1>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ex sapiente dicta,<br>17consequuntur veritatis, ipsum quos, hic dolores alias possimus reiciendis doloremque cupiditate nisi.<br>18Quaerat adipisci blanditiis sit quos, soluta iste.<p>19</div>
Baris ke 4-7, adalah prompt terminal.
Baris ke 13-19, adalah contoh dari quote informasi yang berwarna biru.
Nah, yang menjadi masalah adalah, bayangkan apabila terdapat ratusan artikel dan kita ingin merubah stylenya.
Mungkin gak? Masih mungkin, tapi cukup bikin mumet kepala. 😅
Apa yang saya inginkan?
Saya ingin menggunakan sesuatu semacam wadah, yang apabila ingin merubah stylenya, kita cukup merubah si wadah saja, dan semua yang menggunakan wadah tersebut otomatis ikut berubah juga.
Dan wadah tersebut harus sederhana. Cukup sederhana untuk ditulis dan dibaca.
Seperti ini,
1Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam neque quod, debitis maxime nostrum quibusdam.2Harum ullam repudiandae beatae nesciunt ea ipsam nisi? Quasi quae aliquid ratione vel blanditiis vitae.34{% shell_user %}5sudo pacman -Syu6sudo pacman -S ruby7{% endshell_user %}89Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla doloribus, labore dicta dolore magnam maiores.10Inventore expedita minus accusantium deserunt ipsum pariatur magni, cum reiciendis maxime.11Aperiam incidunt tempora natus?1213{% box_info %}14<p markdown=1>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ex sapiente dicta,<br>15consequuntur veritatis, ipsum quos, hic dolores alias possimus reiciendis doloremque cupiditate nisi.<br>16Quaerat adipisci blanditiis sit quos, soluta iste.<p>17{% endbox_info %}
Pada contoh di atas, saya menggunakan module Liquid::Block untuk membungkus konten yang ingin saya tampilkan.
1{% nama_tag %}2# konten3# yang ingin ditampilkan4# bisa dalam bentuk multiline5{% endnama_tag %}
Fitur ini, disebut dengan Liquid Tags. Fitur ini disediakan oleh Jekyll karena Jekyll menggunakan Liquid sebagai bahasa template.
Oke, karena keterbatasan ilmu saya saat ini, yang ingin saya catat hanya hal yang dasar saja dalam membuat Liquid tags yang juga digunakan di blog ini.
Mungkin artikel ini akan berkesinambungan seiring bertambahnya teknik yang saya dapatkan.
Praktik Membuat Liquid Tags
Di Jekyll, saya melihat pada module Tags menggunakan setidaknya Liquid::Block dan juga Liquid::Tags.
Liquid tags yang disediakan oleh Jekyll, pasti teman-teman pernah menggunakannya.
- highlight, menggunakan Liquid::Block (lib/jekyll/tags/highlight.rb)
- include, menggunakan Liquid::Tags (lib/jekyll/tags/include.rb)
- link, menggunakan Liquid::Tags (lib/jekyll/tags/link.rb)
Nah, kita akan mamanfaatkan kedua module ini untuk membuat Liquid tags yang kita perlukan.
Misal, kalau di BanditHijo, saya lebih banyak memerlukan untuk menampilkan command prompt, highlight code, dan image.
Pertama-tama, karena kita menggunakan Jekyll, kita akan menganggap fitur yang kita buat ini sebagai plugin.
Maka kita akan menempatkannya pada direktori _plugins/.
.
├── 📂 _plugins/
│ ├── 📄 images.rb
│ └── 📄 shells.rb
...
Dapat dilihat, kalau saya memiliki beberapa custom plugin yang saya buat untuk memudahkan proses menulis di blog ini.
Ayo kita lihat!
Liquid::Tags dengan Parameter
Rasanya, penggunaan module Liquid::Tags memang hampir semuanya menggunakan parameter.
Image Tag
Saya menggunakannya untuk menghandle image.
Sebelum mengenal Liquid tags, saya menggunakan cara ini untuk memasukkan gambar.
1{:data-echo="https://i.postimg.cc/wT7rfFFX/gambar-01.png" onerror="imgError(this);"}{:class="myImg"}
Ribet banget yaa.
Saya membuat snippets agar tidak ribet saat akan menggunakannya, namun, tetap saja hal ini membuat markdown file yang kita tulis menjadi kotor.
Saya ingin terlihat lebih rapi tanpa terlalu banyak HTML tag.
Kira-kira seperti ini,
1{% image https://i.postimg.cc/wT7rfFFX/gambar-01.png" | 1 | Ini adalah caption }2
Nah! Lebih sederhana kan?
Berikut ini adalah codenya,
1module Jekyll2 class Image < Liquid::Tag3 def initialize(tag_name, input, tokens)4 super5 @input = input6 end78 def render(context)9 params = split_params(@input)10 url = params[0].strip11 num = params[1].strip if params.length > 112 cap = params[2].strip if params.length > 21314 output = "{:data-echo='#{url}' onerror='imgError(this);'}{:class='myImg'}"15 output += "\n<p class='img-caption' markdown='1'>Gambar #{num} - #{cap}</p>" if params.length == 316 output17 end1819 def split_params(params)20 params.split(' | ')21 end22 end23end2425Liquid::Template.register_tag('image', Jekyll::Image)
Blok kode di atas adalah untuk kebutuhan saya.
Tentunya, teman-teman perlu memodifikasi sesuai dengan yang teman-teman butuhkan.
Liquid::Block Tanpa Parameter
Untuk membuat Liquid::Block Tanpa Parameter, cukup mudah.
Command Prompt
Saya akan contohkan untuk shells.rb, yang saya gunakan untuk menyimpan beberapa prompt shell untuk user dan root.
Kalau teman-teman lihat tampilan prompt seperti di bawah ini:
$ sudo pacman -Syy
# systemctl start NetworkManager.service
Kedua tampilan prompt di atas, digenerate dari Liquid tags yang berasal dari file plugin shells.rb tersebut.
Pada tampilan markdownya akan seperti ini:
1{% shell_user %}2sudo pacman -Syy3{% endshell_user %}
1{% shell_root %}2systemctl start NetworkManager.service3{% endshell_root %}
Nah! Sekarang saya akan perlihatkan isi dari plugin shells.rb.
1module Jekyll2 class ShellRoot < Liquid::Block3 def render(context)4 commands = super.split("\n")5 text = '<pre>'6 text += commands[1..].map do |i|7 "<span class='cmd'># </span><b>#{i}</b><br>"8 end.join.to_s9 text += '</pre>'10 text11 end12 end1314 class ShellUser < Liquid::Block15 def render(context)16 commands = super.split("\n")17 text = '<pre>'18 text += commands[1..].map do |i|19 "<span class='cmd'>$ </span><b>#{i}</b><br>"20 end.join.to_s21 text += '</pre>'22 text23 end24 end25end2627Liquid::Template.register_tag('shell_root', Jekyll::ShellRoot)28Liquid::Template.register_tag('shell_user', Jekyll::ShellUser)
Dapat dilihat bahwa saya membangun sebuah prompt dengan menggunakan pre tag.
<pre>
<span class="cmd">$ </span><b>command terminal</b>
</pre>
Style dari prompt ini adalah:
1/* Untuk box dari command */2pre {3 background: #002b36;4 border-radius: 5px;5 font-size: 14px;6 font-family: 'FiraCodeNerdFontComplete-Medium','Roboto Mono', monospace;7 line-height: 1.45;8 overflow: auto;9 padding: 10px;10}1112/* Untuk mewarnai command terminal menjadi kuning */13pre b {14 color: #FFCC00;15}1617/* Untuk mendisable selection dari simbol prompt */18pre span.cmd {19 user-select: none;20 -webkit-user-select: none;21 -ms-user-select: none;22 -webkit-touch-callout: none;23 -o-user-select: none;24 -moz-user-select: none;25}
Fitur dari Liquid tags ini adalah,
- Setiap baris baru (newline), akan diconvert menjadi 1 baris command (perintah).
Seperti ini contohnya:
1{% shell_user %}2mkdir project3cd project4git clone https://github.com/bandithijo/new_project5cd new_project6bundle exec jekyll server7{% endshell_user %}
Hasilnya:
$ mkdir project
$ cd project
$ git clone https://github.com/bandithijo/new_project
$ cd new_project
$ bundle exec jekyll server
Nah, sederhana kan?
Liquid::Block dengan Parameter
Untuk membuat Liquid::Block dengan Parameter, cukup tricky tapi mungkin.
Command Prompt
Saya akan contohkan lagi untuk Command Prompt tapi dapat kita definisikan sendiri bentuk dari prompt dan warnanya.
Seperti ini misalnya,
1{% shell_term $ %}2sudo pacman -Syu3sudo pacman -Scc4{% endshell_term %}
$ sudo pacman -Syu
$ sudo pacman -Scc
Atau,
1{% shell_term # %}2pacman -Syu3pacman -Scc4{% endshell_term %}
# pacman -Syu
# pacman -Scc
Saya menggunakan parameter $
untuk mengindikasikan user biasa dan #
untuk mengindikasikan root.
Atau, dengan parameter warna
1{% shell_term [arch@iso ~]# | #DC322F %}2mkdir project3cd project4git clone https://github.com/bandithijo/new_project5cd new_project6bundle exec jekyll server7{% endshell_term %}
[arch@iso ~]# mkdir project
[arch@iso ~]# cd project
[arch@iso ~]# git clone https://github.com/bandithijo/new_project
[arch@iso ~]# cd new_project
[arch@iso ~]# bundle exec jekyll server
Jadi lebih fleksible.
Nah! Codenya seperti ini.
1module Jekyll2 class ShellCommand < Liquid::Block3 def initialize(tag_name, input, tokens)4 super5 @input = input6 end78 def render(context)9 params = split_params(@input)10 prompt_symbol = params[0]&.strip11 prompt_color = params[1]&.strip if params.length > 11213 commands = super.split("\n")14 output = '<pre>'15 output += commands[1..].map do |i|16 "<span class='cmd' #{"style='color:#{prompt_color};'" unless prompt_color.nil?}>" \17 "#{prompt_symbol.nil? ? '$' : prompt_symbol} </span><b>#{i}</b><br>"18 end.join.to_s19 output += '</pre>'20 output21 end2223 def split_params(params)24 params.split(' | ')25 end26 end27end2829Liquid::Template.register_tag('shell_term', Jekyll::ShellCommand)
Pesan Penulis
Sepertinya, segini dulu yang dapat saya tuliskan.
Mudah-mudahan dapat bermanfaat.
Terima kasih.
(^_^)
Referensi
-
jekyllrb.com/docs/liquid/tags/
Diakses tanggal: 2021/01/22 -
jekyllrb.com/docs/plugins/your-first-plugin/
Diakses tanggal: 2021/01/22 -
blog.sverrirs.com/2016/04/custom-jekyll-tags.html
Diakses tanggal: 2021/01/25