Widget quotes bisa bikin artikel terasa lebih hidup, apalagi kalau blog memang punya tema inspirasi, personal, lifestyle, fotografi, atau komunitas. Tapi kalau mau memasang quote otomatis, sumber datanya juga perlu diperhatikan. Jangan sampai widget terlihat keren tapi diam-diam bergantung pada scraping atau script pihak ketiga yang cara pakainya sudah nggak sesuai.
Versi lama widget CodeFlare mengambil lima feed BrainyQuote, memasukkan semuanya lewat document.write(), lalu membersihkan HTML hasil feed dengan regex. Cara itu sekarang saya tinggalkan. BrainyQuote masih menyediakan JavaScript dan RSS feed resmi, tetapi mereka menyatakan data feed hanya boleh digunakan tanpa modifikasi dan link atribusinya tidak boleh dihapus tanpa izin.
Informasi Singkat
BrainyQuote masih menyediakan lima kelompok feed: Today's Quote, Art Quote, Funny Quote, Love Quote dan Nature Quote. Kalau memakai feed resminya, gunakan kode yang diberikan BrainyQuote apa adanya. Kalau ingin quote benar-benar random, desain bebas, dan tombol share/copy, lebih aman memakai database quote milik sendiri.
Sumber :
BrainyQuote Quote Feed
Kenapa Widget Quotes Lama Perlu Direbuild?
LAMAjQuery + document.writeBergantung pada library dan memasukkan script eksternal secara dinamis.
BARUVanilla JavaScriptWidget lokal bekerja tanpa jQuery dan tanpa request data eksternal.
LAMAFeed diproses ulangHTML BrainyQuote dibersihkan dengan regex termasuk menghilangkan link.
BARUFeed resmi dibiarkan utuhKalau memakai BrainyQuote, embed sesuai kode resmi mereka.
LAMA4 tombol share customFacebook, SMS, WhatsApp dan Twitter dibuat satu-satu.
BARUWeb Share APIBrowser yang mendukung bisa memakai panel share bawaan perangkat.
Dua Cara yang Saya Pakai untuk Widget Quotes
BrainyQuote Official FeedCocok untuk pembaca yang ingin quote harian dari sumber eksternal tanpa mengelola database sendiri.
Local Random QuotesIni pilihan yang saya gunakan untuk mendapatkan random instan, tombol share, copy, dan desain yang bebas dimodifikasi.
Pilihan 1 - BrainyQuote Quote of the Day
BrainyQuote masih menyediakan JavaScript feed resmi. Contoh paling sederhana adalah Today's Quote. Kode di bawah sebaiknya dipakai apa adanya, termasuk link atribusinya.
<script type="text/javascript" src="https://www.brainyquote.com/link/quotebr.js"></script>
<small><i><a href="https://www.brainyquote.com/quote_of_the_day" target="_blank" rel="nofollow noopener">more Quotes</a></i></small>
Jangan bersihkan hasil feed BrainyQuote dengan regex seperti engine lama. Halaman feed BrainyQuote menyebut data feed hanya boleh digunakan tanpa modifikasi. Jadi kalau ingin desain yang sepenuhnya bebas, gunakan widget lokal pada bagian berikutnya.
Pilihan 2 - Random Quotes Lokal Tanpa API
Untuk versi CodeFlare ini, saya memilih database quote lokal. Semua quote berada langsung di JavaScript, jadi widget tidak bergantung pada website pihak ketiga. Kalau suatu saat ingin menambah atau mengganti isinya, saya cukup mengubah daftar quote di dalam script.
Fitur Widget Random Quotes yang Baru
Random instanKlik tombol dan quote berikutnya langsung muncul tanpa reload halaman.
Native ShareMenggunakan Web Share API pada browser yang mendukung.
Copy quoteKutipan bisa disalin ke clipboard pada browser HTTPS yang mendukung.
Multi instanceSatu halaman bisa punya lebih dari satu widget tanpa ID yang bentrok.
WEB SHARE APIShare mengikuti fitur bawaan perangkatnavigator.share() bisa membagikan teks dan URL melalui target share yang tersedia di perangkat. Fitur ini membutuhkan HTTPS dan dukungannya belum sama di semua browser, jadi widget menyediakan fallback copy.
Dokumentasi
Kode Lengkap Widget Random Quotes
Kode di bawah sudah standalone. Kode ini bisa langsung saya pasang melalui mode HTML artikel atau gadget HTML/JavaScript. Kalau nantinya dipakai berulang di banyak halaman, CSS dan JavaScript lebih rapi kalau dipindahkan ke template sekali saja.
<div class="cfQuoteWidget">
<div class="cfQuoteMark"><i class="fa-solid fa-quote-left"></i></div>
<div class="cfQuoteText">Loading quote...</div>
<div class="cfQuoteAuthor"></div>
<div class="cfQuoteActions">
<button type="button" class="cfQuoteRandom"><i class="fa-solid fa-shuffle"></i> Random</button>
<button type="button" class="cfQuoteShare"><i class="fa-solid fa-share-nodes"></i> Share</button>
<button type="button" class="cfQuoteCopy"><i class="fa-regular fa-copy"></i> Copy</button>
</div>
</div>
<style>
.cfQuoteWidget{position:relative;margin:18px 0;padding:22px;border:1px solid rgba(0,131,218,.22);border-radius:8px;background:rgba(0,131,218,.035)}
.cfQuoteMark{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;margin-bottom:14px;border-radius:6px;background:rgba(0,131,218,.12);color:#0083da;font-size:20px}
.cfQuoteText{margin:0;padding:0;font-size:18px;font-weight:700;line-height:1.65}
.cfQuoteAuthor{display:flex;align-items:center;gap:8px;margin-top:12px;padding-top:10px;border-top:1px solid rgba(0,131,218,.12);font-size:15px;font-weight:600;opacity:.82}
.cfQuoteAuthor::before{content:"";display:block;width:22px;height:2px;border-radius:2px;background:#0083da}
.cfQuoteActions{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}
.cfQuoteActions button{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:38px;padding:8px 12px;border:1px solid rgba(0,131,218,.28);border-radius:5px;background:#0b5d8a;color:#fff;font-size:15px;font-weight:700;line-height:1.2;cursor:pointer;transition:transform .2s ease,background .2s ease,border-color .2s ease}
.cfQuoteActions button i{color:#fff}
.cfQuoteActions button:hover{background:#0878b7;border-color:#0878b7;transform:translateY(-1px)}
.cfQuoteActions button:focus-visible{outline:2px solid #25a9ee;outline-offset:2px}
@media(max-width:560px){.cfQuoteActions button{flex:1 1 calc(33.333% - 8px);min-width:110px}}
</style>
<script>
(function(){
"use strict";
var quotes=[
{text:"Ide yang sederhana bisa menjadi sesuatu yang besar kalau terus dikerjakan.",author:"CodeFlare"},
{text:"Belajar sedikit setiap hari lebih kuat daripada menunggu motivasi besar datang.",author:"CodeFlare"},
{text:"Blog yang berguna tumbuh dari rasa ingin membantu, bukan hanya mengejar angka.",author:"CodeFlare"},
{text:"Kadang perubahan kecil pada cara kerja bisa menghemat banyak waktu.",author:"CodeFlare"},
{text:"Jangan takut mengulang dari awal kalau versi lama memang sudah terlalu rumit.",author:"CodeFlare"},
{text:"Kode yang mudah dipahami hari ini akan menyelamatkan waktu kita besok.",author:"CodeFlare"},
{text:"Konsisten bukan berarti harus cepat, yang penting tetap bergerak.",author:"CodeFlare"},
{text:"Tampilan yang keren tetap harus membuat pengguna nyaman.",author:"CodeFlare"},
{text:"Kalau sebuah fitur tidak membantu pembaca, mungkin fitur itu memang tidak perlu.",author:"CodeFlare"},
{text:"Eksperimen kecil sering menjadi awal dari project yang paling seru.",author:"CodeFlare"},
{text:"Tulisan yang jelas lebih berharga daripada istilah rumit yang tidak perlu.",author:"CodeFlare"},
{text:"Perbaiki satu masalah nyata, lalu lanjut ke masalah berikutnya.",author:"CodeFlare"}
];
function pick(last){var n=Math.floor(Math.random()*quotes.length);if(quotes.length>1&&n===last)n=(n+1)%quotes.length;return n}
document.querySelectorAll(".cfQuoteWidget").forEach(function(w){
if(w.dataset.ready)return;w.dataset.ready="1";
var text=w.querySelector(".cfQuoteText"),author=w.querySelector(".cfQuoteAuthor"),random=w.querySelector(".cfQuoteRandom"),share=w.querySelector(".cfQuoteShare"),copy=w.querySelector(".cfQuoteCopy"),last=-1;
function show(){last=pick(last);text.textContent=quotes[last].text;author.textContent=quotes[last].author}
function value(){return text.textContent+" - "+author.textContent}
random.addEventListener("click",show);
share.addEventListener("click",async function(){
var data={title:document.title,text:value(),url:location.href};
if(navigator.share){try{await navigator.share(data);return}catch(e){}}
if(navigator.clipboard&&window.isSecureContext){await navigator.clipboard.writeText(value()+" "+location.href);share.innerHTML='<i class="fa-solid fa-check"></i> Tersalin';setTimeout(function(){share.innerHTML='<i class="fa-solid fa-share-nodes"></i> Share'},1500)}
});
copy.addEventListener("click",async function(){
if(navigator.clipboard&&window.isSecureContext){await navigator.clipboard.writeText(value());copy.innerHTML='<i class="fa-solid fa-check"></i> Tersalin';setTimeout(function(){copy.innerHTML='<i class="fa-regular fa-copy"></i> Copy'},1500)}
});
show();
});
})();
</script>
Cara Mengganti Database Quote
Untuk mengubah isi widget, saya cukup membuka bagian var quotes=[...]. Setiap quote di database saya buat dengan dua field: text dan author. Formatnya seperti ini:
{text:"Tulis kutipan kamu di sini.",author:"Nama penulis"}
Kalau saya memakai kutipan dari orang lain, atribusinya harus jelas dan penggunaannya memang aman. Untuk contoh widget CodeFlare ini, saya memilih kalimat buatan sendiri supaya sumbernya jelas dan database lebih mudah dirawat.
Mau Random Setiap Klik atau Berubah Sekali Sehari?
Versi default berubah setiap tombol Random ditekan. Kalau saya ingin satu quote yang sama sepanjang hari untuk semua pembaca, index bisa ditentukan dari tanggal. Saya juga tidak akan menyebutnya sebagai data yang “selalu update” kalau databasenya memang tetap; yang berubah hanya quote yang dipilih dari daftar lokal.
RANDOMBerubah saat tombol ditekanCocok untuk widget interaktif.
DAILYSatu quote per tanggalCocok untuk Quote of the Day dari database sendiri.
EXTERNALFeed providerData mengikuti update dari provider seperti BrainyQuote.
Cara Saya Memasang Widget Ini di Blogger
01Tentukan jenis widgetBrainyQuote resmi atau Random Quotes lokal.
02Copy kodeUntuk versi lokal, pembaca bisa langsung pakai kode standalone.
03Buka artikel mode HTMLTempel widget di lokasi yang diinginkan.
04PreviewTes Random, Share dan Copy sebelum publish.
Di template CodeFlare, .add-quotes sudah punya fungsi sendiri untuk kebutuhan artikel. Karena itu pada tutorial ini saya sengaja memakai class .cfQuoteWidget agar engine Random Quotes berdiri sendiri dan tidak mengganggu fungsi bawaan template.
Lebih Ringan Mana?
Local databaseTidak ada request quote ke domain lain setelah halaman dimuat.
External feedMenambah request ke provider, tetapi datanya dikelola pihak ketiga.
Vanilla JSTidak membutuhkan jQuery hanya untuk fungsi random dan tombol.
Script kecilUntuk puluhan quote teks, ukuran data masih sangat ringan.
Pilihan yang Saya Pakai di CodeFlare
Untuk CodeFlare, saya memilih database lokal karena lebih gampang dirawat, desainnya bebas, proses random cepat, dan tidak tergantung perubahan HTML dari provider lain. BrainyQuote tetap saya cantumkan sebagai pilihan untuk pembaca yang memang ingin Quote of the Day dari sumber eksternal resmi.
RANDOM QUOTES WIDGETData sederhana dan engine yang jelas biasanya lebih awet daripada scraping yang rumit.Kalau quote memang bagian dari karakter blog, punya database sendiri juga bikin widget terasa lebih personal.
Senja datang menyambut sang bulan, mengiringi langkahku yang tertatih menyusuri sunyinya malam. Ku terus berjalan melayangkan sebuah khayalan sambil kutepiskan duka dan sendiri kini ku melangkah.
ReplyDeleteSaat itu ku melihat seraut wajah yang pancarkan rasa dan sejenak aku terlena akan indahnya dia... oh angin sampaikan salamku untuk dia yang telah membuatku sejenak terlena.