DTE :]

Saturday, July 6, 2019

Kreatif dengan Tag Kondisional pada Widget HTML Blogger

Sebuah widget berjenis HTML pada tema Blogger dapat Anda gunakan sebagai acuan dasar untuk memahami bagaimana cara kerja XML widget, terutama untuk para pengembang yang ingin membuat widget kustom dari kode sumber secara langsung. Berikut ini adalah sebuah contoh:

<b:section class='section-1' id='section-1' name='Bagian 1'>
  <b:widget id='HTML1' title='Judul Widget' type='HTML'>
    <b:widget-settings>
      <b:widget-setting name='content'>Konten widget.</b:widget-setting>
    </b:widget-settings>
    <b:includable id='main'>
      <h3><data:title/></h3>
      <div><data:content/></div>
    </b:includable>
  </b:widget>
</b:section>

Karena elemen <b:widget> harus berada di dalam elemen <b:section>, maka di sini Saya mengilustrasikannya sebagai sebuah widget HTML yang tersemat di dalam seksi bernama Bagian 1. Ketika kode tersebut diterjemahkan sebagai HTML, maka hasilnya akan menjadi tampak seperti ini:

<div class='section-1 section' id='section-1' name='Bagian 1'>
  <div class='widget HTML' data-version='2' id='HTML1'>
    <h3>Judul Widget</h3>
    <div>Konten widget.</div>
  </div>
</div>

Sedangkan pada halaman Tata Letak akan menjadi tampak seperti ini:

Bagian dalam widget Blogger.
Blok dengan judul Bagian 1 telah ditambahkan.

Jika Anda sunting widget tersebut melalui ikon pensil, maka Anda akan menyadari bahwa nilai data:content akan menempati bidang Konten di dalam formulir pengaturan widget. Sedangkan nilai atribut title pada elemen <b:widget> akan menempati bidang Judul (yang nilainya dapat kita tampilkan melalui data:title). Anda bisa memanfaatkan kedua elemen tersebut untuk mengubah perilaku widget berdasarkan nilainya.

Kode di bawah ini akan menampilkan markup HTML judul apabila data judul tidak kosong, dan akan menampilkan markup HTML konten apabila data konten tidak kosong:

<b:if cond='data:title != ""'>
  <h3><data:title/></h3>
</b:if>
<b:if cond='data:content != ""'>
  <div><data:content/></div>
</b:if>

Kode di bawah ini akan menampilkan markup HTML judul dan konten apabila data judul dan data konten tidak kosong:

<b:if cond='data:title != "" && data:content != ""'>
  <h3><data:title/></h3>
  <div><data:content/></div>
</b:if>

Kode di bawah ini akan menambahkan kelas HTML khusus berdasarkan kosong atau tidaknya data judul dan konten:

<div class='container'>

  <b:class cond='data:title != ""' name='has-title'/>
  <b:class cond='data:content != ""' name='has-content'/>

  <h3><data:title/></h3>
  <div><data:content/></div>

</div>

Kode di bawah ini akan menambahkan kelas HTML khusus berdasarkan nilai dari data judul secara spesifik:

<!-- https://getbootstrap.com/docs/4.3/components/alerts -->
<div class='alert' role='alert'>

  <b:comment>language: en</b:comment>
  <b:class cond='data:title in ["Danger", "Error"]' name='alert-danger'/>
  <b:class cond='data:title == "Info"' name='alert-info'/>
  <b:class cond='data:title == "Warning"' name='alert-warning'/>

  <b:comment>language: id</b:comment>
  <b:class cond='data:title in ["Bahaya", "Kesalahan"]' name='alert-danger'/>
  <b:class cond='data:title == "Informasi"' name='alert-info'/>
  <b:class cond='data:title == "Peringatan"' name='alert-warning'/>

  <h4 class='alert-heading'><data:title/></h4>
  <p class='mb-0'><data:content/></p>

</div>

Untuk manipulasi data yang lebih kompleks, Anda bisa memanfaatkan elemen <b:with> untuk mengubah sintaks objek valid yang tertulis di dalam bidang Konten sehingga nilainya dapat diperlakukan sebagai objek nyata di dalam XML widget dengan metode seperti ini.

Labels: , ,

Tuesday, June 25, 2019

Membuat Formulir Kontak dengan Google Drive

Tutorial kali ini merupakan tindak lanjut dari tutorial sejenis yang pernah Saya publikasikan sebelumnya di sini. Sebelum artikel tersebut ditandai sebagai artikel kadaluarsa, layanan Google Drive saat itu masih bernama Google Docs. Saya sempat berpikir untuk memperbarui artikel tersebut saja, tapi karena terdapat unsur historis pada artikel tersebut maka Saya memutuskan untuk membuat artikel yang baru saja.

Tutorial kali ini Saya harap akan jauh lebih mudah untuk diikuti karena di sini Anda tidak lagi membutuhkan ID spreadsheet untuk membuat formulir kontak bekerja. Tidak perlu panjang-panjang, kita langsung ke langkah-langkahnya saja ya!

Membuat Spreadsheet

Berbeda dari tutorial sebelumnya yang dimulai dengan membuat formulir baru, di sini Anda buat spreadsheet-nya terlebih dahulu. Spreadsheet ini nantinya akan kita gunakan sebagai basis-data untuk semua pesan yang berhasil dikirim. Buka https://drive.google.com/drive kemudian klik pada tombol Baru di pojok kiri atas. Pilih Google Spreadsheet kemudian pilih Spreadsheet kosong.

Membuat Spreadsheet Baru
Membuat spreadsheet baru.

Jendela baru akan terbuka untuk memuat editor spreadsheet dari Google. Setelah termuat, klik pada judulnya kemudian ubah namanya menjadi ‘Pesan Masuk’.

Mengganti nama spreadsheet.

Sekarang pilih menu Alat kemudian pilih Buat formulir.

Buat formulir baru.

Tunggu beberapa saat maka akan muncul tab baru di bagian bawah editor dengan label ‘Form Responses 1’.

Sheet baru dibuat secara otomatis.

Klik untuk mengaktifkan sheet tersebut! Anda boleh menghapus sheet sebelumnya karena itu tidak ada gunanya.

Formulir Anda sebenarnya sudah jadi, tapi masih belum berisi apa-apa kecuali satu bidang dengan label Timestamp dan satu bidang lagi yang hanya berfungsi sebagai contoh saja.

Menyunting Formulir

Pilih menu Formulir kemudian pilih Edit formulir. Maka jendela baru akan terbuka untuk memuat editor formulir.

Menyunting formulir.

Pada editor tersebut, hapus atau sunting bidang contoh, kemudian buat bidang-bidang baru dengan rincian seperti berikut:

  • Perihal
    • Tipe: Jawaban singkat
    • Wajib diisi: Ya
  • Nama
    • Tipe: Jawaban singkat
    • Wajib diisi: Ya
  • Surel
    • Tipe: Jawaban singkat
    • Wajib diisi: Ya
  • Situs Web
    • Tipe: Jawaban singkat
    • Wajib diisi: Tidak
  • Pesan
    • Tipe: Paragraf
    • Wajib diisi: Ya

Semua perubahan akan tersimpan secara otomatis.

Membuat Skrip Pemicu

Skrip ini nantinya akan bekerja setiap kali pesan dikirimkan melalui formulir terkait. Untuk membuatnya, pilih menu Alat kemudian pilih Editor skrip. Jendela baru akan terbuka untuk memuat editor skrip.

Membuka editor skrip.

Pada bidang Kode.gs, tempelkan kode ini:

function onFormSubmit(e) {
    GmailApp.sendEmail('you@example.com', 'Tes', JSON.stringify(e));
}

Simpan kode tersebut dengan nama ‘Kirim Pesan’.

Ganti kode yang Saya beri tanda dengan alamat surel Anda. Sekarang pilih menu yang tampak seperti simbol jam untuk mengaktifkan pemicu (biasanya bernama ‘Pemicu proyek saat ini’). Jendela baru akan terbuka untuk memuat halaman pemicu proyek.

Klik tombol Tambahkan Pemicu di pojok kanan bawah. Pada bidang Pilih fungsi yang ingin dijalankan pilih onFormSubmit (sesuai dengan nama fungsi yang kita buat sebelumnya). Pada bidang Pilih penerapan mana yang harus dijalankan pilih Head. Pada bidang Pilih sumber acara pilih Dari Spreadsheet. Pada bidang Pilih jenis acara pilih Saat mengirim formulir. Pada bidang Setelan notifikasi kegagalan ambil pilihan sesuai kebutuhan saja.

Setelah itu tekan tombol Simpan. Anda akan diminta untuk mengautentikasi pemicu tersebut melalui jendela munculan. Ikuti petunjuk yang ada, kemudian tekan tombol Izinkan di akhir tahapan.

Mengirim Pesan

Sekarang kita coba kirimkan pesan. Pilih menu Formulir kemudian pilih Buka formulir langsung. Jendela baru akan terbuka untuk memuat formulir publik Anda. Salin URL pada jendela tersebut untuk dibagikan nanti. Isi semua bidang yang ada kemudian tekan tombol Kirim untuk mengetes. Jika berhasil, maka Anda akan mendapatkan pesan masuk yang kurang lebihnya tampak seperti ini:

Pesan masuk.

Di situ akan tampak semua data yang telah kita kirimkan tadi. Untuk saat ini kita fokus ke bidang values dan namedValues saja. Kita pilih bidang namedValues karena bidang ini memiliki format {"key": "value"} yang lebih mudah untuk diproses.

Buka kembali editor skrip kemudian ubah fungsi onFormSubmit menjadi seperti ini:

function onFormSubmit(e) {
    var to = 'you@example.com',
        values = e.namedValues,
        key, value,
        body = "";
    for (key in values) {
        value = values[key];
        if (typeof value === "object" && value[0]) {
            value = value[0];
        }
        body += key + ': ' + value + '\n';
    }
    GmailApp.sendEmail(to, 'Pesan baru!', body.trim());
}

