Mecha versi 2.6.4 sudah dirilis!

Fitur Multi-Bahasa pada Tema Blogger

Cara membuat tema Blogger agar bisa diterjemahkan ke dalam bahasa asing.

Tabel Konten
  1. Sintaks XML 
  2. Pengaturan Bahasa 
  3. Eksperimen 

Fitur multi-bahasa pada Blogger sebenarnya sudah lama ada, namun sifatnya sangat tertutup. Data bahasa tersimpan sebagai properti objek dan nilainya tidak bisa diubah oleh pengembang tema.

<h3>
  <b:if cond='data:post.numComments == 1'>
    1 <data:commentLabel/>
  <b:else/>
    <data:post.numComments/> <data:commentLabelPlural/>
  </b:if>
</h3>

Setiap item bahasa tersimpan sebagai data global dan dapat diakses secara langsung melalui elemen <data:*> di mana saja, termasuk di luar lingkup gawai.

Karena sifatnya yang tertutup, para pengembang tema yang ingin menggunakan frase yang berbeda pada elemen blog mereka menjadi harus menuliskannya secara manual, sehingga tidak fleksibel, karena frase tersebut tidak bisa menyesuaikan diri dengan pilihan bahasa antarmuka saat itu.

<h3>
  <b:if cond='data:post.numComments == 0'>
    No Comments
  <b:elseif cond='data:post.numComments == 1'>
    1 Comment
  <b:else/>
    <data:post.numComments/> Comments
  </b:if>
</h3>

Bahasa antarmuka bawaan pada Blogger bisa ditentukan melalui panel kontrol seperti ini:

Pengaturan bahasa antarmuka.
Pengaturan bahasa antarmuka melalui panel kontrol.

Tapi, para pengunjung blog kalian sebenarnya juga bisa menentukan bahasa antarmuka blog melalui kueri hl pada URL seperti ini:

/2020/29/lorem-ipsum.html?hl=fr

Sintaks XML 

Sekitar tahun 2017 yang lalu, Blogger memperkenalkan parameterisasi pada fitur multi-bahasa. Yaitu dengan memanfaatkan tag <b:message> untuk menampung frase, dan <b:param> untuk menentukan nilai parameter pada frase tersebut bila ada. Semua frase bahasa juga sudah dikelompokkan ke dalam objek messages sehingga tidak membuat polusi pada lingkungan global.

<b:message name='messages.numberOfComments'>
  <b:param expr:value='data:post.numberOfComments' name='numComments'/>
</b:message>

Pada contoh di atas, variabel data:post.numberOfComments menyatakan jumlah komentar sebagai angka. Kalian juga bisa menggunakan nilai baku jika memang harus, misalnya untuk melakukan pengetesan.

<h3>
  <b:message name='messages.numberOfComments'>
    <b:param name='numComments' value='30'/>
  </b:message>
</h3>

Jika disimulasikan sebagai bahasa pemrograman JavaScript, maka kode di atas dapat dinyatakan sebagai berikut:

const numberOfComments = numComments => {
    if (0 === numComments) {
        return `No comments`;
    }
    if (1 === numComments) {
        return `1 comment`;
    }
    return `${numComments} comments`;
}

console.log(`<h3>${numberOfComments(30)}</h3>`);

Jika tidak terdapat parameter pada frase tersebut, maka frase dapat dipanggil menggunakan elemen <data:*> seperti biasa:

<data:messages.postAComment/>

Variabel data:messages.numberOfComments berfungsi untuk menampilkan frase. Data pada frase ini tidak pernah didokumentasikan, sehingga kita tidak tahu ada parameter apa saja di dalam data tersebut, dan teks seperti apa yang akan dikembalikan dari waktu ke waktu. Menampilkan frase yang mengandung parameter seperti data:messages.numberOfComments secara langsung akan mengembalikan data berupa teks seperti ini:

{numComments, plural, =0 {No comments} =1 {1 comment} other {# comments}}

Pihak Blogger bisa saja mengubah dan bahkan menghapus nilainya di masa depan jika mereka mau. Hal ini Saya sadari ketika beberapa hari yang lalu Saya coba untuk menampilkan nilai variabel data:commentLabel dan data:commentLabelPlural di dalam tema. Pada tema Blogger V3, data-data tersebut sudah tidak ada lagi, sehingga tidak akan mengembalikan pesan apa-apa di dalam tema.

Dalam banyak kasus, ketika kita ingin membuat tema dengan fitur yang kompleks, kita pasti perlu menentukan frase-frase khusus untuk ditambahkan ke dalam tema. Frase-frase ini, karena bukan merupakan bagian dari data standar Blogger, maka harus dinyatakan secara manual atau langsung sebagai teks biasa. Sehingga tidak jarang kita akan menemui beberapa frase di dalam tema kustom yang nilainya tidak berubah meskipun bahasa antarmuka blog sudah diubah ke bahasa lokal.

Untuk mengatasi masalah tersebut, kita bisa memanfaatkan nilai data:blog.locale untuk mengatur nilai frase yang kita buat:

<h3>
  <data:post.numberOfComments/>
  <b:switch var='data:blog.locale.language'>
    <b:case value='en'/>
      <b:eval expr='data:post.numberOfComments == 1 ? "Comment" : "Comments"'/>
    <b:case value='fr'/>
      <b:eval expr='data:post.numberOfComments == 1 ? "Commentaire" : "Commentaires"'/>
    <b:case value='id'/>
    <b:case value='in'/>
      Komentar
    <b:default/>
      <!-- Comments -->
  </b:switch>
</h3>

Pengaturan Bahasa 

Untuk membuat data frase buatan menjadi lebih mudah dikontrol, Saya lebih menyarankan kalian untuk menyimpan data-data frase tersebut sebagai objek global yang dikategorisasikan berdasarkan kode ISO 639 seperti ini:

<!DOCTYPE html>
<html>
  <b:with value='{
      en: {
          comment: "Comment",
          comments: "Comments",
          delete: "Delete",
          reply: "Reply"
      },
      fr: { … },
      id: { … },
      pt: { … },
      vi: { … },
      …
  }' var='i18n'>

    <head> … </head>
    <body> … </body>

  </b:with>
</html>

Sebagai catatan, kode standar negara Indonesia sejak tahun 2002 sudah direvisi menjadi id pada ISO 639-1:2002, tapi sepertinya Blogger masih menggunakan versi kode negara yang lama yaitu in.

Sebagai catatan juga, Blogger sampai saat ini tidak mendukung fitur interpolasi variabel, sehingga kita tidak bisa melakukan sesuatu semacam ini untuk memanggil properti secara dinamis:

<data:i18n.<data:blog.locale.language/>.comment/>

Satu-satunya cara yang bisa kita lakukan untuk mendapatkan efek serupa saat ini adalah dengan menggunakan metode seperti ini:

<b:switch var='data:blog.locale.language'>
  <b:case value='fr'/>
    <data:i18n.fr.comment/>
  <b:case value='id'/>
  <b:case value='in'/>
    <data:i18n.id.comment/>
  <b:case value='pt'/>
    <data:i18n.pt.comment/>
  <b:case value='vi'/>
    <data:i18n.vi.comment/>
  <b:default/>
    <data:i18n.en.comment/>
</b:switch>

Eksperimen 

Saya belum pernah mencobanya pada data berukuran besar, tapi menggunakan metode ini ternyata berhasil. Di sini Saya juga telah menambahkan objek dengan nilai properti id berupa id sesuai dengan standar ISO 639-1:2002 untuk berjaga-jaga jika suatu saat nanti Blogger memutuskan untuk memperbarui daftar kode negara mereka. Data-data frase di dalam objek tersebut harus sama dengan data-data frase di dalam objek dengan properti id dengan nilai in:

<b:with value='[
    {
        id: "en",
        i18n: {
            comment: "Comment",
            comments: "Comments"
        }
    }, {
        id: "fr",
        i18n: { … }
    }, {
        id: "id",
        i18n: { … }
    }, {
        id: "in",
        i18n: { … }
    }, {
        id: "pt",
        i18n: { … }
    }, {
        id: "vi",
        i18n: { … }
    }
]' var='i18n'>

  …