Simpan perubahan. Kemudian Anda coba kirim pesan lagi, maka format pesan yang masuk akan tampak lebih mudah dibaca sekarang!


Tingkat Lanjut

Mengirim HTML

Pada fungsi sebelumnya, setiap pesan yang dikirim akan diperlakukan sebagai data yang mentah, dimana karakter ganti baris akan diubah menjadi <br> dan tag-tag HTML yang lain akan dianggap sebagai teks biasa. Untuk mengirimkan kode HTML seperti apa adanya, Anda perlu mengosongkan bidang body kemudian ambil parameter berikutnya untuk menempatkan data pada bidang htmlBody agar data yang dikirimkan nantinya dapat dianggap sebagai kode HTML:

GmailApp.sendEmail(to, 'Pesan baru!', "", {
    htmlBody: body
});

Berikut ini adalah fungsi yang telah Saya modifikasi sedemikian rupa agar pesan yang masuk nantinya lebih nyaman untuk dibaca:

function onFormSubmit(e) {
    var to = 'you@example.com',
        values = e.namedValues,
        key, value,
        body = "";
    body += '<table style="width:100%;font-size:13px;font-family:sans-serif;line-height:1.5em;;background:#fff;color:#000;table-layout:fixed;border-collapse:separate;border-spacing:2px;">';
    body += '<tbody>';
    for (key in values) {
        value = values[key];
        if (typeof value === "object" && value[0]) {
            value = value[0];
        }
        // Ubah karakter `\n` menjadi `<br>`
        value = value.replace(/\n/g, '<br>');
        body += '<tr>';
        body += '<th style="font:inherit;font-size:100%;font-weight:bold;width:12em;background:#c3d9ff;padding:.5em 1em;vertical-align:top;text-align:right;">' + key + '</th>';
        body += '<td style="font:inherit;font-size:100%;background:#e0ecff;padding:.5em 1em;vertical-align:top;text-align:left;">' + value + '</td>';
        body += '</tr>';
    }
    body += '</tbody>';
    body += '</table>';
    GmailApp.sendEmail(to, values['Perihal'][0] || 'Pesan Baru!', "", {
        htmlBody: body
    });
}

Mengurutkan Data

Jika pesan yang terkirim tampak tidak sesuai dengan urutan yang seharusnya, Anda bisa mengatur data yang ditampilkan secara manual tanpa melalui pengulangan for:

values['Perihal'] && (body += 'Perihal: ' + values['Perihal'][0] + '\n');
values['Nama'] && (body += 'Nama: ' + values['Nama'][0] + '\n');
values['Surel'] && (body += 'Surel: ' + values['Surel'][0] + '\n');
values['Situs Web'] && (body += 'Situs Web: ' + values['Situs Web'][0] + '\n');
values['Pesan'] && (body += 'Pesan: ' + values['Pesan'][0]);

Atau seperti ini juga bisa:

var orders = ['Perihal', 'Nama', 'Surel', 'Situs Web', 'Pesan'],
    values = e.namedValues,
    key, value,
    body = "";
for (key in orders) {
    if (value = values[key = orders[key]]) {
        if (typeof value === "object" && value[0]) {
            value = value[0];
        }
        body += key + ': ' + value + '\n';
    }
}

Bidang Perihal sebagai Kategori

Anda bisa memanfaatkan fitur editor formulir untuk membatasi bidang yang ada agar hanya bisa diisi oleh nilai-nilai tertentu saja, misalnya dengan memilih tipe bidang Pilihan ganda.

Validasi Alamat Surel

Klik menu tambahan di samping sakelar Wajib diisi kemudian pilih Validasi respons. Pada pilihan Panjang ganti nilainya menjadi Ekspresi reguler (Anda menggunakan Panjang untuk menentukan batasan panjang pesan yang dikirimkan). Dan pada pilihan tambahan di sampingnya ganti nilainya dari Berisi menjadi Kecocokan. Pada bidang Pola, isi dengan ekspresi reguler yang cocok dengan alamat surel (tanpa awalan / dan akhiran /), misalnya seperti ini. Pada bidang Teks kesalahan khusus, isi dengan ‘Pola alamat surel tidak valid.’

Anda juga bisa menerapkan ini pada bidang Situs Web.

Labels: , , ,

Tuesday, September 25, 2018

Menambahkan Fitur Paginasi di dalam Artikel dengan JavaScript

Fitur Paginasi di dalam Artikel Blogger
Fitur paginasi di dalam artikel.

Fitur ini merupakan implementasi JavaScript dari plugin Mecha bernama Next yang berfungsi untuk memotong konten artikel menjadi beberapa bagian sehingga pengunjung dapat diajak untuk membaca konten artikel langkah demi langkah.

Lihat Demo


Integrasi Widget ke Blogger

Untuk menambahkan fitur ini di blog, pertama-tama buka editor HTML tema Anda kemudian temukan kode yang tampak kurang lebih seperti ini:

<b:widget id='Blog1' type='Blog'>

Pada bagian bawah kode tersebut, sisipkan kode ini:

<b:includable id='postTypeNext' var='post'>
  <b:if cond='data:view.isSingleItem and data:post.labels any (i => i.name in ["Next", "Steps", "How-To", "Berikutnya", "Langkah-Langkah", "Bagaimana-Cara", "type:next"])'>
    <b:class name='type:next'/>
    <script src='//dte-project.github.io/blogger/next.min.js'></script>
  </b:if>
</b:includable>

Kemudian cari kode ini:

<data:post.body/>

Pada setiap kode yang Anda temukan, sisipkan kode ini di bawahnya:

<b:include data='post' name='postTypeNext'/>

Klik Simpan Tema. Fitur paginasi artikel sekarang sudah siap untuk digunakan! Yang perlu Anda lakukan berikutnya adalah menambahkan label Langkah-Langkah atau Bagaimana-Cara atau Steps atau How-To pada artikel yang Anda inginkan.

Untuk menandai bagian-bagian yang perlu dipotong, tambahkan komentar <!-- next --> pada baris yang ingin Anda potong di dalam artikel. Pastikan Anda sedang berada pada mode HTML saat menyunting:

<p>Halaman 1</p>
<!-- next -->
<p>Halaman 2</p>
<!-- next -->
<p>Halaman 3</p>
<!-- next -->
<p>Halaman 4</p>
<!-- next -->
<p>Dan seterusnya.</p>

Jika para pembaca artikel Anda dapat dipastikan menggunakan peramban dengan JavaScript yang aktif, maka akan lebih efektif jika Anda mengaktifkan fitur pramuat gambar pada plugin ini. Cara mengaktifkan fitur pramuat gambar adalah dengan mengubah atribut src pada elemen <img> menjadi data-src sehingga gambar-gambar yang ada tidak akan dimuat sebelum potongan halaman yang berisi gambar tersebut dibuka oleh pembaca:

Sebelum

<img alt="" src="path/to/image.jpg">

Sesudah

<img alt="" src="loading.png" data-src="path/to/image.jpg">

Ganti bagian yang Saya beri tanda dengan URL gambar berukuran kecil, atau jika dirasa kurang praktis, Anda bisa menghapus atribut src pada gambar tersebut.

Pengaturan

Opsi Keterangan
hash Merupakan format fragmen URL untuk menandai pergantian halaman. Pola %i% pada !page=%i% akan diubah menjadi nomor halaman.
kin Digunakan untuk menentukan banyaknya kerabat tombol angka halaman yang akan ditampilkan sebelum dan setelah tombol angka halaman yang aktif.
top Jarak perhentian tambahan antara bagian atas layar halaman dengan bagian atas konten artikel setiap kali halaman berganti.
text Label-label yang diperlukan pada artikel. text[first] untuk menampilkan teks First, text[previous] untuk menampilkan teks Previous, text[next] untuk menampilkan teks Next, text[last] untuk menampilkan teks Last, dan text[current] untuk menampilkan teks Page 1 of 20.

Parameter-parameter di atas dapat Anda tambahkan sebagai parameter URL setelah nama berkas next.min.js:

<script src="next.min.js?top=20"></script>

Labels: , ,

Wednesday, September 19, 2018

Menambahkan Fitur AJAX Penelusuran di Blog

Fitur AJAX Penelusuran di Blogger
Fitur kotak penelusuran AJAX di blog.

Artikel ini merupakan hasil akumulasi dari temuan-temuan Saya tentang bagaimana kita bisa menggunakan JSON Blogger untuk menciptakan fitur penelusuran dinamis hanya dengan memanfaatkan parameter q pada tautan umpan. Fitur ini dapat diterapkan pada semua tema dan tidak bergantung pada apapun.

Lihat Demo


Integrasi Widget ke Blogger

Untuk mengaktifkan fitur penelusuran AJAX pada blog, Anda tidak perlu menambahkan markup HTML apapun ke dalam tema, karena widget ini akan menggunakan kotak penelusuran yang ada sebagai kotak penelusuran AJAX. Yang perlu Anda lakukan hanya menambahkan sebuah elemen halaman HTML/JavaScript dengan konten berupa kode ini:

<script src="//dte-project.github.io/blogger/search.min.js?live=true"></script>

Klik Simpan Setelan. Fitur penelusuran AJAX sekarang sudah siap untuk digunakan!

Jika kotak penelusuran AJAX tidak bekerja, mungkin itu karena Anda menambahkan widget ini sebelum widget kotak penelusuran. Untuk membuatnya bisa bekerja, Anda perlu meletakkan widget ini setelah widget kotak penelusuran. Selengkapnya bisa dibaca di sini.

Pengaturan