</b:with>

Kita ambil data pertama yang lolos dari pengetesan persamaan nilai properti id dengan nilai data:blog.locale.language saat ini, kemudian tampung hasilnya pada variabel i:

<b:with value='[ … ]' var='i18n'>
  <b:with value='data:i18n first (v => v.id == data:blog.locale.language)' var='i'>

    …

  </b:with>
</b:with>

Kemudian kita referensikan variabel i.i18n kembali kepada variabel i18n:

<b:with value='[ … ]' var='i18n'>
  <b:with value='data:i18n first (v => v.id == data:blog.locale.language)' var='i'>
    <b:with value='data:i.i18n' var='i18n'>

      …

    </b:with>
  </b:with>
</b:with>

Sehingga kita bisa memanggil nilai properti comment secara dinamis berdasarkan bahasa saat ini melalui variabel i18n seperti ini:

<b:with value='[ … ]' var='i18n'>
  <b:with value='data:i18n first (v => v.id == data:blog.locale.language)' var='i'>
    <b:with value='data:i.i18n' var='i18n'>

      1 <data:i18n.comment/>

    </b:with>
  </b:with>
</b:with>

Sejak Saya menulis artikel ini, data objek yang dituliskan secara manual seperti pada contoh-contoh di atas akan dihilangkan semua karakter ganti barisnya oleh Blogger, sehingga akan tampak berantakan setelah kode tema disimpan. Cara terbaik untuk menjaga agar kode tema tetap rapi adalah dengan meniadakan semua karakter ganti baris dan indentasi yang ada:

<b:with value='[{id:"en",i18n:{comment:"Comment",comments:"Comments"}},{id:"fr",i18n:{…}},{id:"id",i18n:{…}},{id:"in",i18n:{…}},{id:"pt",i18n:{…}},{id:"vi",i18n:{…}}]' var='i18n'>
  <b:with value='data:i18n first (v => v.id == data:blog.locale.language)' var='i'>
    <b:with value='data:i.i18n' var='i18n'>

      …

    </b:with>
  </b:with>
</b:with>

7 Komentar

Nashrullah Ali Fauzi

Sayangnya, nilai dari <data:post.body/> tidak lantas berubah menjadi bahasa selain bahasa yang kita input, misalnya bahasa Inggris, ya, Mas?

Taufik Nurrohman

Kalau masalah itu sudah umum mas. Bukan cuma di Blogger saja.

Iccha Ahyun Iswari

Saya punya dua tanya:

Pertama, saya coba mau panggil data:i18n.id kok tidak bisa ya Mas?

Kedua, misalnya value id ini saya isi boolean, gimanakan implementasinya? Seperti jika kondisi data:view.isHomepage adalah true maka tampilkan value i18n.comments dan jika kondisi data:view.isPost adalah true maka tampilkan value i18n.comment?

Taufik Nurrohman

Karena variabel i18n sudah direferensikan ke data:i.i18n, bukan data:i, jadi pas kamu manggil variabel i18n maka yang kamu akses itu objek data:i.i18n. Pada kasusmu yang diminta harusnya data:i.id.

Untuk membuat boolean sama persis dengan konsep kondisional bahasa di atas, cuma bedanya ini pakai <b:if> yang lebih sederhana:

<b:if cond='data:view.isSingleItem'>
  <data:i18n.comment/>
<b:else/>
  <data:i18n.comments/>
</b:if>

Hussein

Topik yang bagus, saya sudah lama mencari

disamping intinya

Apakah mungkin menambahkan -rw ke gambar secara otomatis sehingga ditampilkan dalam format webp tanpa perlu JavaScript?

Mastewe com

Untuk yang di Template, bagaimana ya mas, di head. Karena berbeda terlihat andai di lihat di GSC

Komentar telah ditutup.