Opsi Keterangan
live Jika bernilai false, maka pengguna perlu mengeklik tombol Telusuri pada formulir atau menekan tombol Enter pada papan ketik untuk memulai penelusuran.
url Ganti nilainya dengan alamat blog Anda atau alamat blog orang lain yang ingin Anda tampilkan kontennya.
id Alternatif untuk menentukan sumber data selain dengan url. Ganti nilainya dengan ID blog Anda atau ID blog orang lain yang ingin Anda tampilkan kontennya. ID harus dituliskan sebagai string. Menambahkan parameter id akan mengabaikan nilai parameter url. Contoh: id="4890949828965961610"
direction Direksi teks pada blog Anda. Nilainya bisa berupa "ltr" atau "rtl".
source Selektor CSS untuk menentukan formulir kotak penelusuran yang ingin dijadikan sebagai kotak penelusuran AJAX. Menghilangkan parameter ini akan membuat widget secara otomatis menyeleksi elemen formulir pertama yang ditemukan yang memiliki nilai atribut action berupa /search pada bagian akhir. Anda bisa menentukan target yang lebih spesifik, misalnya source=%23BlogSearch1%20form untuk menyeleksi elemen formulir pada widget kotak penelusuran yang memiliki ID #BlogSearch1.
container Selektor CSS untuk menentukan di mana hasil penelusuran akan ditampilkan. Menghilangkan parameter ini akan membuat widget secara otomatis menampilkan hasil penelusuran tepat di bawah formulir penelusuran. [demo]
excerpt Ganti nilainya menjadi true untuk menampilkan ringkasan artikel. Atau gunakan angka untuk menentukan maksimal karakter yang akan ditampilkan dalam ringkasan artikel sebelum diakhiri oleh karakter .
image Ganti nilainya menjadi true untuk menampilkan gambar artikel. Atau gunakan angka untuk menentukan ukuran lebar dan tinggi gambar. Anda juga bisa menggunakan parameter standar gambar Google untuk memanipulasi ukuran, seperti "s100", "s100-c", dan "w100-h50".
target Jika bernilai "_blank", semua tautan akan terbuka di tab/jendela baru saat diklik.
chunk Digunakan untuk menentukan banyaknya hasil temuan yang ditampilkan dalam satu kali penelusuran.
text Label-label yang diperlukan pada tampilan penelusuran.

Parameter-parameter di atas dapat Anda tambahkan sebagai parameter URL setelah nama berkas search.min.js:

<script src="search.min.js?live=true&amp;chunk=100&amp;text[loading]=Memuat%E2%80%A6"></script>

Labels: , ,

Thursday, September 6, 2018

Mengakses Tag Kondisional Halaman Blogger di dalam JavaScript

Widget Manager
_WidgetManager._GetAllData()
document.addEventListener("DOMContentLoaded", function() {
    if (typeof _WidgetManager === "undefined") return;
    var data = _WidgetManager._GetAllData();
    // Lakukan sesuatu dengan `data` di sini …
}, false);

Contoh

if (data.view.isSingleItem) { … }
if (data.view.type === "item") { … }
var url = data.view.url;

Labels: , , ,

Wednesday, September 5, 2018

Menambahkan Fitur Komik di Blog dengan JavaScript

Fitur Komik di Blogger
Fitur komik di blog.

Artikel ini merupakan tindak lanjut dari berbagai permintaan pengguna yang mereka tambahkan pada artikel ini yang membahas tentang bagaimana caranya agar gambar-gambar di dalam komik web dapat dimuat secara bergantian untuk mengurangi beban muat halaman. Setelah sekian lama akhirnya Saya punya waktu juga untuk membuat widget yang lebih baik dengan beberapa fitur tambahan, dan yang paling penting adalah widget ini tidak lagi tergantung pada .

Lihat Demo


Integrasi Widget ke Blogger

Untuk menambahkan fitur komik di blog, pertama-tama buka editor HTML tema Anda kemudian temukan kode yang tampak kurang lebih seperti ini:

<b:widget id='Blog1' type='Blog'>

Pada bagian bawah kode tersebut, sisipkan kode ini:

<b:includable id='postTypeComic' var='post'>
  <b:if cond='data:view.isSingleItem and data:post.labels any (i => i.name in ["Comic", "Komik", "type:comic"])'>
    <b:class name='type:comic'/>
    <script src='//dte-project.github.io/blogger/comic.min.js?save=false'></script>
  </b:if>
</b:includable>

Kemudian cari kode ini:

<data:post.body/>

Pada setiap kode yang Anda temukan, sisipkan kode ini di bawahnya:

<b:include data='post' name='postTypeComic'/>

Klik Simpan Tema. Fitur komik sekarang sudah siap untuk digunakan! Yang perlu Anda lakukan berikutnya adalah membuat artikel-artikel baru berisi gambar-gambar, setelah itu cukup tambahkan label Komik atau Comic untuk mengaktifkan tampilan komik.

Widget ini akan mencari semua elemen <a> dan <img> di dalam artikel yang memiliki label Komik atau Comic dan akan mengambil nilai atribut href dan src pada elemen tersebut untuk dijadikan sebagai daftar antrean gambar. Khusus pada nilai atribut href pada elemen <a>, widget ini hanya akan mengambil tautan yang tampak sebagai tautan gambar, yaitu yang memiliki akhiran berupa ekstensi GIF, JPEG, JPG dan PNG.

Selain dari itu akan dianggap sebagai sinopsis atau ringkasan mengenai isi komik.

Saya perlu menambahkan alternatif berupa elemen <a> sebagai penyimpan tautan gambar karena dengan hanya mengandalkan elemen <img>, sama saja dengan meminta peramban untuk memuat semua gambar yang ada saat artikel sedang memuat. Meskipun nantinya ketika komik ditampilkan, gambar-gambar yang ada akan muncul secara bergantian, namun di balik layar sebenarnya peramban akan memuat semua gambar yang ada.

Oleh karena itu Saya sarankan untuk membuat artikel bertipe komik yang terdiri dari satu gambar saja yaitu gambar sampul komik. Sedangkan gambar-gambar yang lainnya dapat Anda tampilkan sebagai tautan biasa seperti ini:

<p>In every class, it’s not usual for there to be one or two people who seem a little strange. In Oda’s class, there is Hototogi.</p>
<p><img alt="Cover" title="Page 1" src="/path/to/image/1.png"></p>
<p><a href="/path/to/image/2.png">Page 2</a></p>
<p><a href="/path/to/image/3.png">Page 3</a></p>
<p><a href="/path/to/image/4.png">Page 4</a></p>
<p><a href="/path/to/image/5.png">Page 5</a></p>
<p><a href="/path/to/image/6.png">Page 6</a></p>
<p><a href="/path/to/image/7.png">Page 7</a></p>

Untuk memperoleh waktu muat komik yang paling cepat, Anda bisa menghapus semua gambar yang ada dan menggantinya dengan elemen <a>, namun kekurangannya adalah nanti Anda tidak akan memiliki elemen <data:post.thumbnailUrl/> untuk ditampilkan sebagai keluku artikel.

Pengaturan

Opsi Keterangan
hash Merupakan format fragmen URL untuk menandai pergantian halaman. Pola %i% pada !page=%i% akan diubah menjadi nomor halaman. [demo]
save Pilihan untuk memungkinkan para pembaca menyimpan gambar komik Anda dengan cara klik kanan pada gambar. Ganti nilainya menjadi false untuk melarang pembaca menyimpan gambar-gambar komik Anda.
image Resolusi maksimal gambar komik yang Anda simpan di Google berupa angka. [demo]
chunk Pilihan untuk menampilkan beberapa gambar sekaligus dalam satu lompatan halaman. Nilai bawaan adalah 1. Jika Anda mengubah nilainya menjadi 2, maka setiap halaman komik akan menampilkan dua gambar. [demo]
kin Digunakan untuk menentukan banyaknya kerabat tombol angka halaman yang akan ditampilkan sebelum dan setelah tombol angka halaman yang aktif.
top Jarak perhentian tambahan antara bagian atas layar halaman dengan bagian atas area komik setiap kali halaman berganti. [demo]
text Label-label yang diperlukan pada komik. text[first] untuk menampilkan teks First, text[previous] untuk menampilkan teks Previous, text[next] untuk menampilkan teks Next, text[last] untuk menampilkan teks Last, text[current] untuk menampilkan teks Page 1 of 20, dan text[enter] untuk menampilkan teks Read on….

Parameter-parameter di atas dapat Anda tambahkan sebagai parameter URL setelah nama berkas comic.min.js:

<script src="comic.min.js?save=false&amp;chunk=2&amp;text[enter]=Read%20More"></script>

Beberapa tema seperti 000000.min.css dan ffffff.min.css dapat Anda tambahkan seperti ini:

  …
  …
  <link href='//dte-project.github.io/blogger/comic/000000.min.css' rel='stylesheet'/>
</head>

Labels: , , ,

Saturday, September 1, 2018

Gawai Daftar Isi Akordion untuk Blogger

Pembaruan 2018/09/01: Berbagai perubahan dan fitur baru telah ditambahkan untuk memenuhi saran dan permintaan para pengguna. Beberapa diskusi yang terdapat di dalam ruang komentar mungkin sudah tidak relevan lagi dengan isi artikel.

Gawai Daftar Isi Akordion untuk Blogger

Kali ini Saya akan memperkenalkan gawai daftar isi akordion berdasarkan label setelah sebelumnya Saya pernah menuliskan tentang gawai daftar isi akordion berdasarkan bulan terbit:

Lihat Demo


Integrasi Gawai ke Blogger

Memasang widget ini memerlukan kemampuan dasar dalam membaca dan menulis kode HTML. Jika Anda termasuk kategori penulis blog yang masih bergantung pada perangkat tulis WYSIWYG atau pada mode Compose di editor Blogger, mungkin Anda perlu mempelajari dasar-dasar penulisan kode HTML terlebih dahulu sebelum menerapkan gawai ini. Sebuah blog dari Niagahoster menyediakan tutorial dasar tentang pemahaman kode HTML untuk pemula dimulai dari persiapan alat hingga pengenalan berbagai tag dan atribut HTML dasar, terutama yang sangat umum dijumpai di dalam konten sebuah artikel seperti format judul, efek huruf tebal dan miring, serta penjelasan tentang cara menyisipkan tautan dan gambar. Anda bisa membacanya di halaman Belajar HTML.

Pertama-tama klik menu Laman pada bilah sisi. Kemudian, pada menu Laman Baru pilihlah Laman Kosong:

Blogger Post Editor
Menambahkan halaman statis baru.

Setelah itu kamu akan melihat formulir halaman statis seperti ini. Klik mode HTML:

Blogger Post Editor
Memilih mode HTML.

Salin kode di bawah ini kemudian letakkan di dalam formulirnya:

<link href="//dte-project.github.io/blogger/stacked-toc/248ab0.min.css" rel="stylesheet">
<script src="//dte-project.github.io/blogger/stacked-toc.min.js?url=http://dte-feed.blogspot.com&amp;active=0"></script>

Ganti URL yang Saya beri tanda dengan alamat blog kamu kemudian klik tombol Publikasikan.

Menghilangkan parameter url akan membuat gawai ini secara otomatis menentukan URL halaman muka berdasarkan URL pada bilah alamat. Berkas 248ab0.min.css adalah berkas tema. Kamu bisa menghapus berkas tersebut jika kamu ingin membuat tema sendiri:

<style>
/* Kode tema kustom di sini… */
</style>
<script src="//dte-project.github.io/blogger/stacked-toc.min.js?active=0"></script>

Pengaturan

Opsi Keterangan
url Ganti nilainya dengan alamat blog kamu atau alamat blog orang lain yang ingin kamu tampilkan kontennya.
id Alternatif untuk menentukan sumber data selain dengan url. Ganti nilainya dengan ID blog kamu atau ID blog orang lain yang ingin kamu tampilkan kontennya. ID harus dituliskan sebagai string. Menambahkan parameter id akan mengabaikan nilai parameter url. Contoh: id="4890949828965961610"
direction Direksi teks pada blog kamu. Nilainya bisa berupa "ltr" atau "rtl".
container Selektor CSS untuk menentukan di mana gawai akan ditampilkan. Menghilangkan parameter ini akan membuat gawai secara otomatis menempatkan diri tepat sebelum tag <script> yang kamu sisipkan.
active Digunakan untuk menentukan urutan panel yang akan aktif saat pertama kali halaman dimuat. Nilai 0 akan membuat panel di urutan pertama menjadi aktif. Nilai "Musim Gugur" akan membuat panel dengan label Musim Gugur menjadi aktif.
toggle Digunakan untuk menentukan sifat panel ketika diklik. Menentukan nilai true akan membuat panel yang aktif menutup dirinya sendiri ketika kamu mengeklik panel tersebut, atau ketika kamu mengeklik panel yang lainnya. Menentukan nilai false akan membuat panel yang aktif menutup hanya ketika kamu mengeklik panel yang lainnya. Menentukan nilai -1 akan membuat panel yang aktif menutup dirinya sendiri hanya ketika kamu mengeklik panel tersebut; panel-panel yang lain tidak akan terpengaruh.
hide Tentukan nama-nama label yang tidak ingin kamu tampilkan.
date Ganti nilainya menjadi false untuk menyembunyikan waktu penerbitan artikel. Selain itu akan dianggap sebagai format waktu penerbitan: %Y% untuk menampilkan angka tahun, %M% untuk menampilkan angka bulan, %D% untuk menampilkan angka hari, %h% untuk menampilkan angka jam format 12, %m% untuk menampilkan angka menit, %s% untuk menampilkan angka detik, %M~% untuk menampilkan nama bulan, %D~% untuk menampilkan nama hari, %h~% untuk menampilkan angka jam format 24, dan %N% untuk menampilkan keterangan waktu format 12; nilainya bisa berupa "AM" atau "PM" tergantung dari data text[midday].
excerpt Ganti nilainya menjadi true untuk menampilkan ringkasan artikel. Atau gunakan angka untuk menentukan maksimal karakter yang akan ditampilkan dalam ringkasan artikel sebelum diakhiri oleh karakter .
image Ganti nilainya menjadi true untuk menampilkan gambar artikel. Atau gunakan angka untuk menentukan ukuran lebar dan tinggi gambar. Kamu juga bisa menggunakan parameter standar gambar Google untuk memanipulasi ukuran, seperti "s100", "s100-c", dan "w100-h50".
target Jika bernilai "_blank", semua tautan akan terbuka di tab/jendela baru saat diklik.
load Digunakan untuk menentukan waktu penundaan pemuatan JSON. Tentukan sebagai angka untuk waktu penundaan memuat dalam satuan milidetik atau true agar gawai ini memuat setelah keseluruhan halaman telah selesai termuat.
sort false untuk menyortir artikel secara normal berdasarkan bulan terbit, 1 untuk menyortir artikel dari A ke Z, -1 untuk menyortir artikel dari Z ke A.
recent false untuk menyembunyikan tanda New!. Ganti dengan angka untuk menentukan berapa banyak artikel terbaru yang ingin ditandai dengan label New!.
text[recent] Markup HTML bebas untuk membuat label New! pada artikel-artikel terbaru.
text[months] Digunakan untuk menentukan nama-nama bulan sesuai dengan sistem kalender di negara tempat kamu tinggal.
text[days] Digunakan untuk menentukan nama-nama hari sesuai dengan sistem kalender di negara tempat kamu tinggal.

Contoh

Menampilkan gambar dan ringkasan:

<script src="stacked-toc.min.js?excerpt=200&amp;image=80"></script>

Membuat panel ke tiga aktif saat pertama kali halaman dimuat:

<script src="stacked-toc.min.js?active=2"></script>

Membuat panel dengan label Iklan aktif saat pertama kali halaman dimuat:

<script src="stacked-toc.min.js?active=Iklan"></script>

Menyembunyikan panel dengan label Iklan dan Tautan:

<script src="stacked-toc.min.js?hide=["Iklan","Tautan"]"></script>
<script src="stacked-toc.min.js?hide[0]=Iklan&amp;hide[1]=Tautan"></script>

Memodifikasi format waktu penerbitan (karakter % harus diubah menjadi %25):

<script src="stacked-toc.min.js?date=%25Y%25-%25M%25-%25D%25%20%25h%25%3A%25m%25%3A%25s%25"></script>

Menentukan kontainer spesifik (karakter # harus diubah menjadi %23):

<script src="stacked-toc.min.js?container=%23content"></script>

Kemudian, pada suatu tempat, Anda buat elemen HTML seperti ini:

<div id="content"></div>

Gunakan alat ini untuk mempermudah dalam mengubah karakter mentah menjadi karakter yang aman untuk URL.


Animasi

Fitur animasi pada gawai ini sudah tidak lagi dibuat menggunakan API jQuery, melainkan hanya memanfaatkan fitur CSS3 transisi. Kamu bisa memodifikasi kecepatan dan percepatan animasi dengan cara seperti ini:

<style>
.stacked-toc-panel {
  /* `ease-in-out-quart` */
  -webkit-transition-timing-function: cubic-bezier(.77, 0, .18, 1);
  -moz-transition-timing-function: cubic-bezier(.77, 0, .18, 1);
  transition-timing-function: cubic-bezier(.77, 0, .18, 1);
  /* ½ detik */
  -webkit-transition-duration: .5s;
  -moz-transition-duration: .5s;
  transition-duration: .5s;
}
</style>
<script src="stacked-toc.min.js?active=0"></script>

Contoh

Labels: , ,

Tuesday, August 14, 2018

Gawai Daftar Isi Tabulasi untuk Blogger

Pembaruan 2018/08/13: Berbagai perubahan dan fitur baru telah ditambahkan untuk memenuhi saran dan permintaan para pengguna. Beberapa diskusi yang terdapat di dalam ruang komentar mungkin sudah tidak relevan lagi dengan isi artikel.

Widget Daftar Isi Tabulasi untuk Bogger

Berikut ini adalah sebuah gawai daftar isi blog berbentuk tabulasi. Gawai ini terdiri dari dua bilah sisi berupa daftar label dan daftar artikel. Setiap nama label akan menjadi tab, sedangkan daftar artikel akan menjadi panel tab yang akan tampil setiap kali tab diklik:

Lihat Demo


Integrasi Gawai ke Blogger

Pertama-tama klik menu Laman pada bilah sisi. Kemudian, pada menu Laman Baru pilihlah Laman Kosong:

Blogger Post Editor
Menambahkan halaman statis baru.

Setelah itu kamu akan melihat formulir halaman statis seperti ini. Klik mode HTML:

Blogger Post Editor
Memilih mode HTML.

Salin kode di bawah ini kemudian letakkan di dalam formulirnya:

<link href="//dte-project.github.io/blogger/tabbed-toc/224c19.min.css" rel="stylesheet">
<script src="//dte-project.github.io/blogger/tabbed-toc.min.js?url=http://dte-feed.blogspot.com&amp;active=0"></script>

Ganti URL yang Saya beri tanda dengan alamat blog Anda kemudian klik tombol Publikasikan.

Menghilangkan parameter url akan membuat gawai ini secara otomatis menentukan URL halaman muka berdasarkan URL pada bilah alamat. Berkas 224c19.min.css adalah berkas tema. Kamu bisa menghapus berkas tersebut jika kamu ingin membuat tema sendiri:

<style>
/* Kode tema kustom di sini… */
</style>
<script src="//dte-project.github.io/blogger/tabbed-toc.min.js?active=0"></script>

Pengaturan

Opsi Keterangan
url Ganti nilainya dengan alamat blog kamu atau alamat blog orang lain yang ingin kamu tampilkan kontennya.
id Alternatif untuk menentukan sumber data selain dengan url. Ganti nilainya dengan ID blog kamu atau ID blog orang lain yang ingin kamu tampilkan kontennya. ID harus dituliskan sebagai string. Menambahkan parameter id akan mengabaikan nilai parameter url. Contoh: id="4890949828965961610"
direction Direksi teks pada blog kamu. Nilainya bisa berupa "ltr" atau "rtl".
container Selektor CSS untuk menentukan di mana gawai akan ditampilkan. Menghilangkan parameter ini akan membuat gawai secara otomatis menempatkan diri tepat sebelum tag <script> yang kamu sisipkan.
active Digunakan untuk menentukan urutan tab yang akan aktif saat pertama kali halaman dimuat. Nilai 0 akan membuat tab di urutan pertama menjadi aktif. Nilai "Musim Gugur" akan membuat tab dengan label Musim Gugur menjadi aktif.
hide Tentukan nama-nama label yang tidak ingin kamu tampilkan.
date Ganti nilainya menjadi false untuk menyembunyikan waktu penerbitan artikel. Selain itu akan dianggap sebagai format waktu penerbitan: %Y% untuk menampilkan angka tahun, %M% untuk menampilkan angka bulan, %D% untuk menampilkan angka hari, %h% untuk menampilkan angka jam format 12, %m% untuk menampilkan angka menit, %s% untuk menampilkan angka detik, %M~% untuk menampilkan nama bulan, %D~% untuk menampilkan nama hari, %h~% untuk menampilkan angka jam format 24, dan %N% untuk menampilkan keterangan waktu format 12; nilainya bisa berupa "AM" atau "PM" tergantung dari data text[midday].
excerpt Ganti nilainya menjadi true untuk menampilkan ringkasan artikel. Atau gunakan angka untuk menentukan maksimal karakter yang akan ditampilkan dalam ringkasan artikel sebelum diakhiri oleh karakter .
image Ganti nilainya menjadi true untuk menampilkan gambar artikel. Atau gunakan angka untuk menentukan ukuran lebar dan tinggi gambar. Kamu juga bisa menggunakan parameter standar gambar Google untuk memanipulasi ukuran, seperti "s100", "s100-c", dan "w100-h50".
target Jika bernilai "_blank", semua tautan akan terbuka di tab/jendela baru saat diklik.
load Digunakan untuk menentukan waktu penundaan pemuatan JSON. Tentukan sebagai angka untuk waktu penundaan memuat dalam satuan milidetik atau true agar gawai ini memuat setelah keseluruhan halaman telah selesai termuat.
sort false untuk menyortir artikel secara normal berdasarkan bulan terbit, 1 untuk menyortir artikel dari A ke Z, -1 untuk menyortir artikel dari Z ke A.
recent false untuk menyembunyikan tanda New!. Ganti dengan angka untuk menentukan berapa banyak artikel terbaru yang ingin ditandai dengan label New!.
text[recent] Markup HTML bebas untuk membuat label New! pada artikel-artikel terbaru.
text[months] Digunakan untuk menentukan nama-nama bulan sesuai dengan sistem kalender di negara tempat kamu tinggal.
text[days] Digunakan untuk menentukan nama-nama hari sesuai dengan sistem kalender di negara tempat kamu tinggal.

Contoh

Menampilkan gambar dan ringkasan:

<script src="tabbed-toc.min.js?excerpt=200&amp;image=80"></script>

Membuat tab ke tiga aktif saat pertama kali halaman dimuat:

<script src="tabbed-toc.min.js?active=2"></script>

Membuat tab dengan label Iklan aktif saat pertama kali halaman dimuat:

<script src="tabbed-toc.min.js?active=Iklan"></script>

Menyembunyikan tab dengan label Iklan dan Tautan:

<script src="tabbed-toc.min.js?hide=["Iklan","Tautan"]"></script>
<script src="tabbed-toc.min.js?hide[0]=Iklan&amp;hide[1]=Tautan"></script>

Memodifikasi format waktu penerbitan (karakter % harus diubah menjadi %25):

<script src="tabbed-toc.min.js?date=%25Y%25-%25M%25-%25D%25%20%25h%25%3A%25m%25%3A%25s%25"></script>

Menentukan kontainer spesifik (karakter # harus diubah menjadi %23):

<script src="tabbed-toc.min.js?container=%23content"></script>

Kemudian, pada suatu tempat, Anda buat elemen HTML seperti ini:

<div id="content"></div>

Gunakan alat ini untuk mempermudah dalam mengubah karakter mentah menjadi karakter yang aman untuk URL.

Menyembunyikan iklan:

<script src="tabbed-toc.min.js?ad=false"></script>

Gawai ini Saya buat sebagai kode sumber yang terbuka sehingga Saya pada dasarnya tidak menghasilkan keuntungan apa-apa secara finansial. Ada baiknya kamu bersedia membantu Saya untuk menyebarkan alamat web ini dengan cara tidak menentukan nilai parameter ad sebagai false atau dengan cara berinisiatif memasang iklan pada web ini. Dengan begitu Saya dapat terus termotivasi untuk mengembangkan gawai-gawai yang ada. Menentukan nilai berupa angka akan membuat tautan web ini muncul setiap N sekali dimana N memiliki arti seberapa banyak pengunjung yang sama memuat ulang halaman kamu:

<script src="tabbed-toc.min.js?ad=10"></script>

Contoh

Labels: , ,

Wednesday, August 1, 2018

Widget Menu Navigasi Blogger Dari Sumber Berupa Objek

Konsep ini merupakan salah satu penerapan dari artikel berikut sebagai salah satu cara untuk menyederhanakan sintaks HTML elemen navigasi sebagai objek:

<b:widget id='HTML1' title='Navigation' type='HTML' version='1'>
  <b:widget-settings>
    <b:widget-setting name='content'>[{
    name: "Home",
    path: "/"
}]</b:widget-setting>
  </b:widget-settings>
  <b:includable id='main'>
    <b:with expr:value='data:content' var='array'>
      <b:include data='array' name='nav'/>
    </b:with>
  </b:includable>
  <b:includable id='nav' var='array'>
    <nav class='nav' id='nav'>
      <b:include data='array' name='ul'/>
    </nav>
  </b:includable>
  <b:includable id='ul' var='array'>
    <b:if cond='data:array.size > 0'>
      <ul>
        <b:loop values='data:array' var='this'>
          <b:include data='this' name='li'/>
        </b:loop>
      </ul>
    </b:if>
  </b:includable>
  <b:includable id='li' var='this'>
    <li>
      <b:class cond='path(data:view.url, data:this.path) == data:view.url' name='active'/>
      <b:include data='this' name='a'/>
      <b:if cond='data:this.children'>
        <b:include data='this.children' name='ul'/>
      </b:if>
    </li>
  </b:includable>
  <b:includable id='a' var='this'>
    <b:if cond='data:this.path || data:this.link'>
      <a>
        <b:attr expr:value='data:this.path ? path(data:view.url, data:this.path) : data:this.link' name='href'/>
        <b:attr cond='data:this.title' expr:value='data:this.title' name='title'/>
        <b:attr cond='data:this.target' expr:value='data:this.target' name='target'/>
        <data:this.name/>
      </a>
    <b:else/>
      <span class='a'><data:this.name/></span>
    </b:if>
  </b:includable>
</b:widget>

Kode CSS menu navigasi dapat Anda ambil dari sumber mana saja, selama selektor CSS adalah berupa .nav atau #nav (misalnya dari sini). Atau, Anda juga bisa menambahkan kelas kustom seperti ini sebagai cara untuk menyesuaikan kode HTML dengan kode CSS menu navigasi yang Anda dapatkan:

<b:includable id='nav' var='array'>
  <nav class='nav superfish' id='nav'>
    <b:include data='array' name='ul'/>
  </nav>
</b:includable>

Penggunaan

Masuk ke editor HTML Templat, salin dan tempel kode XML di atas ke dalam area <b:section> … </b:section> kemudian simpan perubahan. Anda mungkin perlu mengubah ID widget yang Saya beri tanda dengan urutan angka yang lain untuk mencegah duplikat ID widget. Setelah itu masuk ke editor Tata Letak. Di situ seharusnya sudah bertambah satu buah widget bertipe HTML/JavaScript dengan judul Navigation. Klik tombol Edit!

Setiap item menu tersimpan di dalam kontainer. Berikut ini adalah contoh kontainer menu yang masih kosong:

[]

Kemudian kita tambahkan sebuah menu, sebut saja Beranda:

[{
    name: "Beranda",
    path: "/"
}]

Kemudian kita tambahkan sebuah menu lagi bernama Profil:

[{
    name: "Beranda",
    path: "/"
}, {
    name: "Profil",
    path: "p/tentang-saya.html"
}]

Untuk tautan eksternal, gunakan atribut url sebagai pengganti path:

[{
    name: "Beranda",
    path: "/"
}, {
    name: "Profil",
    url: "//about.me/ta.tau.taufik"
}]

Judul dan target tautan juga dapat ditentukan seperti ini:

[{
    name: "Profil",
    url: "//about.me/ta.tau.taufik",
    title: "Taufik Nurrohman",
    target: "_blank"
}]

Anak-anak menu dapat dibuat kembali pada atribut children dengan aturan yang sama seperti sebelumnya:

[{
    name: "Profil",
    children: [{
        name: "Facebook",
        url: "//www.facebook.com/ta.tau.taufik"
    }, {
        name: "Google+",
        url: "//plus.google.com/+TaufikNurrohman"
    }]
}]

Contoh Objek

[{
    name: "Home",
    path: "/"
}, {
    name: "About",
    path: "p/about.html",
    children: [{
        name: "About Me",
        path: "p/about.html"
    }, {
        name: "Advertise",
        path: "p/advertise.html",
        children: [{
            name: "Method 1",
            path: "p/advertise-1.html"
        }, {
            name: "Method 2",
            path: "p/advertise-2.html"
        }]
    }]
}, {
    name: "Archive",
    path: "p/archive.html"
}, {
    name: "Contact",
    link: "//www.facebook.com/ta.tau.taufik",
    title: "Facebook",
    target: "_blank"
}]

Labels: , ,

Monday, May 29, 2017

JavaScript Atribusi Otomatis

Sticky Attribution

Setelah membuat Rich Text Editor, Saya jadi makin familiar dengan API Rentang Seleksi. Kali ini Saya membuat plugin dengan memanfaatkan fitur tersebut. Dengan tingkatan yang lebih sederhana lagi, sehingga akan mudah untuk diterapkan pada Blogger, yang Saya rasa akan bermanfaat terutama untuk para penulis yang tidak suka jika artikelnya disalin oleh penulis lain tanpa menyertakan tautan sumber yang asli.

Plugin ini tidak menjamin bahwa penyalin konten akan menyertakan tautan Anda pada artikel mereka, tapi setidaknya ini bisa memberikan sedikit peringatan. Selain itu, plugin ini juga memiliki beberapa keistimewaan, salah satunya adalah plugin ini tidak akan menambahkan tautan atribusi secara otomatis ketika teks yang disalin berada di dalam elemen <pre> dan <code>. Saya menambahkan fitur ini karena berdasarkan pengalaman Saya dulu, Saya juga pernah menggunakan plugin sejenis dari luar (kalau tidak salah namanya Tynt), tapi setiap kali Saya menyalin kode (yang tujuannya memang untuk disalin) untuk Saya gunakan, pada saat Saya menempelkan kode tersebut di suatu tempat, tautan atribusi ikut di dalamnya, sehingga orang yang tidak mengerti akan menganggap bahwa atribusi itu memang diperlukan padahal kemungkinan besar atribusi tambahan tersebut malah akan membuat kode menjadi error. Plugin ini juga akan mengembalikan seleksi ke posisi semula sesaat setelah aksi copy dilakukan.

Demo Halaman Proyek

Untuk mengaktifkan fitur ini di blog, cukup salin kode ini dan tempelkan di atas </body>:

<script>
//<![CDATA[
!function(e,t){var n="getSelection",o="removeAllRanges",i="addRange",l="parentNode",a="firstChild",d="appendChild",r="removeChild",s="test",c="innerHTML";if(e[n]){var p,g,f,h,u,y;t.addEventListener("copy",function(C){for(g=C.target;3===g.nodeType;)g=g[l];if(h=t.createElement("div"),(p=e[n]())&&p.rangeCount&&(p=p.getRangeAt(0))&&(f=p.cloneRange(),p=p.cloneContents())){for(;u=p[a];)h[d](u);if(!/^(pre|code)$/i[s](g.nodeName||"")&&!/(^|\s)no-attribution(\s|$)/i[s](g.className||"")){var v=e.location.href;h[c]+="<br><br>&copy; "+t.title+'<br>Source: <a href="'+v+'">'+v+"</a>"}y=t.createRange(),t.body[d](h),y.selectNodeContents(h),p=e[n](),p[o](),p[i](y),setTimeout(function(){h[l][r](h),p[o](),p[i](f)})}},!1)}}(window,document);
//]]>
</script>

Simpan perubahan.

Labels: ,

Saturday, May 17, 2014

Kondisional Halaman “selected” pada Widget Label Blogspot Tidak Konsisten

Saya anggap Anda sedang memakai widget Label/Kategori yang masih murni merupakan bawaan dari Blogger. Saat kita mengunjungi halaman label, pada bagian tautan label seharusnya akan berubah menjadi elemen <span> yang tidak bisa diklik seperti ini:

Label Widget in Blogspot
Tanda bahwa halaman label “JavaScript” sedang dikunjungi.

Ini bagus, karena widget dapat memberikan informasi kepada kita mengenai di mana kita sedang berada saat itu. Akan tetapi, ketika kita mengeklik tautan menuju posting yang lebih lama, tanda tersebut malah hilang:

Broken Label Widget
Tanda yang menyatakan bahwa halaman label “JavaScript” sedang dikunjungi rusak pada halaman berikutnya.

Ini tidak bagus. Tanda label tersebut seharusnya bisa tetap ada meskipun kita sudah berpindah-pindah ke halaman yang lain asalkan kita masih berada dalam halaman indeks kategori/label yang sama. Ini terjadi karena kondisional penanda pada widget label sudah salah sejak awal. Perhatikan bagian yang Saya tandai:

<b:widget id='Label1' locked='false' title='Label' type='Label'>
  <b:includable id='main'>
    <b:if cond='data:title'>
      <h2><data:title/></h2>
    </b:if>
    <div expr:class='&quot;widget-content &quot; + data:display + &quot;-label-widget-content&quot;'>
      <b:if cond='data:display == &quot;list&quot;'>
        <ul>
          <b:loop values='data:labels' var='label'>
            <li><b:if cond='data:blog.url == data:label.url'>                <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
              <b:else/>
                <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
              </b:if>
              <b:if cond='data:showFreqNumbers'>
                <span dir='ltr'>(<data:label.count/>)</span>
              </b:if>
            </li>
          </b:loop>
        </ul>
      <b:else/>
        <b:loop values='data:labels' var='label'>
          <span expr:class='&quot;label-size label-size-&quot; + data:label.cssSize'><b:if cond='data:blog.url == data:label.url'>              <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
            <b:else/>
              <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
            </b:if>
            <b:if cond='data:showFreqNumbers'>
              <span class='label-count' dir='ltr'>(<data:label.count/>)</span>
            </b:if>
          </span>
        </b:loop>
      </b:if>
      <b:include name='quickedit'/>
    </div>
  </b:includable>
</b:widget>

Menggunakan perbandingan URL sebagai kondisional halaman label tidak akan berhasil, karena URL pada setiap halaman itu pasti akan berubah-ubah meskipun kita masih berada pada kategori/label yang sama. Untuk memperbaikinya, ganti kode yang Saya beri tanda dengan ini:

<b:if cond='data:blog.searchLabel == data:label.name'>

Simpan perubahan.

Labels: , ,

Saturday, February 8, 2014

PHP Flat-File GuestBook

Flat-File Guestbook in PHP
Tampilan Buku Tamu

Saya membuat aplikasi Buku Tamu tanpa basis data dengan PHP. Semua data disimpan di dalam sebuah file TXT sebagai pengganti basis data. Ide asli diambil dari sini.

Pada versi Saya, Saya tidak menggunakan captcha gambar, melainkan hanya menggunakan tantangan matematika yang lebih sederhana namun relatif aman. Kode ini dituliskan secara baru, mulai dari awal dan bukan merupakan hasil modifikasi. Beberapa fitur baru yang Saya berikan:

  • Memungkinkan pengguna untuk menambahkan URL.
  • Tanggal penerbitan tersedia, dan akan ditampilkan di pojok kanan atas secara normal.
  • Memungkinkan pengguna untuk membagikan pesan secara individual melalui tautan permanen.
  • Memungkinkan administrator untuk membuat “database” baru tanpa harus menghapus data yang lama.
  • Memungkinkan administrator dan pengguna untuk memuat data lama melalui parameter URL berupa nama file.
  • Sistem keamanan yang lebih baik:
    • Pengguna wajib menjawab tantangan matematika sederhana.
    • Pembatasan jumlah karakter pada setiap bidang.
    • Secara otomatis mengubah kode HTML menjadi entitas HTML untuk keamanan, dan hanya akan menerjemahkan kode HTML yang diperbolehkan saja.
    • Pesan kesalahan akan tampil lebih jelas, serta data yang telah pengguna masukkan sebelumnya ke dalam formulir akan tetap tersimpan di sana sebelum pengguna berhasil mengirimkan pesannya.
    • Tautan di dalam pesan akan terhapus secara otomatis.

Lihat Demo Sementara Unduh Berkas Lihat Kode Sumber

Ekstrak file unduhan untuk mendapatkan folder guestbook. Masukkan folder tersebut beserta isinya ke dalam folder public_html atau www pada server lokal Anda. Tidak perlu konfigurasi khusus. Sekali pasang langsung jalan! Jika Anda ingin melakukan konfigurasi, maka itu hanya sebatas pada penamaan “database”, pengaturan panjang karakter maksimal dan penyesuaian teks pesan peringatan.

Jika sudah selesai, buka alamat http://localhost/guestbook/index.php pada peramban untuk melihat hasilnya.

Tidak ada fitur emotikon. Terlalu berlebihan untuk diterapkan pada aplikasi yang sederhana dan bukan merupakan kebutuhan primer. Anda bisa dengan mudah membuatnya sendiri melalui perintah preg_replace() seperti ini:

$message = preg_replace(
    array(
        '/( |>)\:\-?\)/',
        '/( |>)\:\-?D/',
        '/( |>)\:\-?\)/',
        ...
        ...
    ),
    array(
        '$1<img src="emoticons/smile.gif" alt=":)">',
        '$1<img src="emoticons/laugh.gif" alt=":D">',
        '$1<img src="emoticons/sad.gif" alt=":(">',
        ...
        ...
    ),
$message);

Ketika Data Dirasa telah Penuh

Ketika Anda merasa bahwa file TXT yang Anda buat sudah terlalu besar ukurannya, atau membuat proses muat halaman menjadi lambat, Anda bisa mengatasinya dengan cara mengganti nilai $database dengan nama yang baru untuk menciptakan file TXT baru tanpa harus menghapus yang lama. Untuk memuat data yang lama ke dalam halaman buku tamu agar bisa ditampilkan ke publik (katakanlah Anda telah membuat pengaturan khusus agar pengguna tidak bisa melihat file dengan format TXT), Anda bisa menambahkan parameter data dengan nilai berupa nama “database” seperti ini:

http://localhost/guestbook/index.php?data=database-003

Atau kalau memang data-data di dalam buku tamu Anda itu tidak penting, Anda bisa menghapus file tersebut begitu saja kalau mau. Semua kode sudah Saya lengkapi dengan penjelasan. Silakan dipelajari atau digunakan jika dirasa berguna.

Labels: ,

Sunday, December 22, 2013

Membuat Posting Layar Penuh

Mode layar penuh.
Mode layar penuh.

Saya membuat sebuah aplikasi/widget kecil untuk membuat posting di blog menjadi memiliki alternatif tampilan “layar penuh”. Tidak benar-benar layar penuh sebenarnya, karena widget ini hanya bekerja dengan cara menyisipkan tabir baru berisi duplikat judul dan konten posting. Kalau Anda ingin membuat fitur full screen sungguhan yang bisa memenuhi seluruh layar, Anda bisa mempelajari API JavaScript ini ⇒ MDN – Using Full Screen Mode

Lihat Demo

Untuk memasang widget ini, masuklah ke halaman editor HTML Templat, lalu letakkan kode ini di atas </body>:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <script src='https://cdn.rawgit.com/tovic/dte-project/2fd2d2971c3398029ea5e149696447243e7f4d94/full-screen.min.js'/>
  <script>
  //<![CDATA[
  postFullScreen({
    titleSource: document.querySelector('.post-title'),
    contentSource: document.querySelector('.post-body'),
    background: "#fff",
    color: "inherit",
    fontSize: "120%",
    padding: 50,
    maxWidth: 750,
    openText: "Full Screen Mode",
    closeText: "Exit full screen mode",
    appendButtonTo: null,
    beforeInit: null,
    afterInit: null
  });
  //]]>
  </script>
</b:if>

Atau Saya sarankan lebih baik letakkan kode di atas sedekat mungkin dengan posting. Lebih tepatnya di bagian paling bawah dari posting:

<b:section class='main' id='main' showaddelement='no'>
  <b:widget id='Blog1' locked='true' title='Posting Blog' type='Blog'> … </b:section>
</b:section>
<!-- Letakkan di sini -->

Klik Simpan Templat.

Konfigurasi

Opsi Keterangan
titleSource Selektor elemen HTML dimana di dalamnya berisi teks judul. Di atas Saya menggunakan selektor document.querySelector('.post-title') untuk memperoleh teks judul dari dalam elemen <h3 class='post-title'></h3>. Sebagai alternatif, Anda bisa mencoba untuk menggunakan selektor document.title untuk memperoleh judul dari address bar.
contentSource Selektor elemen HTML dimana di dalamnya terdapat konten artikel/posting. Pengaturannya sama persis dengan opsi titleSource.
background Digunakan untuk menentukan warna latar tabir layar penuh.
color Digunakan untuk menentukan warna teks mode layar penuh. inherit artinya warna menyesuaikan dengan warna teks posting.
fontSize Digunakan untuk menentukan besar teks di artikel layar penuh.
padding Digunakan untuk menentukan padding tabir layar penuh.
maxWidth Digunakan untuk menentukan lebar maksimal area artikel layar penuh.
openText Digunakan untuk menentukan teks tombol pemicu layar penuh.
closeText Digunakan untuk menentukan teks tombol penutup tampilan layar penuh.
createButton Digunakan untuk membuat tombol kustom. Lihat penjelasan di bawah.
appendButtonTo Nilai berupa selektor elemen HTML. Jika nilainya null, tombol akan secara otomatis disisipkan di bawah posting. Jika nilainya false, tombol tidak akan disisipkan secara otomatis (bermanfaat jika Anda ingin membuat tombol pemicu tersendiri secara terpisah).
beforeInit Lihat penjelasan di bawah.
afterInit Lihat penjelasan di bawah.

Penjelasan Ekstra

createButton

Opsi ini digunakan sebagai alternatif jika Anda tidak suka dengan tampilan tombol pemicu layar penuh secara normal. Anda bisa memanfaatkan opsi ini untuk menentukan/membuat elemen tombol kustom. Sebagai contoh di sini Saya menggunakan elemen tautan sebagai tombol:

var buttonMarkup = document.createElement('a');
    buttonMarkup.className = "custom-button";
    buttonMarkup.style.display = "block";
    buttonMarkup.style.marginTop = "20px";

postFullScreen({
    openText: "Layar Penuh!",
    createButton: buttonMarkup
});

/*

akan menghasilkan ini:

<a class="custom-button" style="display:block;margin-top:20px;">Layar Penuh!</a>

*/

Lihat Demo

Atau Anda juga bisa menentukan nilainya sebagai objek yang sudah ada. Sebagai contoh Anda membuat tombol pemicu secara manual di tempat tertentu, misalnya di sidebar:

<aside>
  ...
  <button id="full-screen-button">Layar Penuh</button>
  ...
  ...
</aside>

Kemudian Anda bisa melakukan ini untuk membuat tombol tersebut menjadi aktif:

postFullScreen({
    createButton: document.getElementById('full-screen-button'),
    appendButtonTo: false
});

Jangan lupa untuk mengatur opsi appendButtonTo menjadi false karena jika tidak tombol tersebut mungkin akan berpindah tempat. Secara umum akan berpindah ke bagian akhir posting:

Lihat Demo

appendButtonTo

Opsi ini digunakan untuk menentukan ke mana tombol pemicu tampilan layar penuh akan disisipkan. Berikut ini adalah sebuah contoh jika Anda ingin menyisipkan tombol pemicu layar penuh di dalam elemen #button-container:

<div id="button-container"></div>
postFullScreen({
    ...
    appendButtonTo: document.getElementById('button-container')
});

Lihat Demo

beforeInit dan afterInit

Ini adalah opsi untuk membuat fungsi bebas yang akan tereksekusi sebelum (untuk beforeInit) dan sesudah (untuk afterInit) markup tabir tersisip ke blog. Yang paling berguna adalah beforeInit. Fungsi ini bisa Anda gunakan untuk memastikan bahwa manipulasi konten posting yang dilakukan oleh JavaScript telah dilakukan sebelum widget ini tereksekusi. Misalnya mengenai Syntax Highlighter atau JavaScript emotikon. Jika Syntax Highlighter atau JavaScript emotikon tidak diaktifkan sebelum widget ini aktif, maka kemungkinannya posting-posting kode yang berada di dalam artikel layar penuh tidak akan berwarna, dan emotikon-emotikon di dalam artikel tidak akan berubah menjadi gambar:

postFullScreen({
    beforeInit: function() {
        repText('post-12345');
        hljs.initHighlighting();
    },
    afterInit: function() {
        alert('OK!');
    }
});

Pengguna jQuery

Jangan lupa untuk menambahkan indeks [0] setelah selektor jika Anda menggunakan API selektor elemen jQuery:

postFullScreen({
    titleSource: $('.post-title')[0],
    contentSource: $('.post-body')[0]
});

Labels: ,

Wednesday, September 25, 2013

Membuat Formulir Kontak Google Doc Agar Bisa Mengirimkan Datanya Langsung ke Kotak Pesan Email

Posting ini membutuhkan pembaharuan → Google Apps Script – Error: “DocsList” not Defined

Sebenarnya Google Doc bukan merupakan layanan untuk membuat aplikasi-aplikasi semacam ini. Membuat formulir kontak menggunakan Google Doc hanya bisa menampilkan pesan di spreadsheet, dan bukannya langsung menuju kotak masuk pesan seperti yang kita kehendaki. Karena fungsi utama Google Doc pada dasarnya memang bukan untuk membuat formulir kontak semacam itu, melainkan untuk membuat formulir yang terintegrasi dengan dokumen, sehingga ini memungkinkan pengguna untuk bisa mengirimkan data secara online. Dan dari formulir itulah data bisa langsung terkirim dan akan tersimpan ke dalam dokumen berbentuk tabel.

Blogger Xpertise memiliki solusi agar data pesan yang dikirimkan melalui formulir Google Doc bisa langsung terkirim menuju pesan masuk email Anda seperti ini:

Contact results - Google Drive
Data kontak langsung terlihat di pesan masuk.

Di sini Saya akan menjelaskan langkah-langkah pembuatan formulir kontak dimulai dari awal sampai akhir. Ada dua bagian utama yang harus Anda kerjakan di sini, yaitu membuat formulir kontak dan mengelola spreadsheet yang terkait dengan formulir kontak tersebut.

Membuat Formulir Kontak

Di sini Anda akan diajak untuk membuat formulir kontak menggunakan Google Doc.

Pertama-tama buka halaman dasbor Google Drive Anda, lalu buat sebuah formulir:

Create a new form - Google Drive
Membuat formulir baru.

Tentukan judul dan deskripsi formulir, serta buat beberapa kotak pertanyaan yang umum terdapat pada formulir kontak di web. Misalnya: Perihal, Nama, Email, Alamat Web dan Pesan:

Form configuration - Google Drive
Membuat formulir.

Pada bagian Laman Konfirmasi, tuliskan pesan terima kasih yang ingin Anda tampilkan ketika pesan telah berhasil terkirim:

Sent message setup - Google Drive
Menyunting pesan ucapan terima kasih.

Klik tombol Kirim Formulir. Akan muncul kotak dialog baru. Klik tombol Sematkan. Di situ Anda akan diberi kode embed formulir kontak yang bisa Anda pasang pada halaman web Anda. Atau Anda juga bisa melihat hasil jadinya pada halaman formulir khusus dengan menekan tombol Lihat Bentuk Jadi di panel atas, tepat di bawah menu utama.

Klik tombol Pilih Tujuan Tanggapan, lalu cek opsi Spreasheet baru. Berikan judul, misalnya Data Tanggapan:

Create new spreadsheet - Google Drive
Membuat spreadsheet baru.

Klik tombol Buat. Tunggu sampai tombol Lihat Tanggapan muncul. Pada tampilan Google Doc saat ini, tombol Lihat Tanggapan akan muncul untuk menggantikan tombol Pilih Tujuan Tanggapan. Klik tombol tersebut untuk melihat spreadsheet formulir kontak Anda.

Mengelola Data yang Masuk

Setelah spreadsheet tercipta, sekarang adalah saatnya untuk mengelola data yang masuk agar setiap kali data baru terkirim ke dokumen, maka salinan data tersebut bisa langsung masuk ke kotak pesan email.

Pilih menu Alat » Editor skrip:

Script editor menu - Google Drive
Editor skrip.

Anda akan dibawa menuju halaman proyek tak berjudul. Pada formulir bernama Kode.gs tempelkan JavaScript ini:

function sendFormByEmail(e) {

  // Tentukan teks subjek/perihal yang nantinya akan muncul pada pesan masuk email setiap kali pesan baru terkirim
  var emailSubject = "PESAN BARU!";

  // Tentukan alamat email di sini atau beberapa alamat email sekaligus yang dipisahkan dengan tanda koma
  var yourEmail = "email@domain.com";

  // Masukkan kunci spreadsheet yang terhubung dengan formulir kontak ini
  // Bisa ditemukan pada URL ketika Anda melihat spreadsheet tersebut
  var docKey = "0Ah0bOy8H_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

  // Jika Anda menginginkan skrip ini mengirim data secara otomatis ke semua editor sheet, set nilainya menjadi `1`
  // Jika Anda hanya ingin mengirimkan data ke `yourEmail`, set nilainya menjadi `0`
  var useEditors = 1;

  // Apakah Anda telah menambahkan kolom yang ternyata tidak Anda gunakan pada formulir?
  // Jika ya, set nilai ini ke nomor urut kolom terakhir yang Anda tambahkan pada spreadsheet.
  // Sebagai contoh: Kolom `C` ada pada nomor urut ke 3
  var extraColumns = 0;

  if (useEditors) {
    var editors = DocsList.getFileById(docKey).getEditors();
    var notify = (editors) ? editors.join(',') : yourEmail;
  } else {
    var notify = yourEmail;
  }

  // Variabel `e` memegang semua data di dalam array.
  // Loop semua data di dalam array dan sisipkan nilainya ke pesan.
  var s = SpreadsheetApp.getActive().getSheetByName("Data1");
  if (extraColumns) {
    var headers = s.getRange(1, 1, 1, extraColumns).getValues()[0];
  } else {
    var headers = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0];
    var message = "";
  }
  for (var i in headers) {
    message += headers[i] + ' = ' + e.values[i].toString() + '\n';
  }
  MailApp.sendEmail(notify, emailSubject, message);
}

Tentukan subjek email, alamat email dan kunci/ID spreadsheet yang tadi Anda buat. ID spreadsheet bisa Anda temukan pada URL spreadsheet terkait:

https://docs.google.com/spreadsheet/ccc?key=0Ah0bOy8H_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#gid=0

Data1 adalah nama sheet. Pastikan nilainya sama dengan sheet terkait:

Sheet rename - Goole Drive
Memberi nama sheet.

Sekarang pilih menu Sumber Daya » Pemicu proyek saat ini. Akan muncul kata “No triggers set up. Click to add one now”. Klik pada tautan tersebut untuk menambahkan trigger. Pada kolom Events, pastikan opsi yang terpilih adalah From spreadsheet dan On form submit.

Script trigger authorization - Google Drive
Pemicu proyek.…

Klik opsi notification. Pada opsi ke dua di kotak dialog Execution failure notifications, pilih immediately.

Klik OK.

Akan muncul pesan authorisasi skrip. Klik tombol Terima/Authorize. Ini akan menyetujui authorisasi untuk trigger yang Anda buat.

Anda akan dibawa kembali menuju layar editor. Klik Simpan/Save. Sekarang Anda sudah bisa mencoba mengirimkan pesan melalui formulir kontak buatan Anda. Pembuatan formulir kontak ini sudah selesai.

Setelah ini mungkin Anda akan menerima pesan error ke kotak pesan email. Beruntung jika tidak. Selebihnya hanyalah mengenai pemecahan masalah error yang terjadi. Saya pribadi belum pernah mengalami masalah-masalah yang rumit. Jadi Saya masih belum bisa membuat daftar kemungkinan error yang terjadi di sini. Berikut ini adalah beberapa hal yang perlu diperhatikan menurut Blogger Xpertise:

  1. Pastikan nama sheet tidak mengandung karakter spasi. Ini mungkin bisa menimbulkan errorSheet Saya mengandung karakter spasi, tetapi Saya tidak mengalami masalah itu.
  2. Jangan sampai ada kolom yang kosong yang Anda tambahkan ke dalam spreadsheet kontak. Ini akan menciptakan masalah pada perataan data yang masuk serta membuat skrip gagal bekerja ⇐ Saya mengalami masalah ini sebelumnya gara-gara menambahkan dan memindahkan kolom baru, serta karena menambahkan field pertanyaan baru pada formulir kontak yang Saya buat. Jadi pastikan formulir yang Anda buat sudah benar-benar menetap.
  3. Nama kolom terkadang juga dapat menimbulkan masalah. Pastikan Anda membuat nama kolom/pertanyaan formulir dengan karakter teks yang standar.

Menonaktifkan Notifikasi pada Kiriman Email Spam

Karena formulir kontak ini tidak memiliki captcha maka seringkali Anda akan mendapatkan pesan-pesan aneh yang datang entah dari mana. Berikut ini adalah sebuah cara untuk membuat agar pesan notifikasi tidak dikirimkan ke email Anda jika submisi pesan yang dilakukan terdeteksi sepagai spam:

function sendFormByEmail(e) {

  // Tentukan teks subjek/perihal yang nantinya akan muncul pada pesan masuk email setiap kali pesan baru terkirim
  var emailSubject = "PESAN BARU!";

  // Tentukan alamat email di sini atau beberapa alamat email sekaligus yang dipisahkan dengan tanda koma
  var yourEmail = "email@domain.com";

  // Masukkan kunci spreadsheet yang terhubung dengan formulir kontak ini
  // Bisa ditemukan pada URL ketika Anda melihat spreadsheet tersebut
  var docKey = "0Ah0bOy8H_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

  // Jika Anda menginginkan skrip ini mengirim data secara otomatis ke semua editor sheet, set nilainya menjadi `1`
  // Jika Anda hanya ingin mengirimkan data ke `yourEmail`, set nilainya menjadi `0`
  var useEditors = 1;

  // Apakah Anda telah menambahkan kolom yang ternyata tidak Anda gunakan pada formulir?
  // Jika ya, set nilai ini ke nomor urut kolom terakhir yang Anda tambahkan pada spreadsheet.
  // Sebagai contoh: Kolom `C` ada pada nomor urut ke 3
  var extraColumns = 0;

  if (useEditors) {
    var editors = DocsList.getFileById(docKey).getEditors();
    var notify = (editors) ? editors.join(',') : yourEmail;
  } else {
    var notify = yourEmail;
  }

  // Cek pesan spam: `0` berarti tidak ada spam
  var isSpam = 0;

  // Isi dengan pola-pola spam yang ingin Anda blokir dalam format regular ekspresi
  var spamKeywords = [
    /beijing escort|louis vuitton|www\.nama_web_1\.com|www\.nama_web_2\.com/i,
    /(buy|cheap)(ing|est)/i,
    /fuck|shit|sex|xxx/i
    ...
    ...
  ];

  // Variabel `e` memegang semua data di dalam array.
  // Loop semua data di dalam array dan sisipkan nilainya ke pesan.
  var s = SpreadsheetApp.getActive().getSheetByName("Data1");
  if (extraColumns) {
    var headers = s.getRange(1, 1, 1, extraColumns).getValues()[0];
  } else {
    var headers = s.getRange(1, 1, 1, s.getLastColumn()).getValues()[0];
    var message = "";
  }
  for (var i in headers) {
    message += headers[i] + ' = ' + e.values[i].toString() + '\n';
    for (var j = 0, sk = spamKeywords.length; j < sk; ++j) {
      // Jika data terdeteksi sebagai spam, tingkatkan nilai variabel `isSpam`
      if (spamKeywords[j].test(e.values[i].toString())) isSpam++;
    }
  }
  if (isSpam === 0) { // Kirimkan notifikasi jika nilai `isSpam` adalah `0`
    MailApp.sendEmail(notify, emailSubject, message);
  }
}

Anda bisa mengatur pola spam pada variabel spamKeywords sesuka hati dengan jumlah pola sebanyak yang Anda mau dalam bentuk regular ekspresi. Jika Anda tidak mengerti atau belum menguasai regular ekspresi, Anda bisa menggunakan deteksi spam yang lebih sederhana menggunakan pengecekan indeks teks:

var spamKeywords = [
  "beijing escort"
  "louis vuitton"
  "www.nama_web_1.com",
  "www.nama_web_2.com",
  "buy",
  "cheap",
  ...
  ...
];
if (e.values[i].toString().indexOf(spamKeywords[j]) > -1) isSpam++;

Walaupun begitu, cara ini hanya bisa digunakan untuk mencegah terkirimnya notifikasi pesan masuk saja jika pesan yang dikirimkan adalah pesan spam, dan tidak bisa mencegah terkirimnya data pesan spam ke dalam spreadsheet. Saya sarankan Anda untuk secara rutin membuka sheet terkait formulir kontak ini minimal setiap satu bulan sekali untuk menghapus data-data yang tidak diperlukan. Karena Saya tidak bisa menjamin tentang apa yang akan terjadi pada data Google Doc Anda jika jumlah data yang masuk nanti sudah terlalu besar.

Bacaan Lebih Lanjut

Labels: , , ,