Parser JSON untuk Blogger · Posting dan Halaman Statis
Berikut adalah generalisasi fungsi untuk mengubah data JSON posting dan halaman statis Blogger menjadi markup HTML sesuai dengan keinginan. Di sini Saya membagi fungsinya menjadi dua macam yaitu generatePostsData
untuk menangani posting dan halaman dalam bentuk daftar dan generatePostData
untuk menangani posting dan halaman dalam bentuk tunggal:
Bentuk Daftar
function generatePostsData(json) {
// Poor configuration settings, develop them yourself!
var config = {
containerID: 'result-container', // Container ID to show the generated data
avatarSize: 50, // Default avatar size
noThumbnail: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAQMAAABvIyEEAAAABGdBTUEAALGPC/xhBQAAAAZQTFRFOjo6JycnNkxyjQAAADZJREFUKM9j+A8DDFRnNTCAACP9WewPGNgfkMmiwN7GH0CGfCPdWZT5V/7/DwZyWeSHFa1SHQDDGF2E0US40gAAAABJRU5ErkJggg==',
text: {
anon: 'Anonymous',
untagged: 'Untagged',
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
}
};
var html = "",
item = "",
w = window,
d = document,
feed = json.feed,
container = d.getElementById(config.containerID),
postTotal = +feed.openSearch$totalResults.$t, // The post/page feeds' total (all)
postStartIndex = +feed.openSearch$startIndex.$t, // The post/page feeds' start index
postPerPage = +feed.openSearch$itemsPerPage.$t, // The post/page feeds' max results per page or per feed request
blogID = /\:blog-?(\d+)(\.|$)/.exec(feed.id.$t) ? /\:blog-?(\d+)(\.|$)/.exec(feed.id.$t)[1] : false, // The blog ID
blogTitle = feed.title.$t, // The post/page feeds' title
blogTags = false, // The available post/page tags (all)
blogSubTitle = feed.subtitle.$t, // The post/page feeds' subtitle
blogAuthorName = feed.author[0].name ? feed.author[0].name.$t : config.text.anon, // The blog/post author name
blogAuthorAvatar = feed.author[0].gd$image.src.replace(/\/s\d+(\-c)?\//, '/s' + config.avatarSize + '-c/'), // The blog/post author profile avatar URL
blogGeneratorName = feed.generator.$t, // The blog generator name (Blogger)
blogGeneratorURL = feed.generator.uri; // The blog generator URL (http://www.blogger.com)
// Remove the leading `http://` or `https://` in blog/post author profile avatar URL
// blogAuthorAvatar = blogAuthorAvatar.replace(/^https?\:/, "");
// No container found
if (!container) {
alert('Container not found.');
return;
}
// Getting the blog tags
if (feed.category && feed.category.length) {
blogTags = [];
for (var h = 0, hen = feed.category.length; h < hen; ++h) {
blogTags.push(feed.category[h].term);
}
// Sort the blog tags alphabetically
blogTags = blogTags.sort();
}
// No posts/pages yet
if (!feed.entry || feed.entry.length === 0) {
container.innerHTML = '<p>No posts/pages yet.</p>';
return;
}
// Building the markup ...
html += '<h1>' + blogTitle + '</h1>';
html += '<h2>' + blogSubTitle + '</h2>';
html += '<p><b>Blog ID:</b> ' + blogID + '</p>';
html += '<p><b>Blog Tags:</b> ' + (blogTags !== false ? blogTags.join(', ') : config.text.untagged) + '</p>';
html += '<p><b>Blog Author Name:</b> ' + blogAuthorName + '</p>';
html += '<p><b>Blog Author Avatar URL:</b> ' + blogAuthorAvatar + '</p>';
html += '<p><b>Total Posts:</b> ' + postTotal + '</p>';
html += '<p><b>Posts Per Page:</b> ' + postPerPage + '</p>';
html += '<p><b>Posts Start Index:</b> ' + postStartIndex + '</p>';
html += '<hr>';
html += '<ol>';
var posts = feed.entry;
for (var i = 0, ien = posts.length; i < ien; ++i) {
var post = posts[i], // A single post/page object
postID = post.id.$t, // The post/page ID
postPublish = post.published.$t, // The post/page publishing time in ISO format
postUpdate = post.updated.$t, // The post/page updating time in ISO format
postDate = postPublish, // The post/page publishing time in human-readable format
postURL = false, // The post/page URL
postTags = false, // The post/page tags
postCommentTotal = post.thr$total ? +post.thr$total.$t : 0, // The post/page comments total
postCommentFeedURL = false, // The post/page comments feed URL
postThumbnail = post.media$thumbnail ? post.media$thumbnail.url : config.noThumbnail, // The post/page thumbnail
postAuthorName = post.author[0].name ? post.author[0].name.$t : config.text.anon, // The post/page author name
postAuthorURL = post.author[0].uri ? post.author[0].uri.$t : false, // The post/page author profile URL
postAuthorAvatar = post.author[0].gd$image.src.replace(/\/s\d+(\-c)?\//, '/s' + config.avatarSize + '-c/'), // The post/page author profile avatar URL
postTitle = post.title.$t, // The post/page title
postContent = post.content ? post.content.$t : post.summary.$t.replace(/<br *\/?>|[\s]+/gi, ' ').replace(/<.*?>|[<>]/g, ""), // The post/page content
postEditURL = false; // The post/page edit URL
// Generate human-readable post/page date format
var date = postDate.split('T')[0].split('-');
postDate = date[2] + ' ' + config.text.monthNames[(+date[1]) - 1] + ' ' + date[0];
// Remove the leading `http://` or `https://` in post/page thumbnail URL
// postThumbnail = postThumbnail.replace(/^https?\:/, "");
// Remove the leading `http://` or `https://` in post/page author profile avatar URL
// postAuthorAvatar = postAuthorAvatar.replace(/^https?\:/, "");
for (var j = 0, jen = post.link.length; j < jen; ++j) {
item = post.link[j];
if (item.rel == 'self') {
// Getting the original post/page ID
postID = item.href.split('/').pop();
// Getting the post/page edit URL
postEditURL = item.href.replace(/\/feeds\/(\d+)\/(post|page)s?\/(default|summary)\/(\d+)/, '/$2-edit.g?blogID=$1&$2ID=$4');
}
// Getting the post/page URL
if (item.rel == 'alternate') {
postURL = item.href;
}
// Getting the post/page comment feed URL
if (item.rel == 'replies' && item.type == 'application/atom+xml') {
postCommentFeedURL = item.href;
}
}
// Trying to get the external image URL from post/page content
if (post.content && postThumbnail == config.noThumbnail) {
var image = /<img +(.*?)src=(['"])([^'"]+?)(['"])(.*?) *\/?>/i.exec(post.content.$t);
postThumbnail = image && image[3] ? image[3] : config.noThumbnail;
}
// Getting the post/page tags
if (post.category && post.category.length) {
postTags = [];
for (var k = 0, ken = post.category.length; k < ken; ++k) {
postTags.push(post.category[k].term);
}
// Sort the post/page tags alphabetically
postTags = postTags.sort();
}
// Building the markup ...
html += '<li>';
html += '<p><b>ID:</b> ' + postID + '</p>';
html += '<p><b>Publish:</b> ' + postPublish + '</p>';
html += '<p><b>Update:</b> ' + postUpdate + '</p>';
html += '<p><b>Date:</b> ' + postDate + '</p>';
html += '<p><b>URL:</b> ' + postURL + '</p>';
html += '<p><b>Tags:</b> ' + (postTags !== false ? postTags.join(', ') : config.text.untagged) + '</p>';
html += '<p><b>Comment Total:</b> ' + postCommentTotal + '</p>';
html += '<p><b>Comment Feed URL:</b> ' + postCommentFeedURL + '</p>';
html += '<p><b>Thumbnail:</b> ' + postThumbnail + '</p>';
html += '<p><b>Author:</b> ' + postAuthorName + '</p>';
html += postAuthorURL !== false ? '<p><b>Author URL:</b> ' + postAuthorURL + '</p>' : "";
html += '<p><b>Author Avatar URL:</b> ' + postAuthorAvatar + '</p>';
html += '<p><b>Edit URL:</b> ' + postEditURL + '</p>';
html += '<p><b>Title:</b> ' + postTitle + '</p>';
html += '<p><b>Content:</b></p>';
html += '<div>' + postContent + '</div>';
html += '</li>';
}
// Building the markup ...
html += '</ol>';
// Show the generated data to the container ...
container.innerHTML = html;
}
Penggunaan
Urutannya dimulai dari penulisan HTML untuk menampung data yang akan digenerasikan oleh fungsi di atas, dilanjutkan dengan memasukkan fungsi di atas ke dalam tag <script>
, lalu memanggil data JSON dengan menggunakan nilai parameter URL callback
berupa generatePostsData
, sesuai dengan nama fungsi di atas:
<div id="result-container">Loading…</div>
<script>
function generatePostsData(json) { … }
</script>
<script src="//nama_blog.blogspot.com/feeds/posts/default?alt=json-in-script&orderby=published&callback=generatePostsData"></script>
Bentuk Tunggal
function generatePostData(json) {
// Poor configuration settings, develop them yourself!
var config = {
containerID: 'result-container', // Container ID to show the generated data
avatarSize: 50, // Default avatar size
noThumbnail: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAQMAAABvIyEEAAAABGdBTUEAALGPC/xhBQAAAAZQTFRFOjo6JycnNkxyjQAAADZJREFUKM9j+A8DDFRnNTCAACP9WewPGNgfkMmiwN7GH0CGfCPdWZT5V/7/DwZyWeSHFa1SHQDDGF2E0US40gAAAABJRU5ErkJggg==',
text: {
anon: 'Anonymous',
untagged: 'Untagged',
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
}
};
var html = "",
item = "",
w = window,
d = document,
container = d.getElementById(config.containerID);
// No container found
if (!container) {
alert('Container not found.');
return;
}
var post = json.entry, // The post/page object
postID = post.id.$t, // The post/page ID
postPublish = post.published.$t, // The post/page publishing time in ISO format
postUpdate = post.updated.$t, // The post/page updating time in ISO format
postDate = postPublish, // The post/page publishing time in human-readable format
postURL = false, // The post/page URL
postTags = false, // The post/page tags
postCommentTotal = post.thr$total ? +post.thr$total.$t : 0, // The post/page comments total
postCommentFeedURL = false, // The post/page comments feed URL
postThumbnail = post.media$thumbnail ? post.media$thumbnail.url : config.noThumbnail, // The post/page thumbnail
postAuthorName = post.author[0].name ? post.author[0].name.$t : config.text.anon, // The post/page author name
postAuthorURL = post.author[0].uri ? post.author[0].uri.$t : false, // The post/page author profile URL
postAuthorAvatar = post.author[0].gd$image.src.replace(/\/s\d+(\-c)?\//, '/s' + config.avatarSize + '-c/'), // The post/page author profile avatar URL
postTitle = post.title.$t, // The post/page title
postContent = post.content ? post.content.$t : post.summary.$t.replace(/<br *\/?>|[\s]+/gi, ' ').replace(/<.*?>|[<>]/g, ""), // The post/page content
postEditURL = false; // The post/page edit URL
// Generate human-readable post/page date format
var date = postDate.split('T')[0].split('-');
postDate = date[2] + ' ' + config.text.monthNames[(+date[1]) - 1] + ' ' + date[0];
// Remove the leading `http://` or `https://` in post/page thumbnail URL
// postThumbnail = postThumbnail.replace(/^https?\:/, "");
// Remove the leading `http://` or `https://` in post/page author profile avatar URL
// postAuthorAvatar = postAuthorAvatar.replace(/^https?\:/, "");
for (var j = 0, jen = post.link.length; j < jen; ++j) {
item = post.link[j];
if (item.rel == 'self') {
// Getting the original post/page ID
postID = item.href.split('/').pop();
// Getting the post/page edit URL
postEditURL = item.href.replace(/\/feeds\/(\d+)\/(post|page)s?\/(default|summary)\/(\d+)/, '/$2-edit.g?blogID=$1&$2ID=$4');
}
// Getting the post/page URL
if (item.rel == 'alternate') {
postURL = item.href;
}
// Getting the post/page comment feed URL
if (item.rel == 'replies' && item.type == 'application/atom+xml') {
postCommentFeedURL = item.href;
}
}
// Trying to get the external image URL from post/page content
if (post.content && postThumbnail == config.noThumbnail) {
var image = /<img +(.*?)src=(['"])([^'"]+?)(['"])(.*?) *\/?>/i.exec(post.content.$t);
postThumbnail = image && image[3] ? image[3] : config.noThumbnail;
}
// Getting the post/page tags
if (post.category && post.category.length) {
postTags = [];
for (var k = 0, ken = post.category.length; k < ken; ++k) {
postTags.push(post.category[k].term);
}
// Sort the post/page tags alphabetically
postTags = postTags.sort();
}
// Building the markup ...
html += '<li>';
html += '<p><b>ID:</b> ' + postID + '</p>';
html += '<p><b>Publish:</b> ' + postPublish + '</p>';
html += '<p><b>Update:</b> ' + postUpdate + '</p>';
html += '<p><b>Date:</b> ' + postDate + '</p>';
html += '<p><b>URL:</b> ' + postURL + '</p>';
html += '<p><b>Tags:</b> ' + (postTags !== false ? postTags.join(', ') : config.text.untagged) + '</p>';
html += '<p><b>Comment Total:</b> ' + postCommentTotal + '</p>';
html += '<p><b>Comment Feed URL:</b> ' + postCommentFeedURL + '</p>';
html += '<p><b>Thumbnail:</b> ' + postThumbnail + '</p>';
html += '<p><b>Author:</b> ' + postAuthorName + '</p>';
html += postAuthorURL !== false ? '<p><b>Author URL:</b> ' + postAuthorURL + '</p>' : "";
html += '<p><b>Author Avatar URL:</b> ' + postAuthorAvatar + '</p>';
html += '<p><b>Edit URL:</b> ' + postEditURL + '</p>';
html += '<p><b>Title:</b> ' + postTitle + '</p>';
html += '<p><b>Content:</b></p>';
html += '<div>' + postContent + '</div>';
html += '</li>';
// Building the markup ...
html += '</ol>';
// Show the generated data to the container ...
container.innerHTML = html;
}
Penggunaan
Sisipkan ID posting/halaman statis setelah path default
atau summary
:
<div id="result-container">Loading…</div>
<script>
function generatePostData(json) { … }
</script>
<script src="//nama_blog.blogspot.com/feeds/posts/default/1962799387619194999?alt=json-in-script&callback=generatePostData"></script>
Ekstra
Halaman Statis
Data halaman statis dapat dipanggil dengan menggunakan format URL seperti ini:
http://nama_blog.blogspot.com/feeds/pages/default?alt=json-in-script&orderby=published&callback=generatePostsData
http://nama_blog.blogspot.com/feeds/pages/default?alt=json-in-script&callback=generatePostData
Mode Ringkas
Mode ringkas dapat dipanggil dengan menggunakan format URL seperti ini:
http://nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&orderby=published&callback=generatePostsData
http://nama_blog.blogspot.com/feeds/pages/summary?alt=json-in-script&orderby=published&callback=generatePostsData
http://nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&callback=generatePostData
http://nama_blog.blogspot.com/feeds/pages/summary?alt=json-in-script&callback=generatePostData
40 Komentar
Michael
Itu kode apasih, masih kagak ngerti.
Giri Diwa Adam
Kode JSON Gan untuk Halaman Statis Blogger
Kang Kapuk
Pesen JSon buat Popular-Post with thumbnail
Taufik Nurrohman
Data statistiknya yang Saya tidak tahu pak letaknya ada di mana :\ Kalau datanya ada di dalam JSON mungkin Saya bisa buat. Dan kalaupun bisa dibuat pasti performanya akan tetap lebih jelek jika dibandingkan dengan widget posting populer yang asli. Karena untuk mendapatkan 7 buah posting yang paling populer misalnya, Saya harus memuat semua posting terlebih dahulu untuk mendapatkan data statistik masing-masing posting, agar kemudian bisa Saya ambil tujuh buah posting saja yang memiliki data statistik kunjungan paling besar.
Kecuali kalau parameter JSON seperti
orderby=popular
telah disediakan oleh Blogger. Atau kalau Bapak memakai API Blogger V3 seperti yang dinyatakan di halaman ini → PageViewsAdmin
nah, mas taufik, populer post dari widget bawaan blogger kan cuman 10, bisa gak kalau misalnya mau dibuat jadi 20 artikel mas?
Taufik Nurrohman
Sayangnya nggak bisa. Saya malah mikirnya begini: makin banyak posting populer yang diambil, maka makin tidak populer–lah mereka, karena semuanya toh sama-sama populer.
Unknown
This is very cool post for development in Blogger widgets. Thanks for the hard work and cool blog :-bd
Unknown
mantabss,,, dewo nih :v
Unknown
mantap ni... :-bd
IRIL SAGITA
Kak, aku sudah pakek parser bentuk tunggal tersebut diatas, dan sukses di blog aku, yang aku tanyakan : jika di dalam posting tersebut ada code java script-nya apakah memang tidak bisa berfungsi java script yang terdapat di dalamnya, suatu contoh saat ini kendala yang saya alami di daftar isi blog SAGITA COM, dan agar java script di dalam posting tersebut bisa berfungsi bagaimana solusinya ?
Taufik Nurrohman
Iya, biasanya tag
<script>
yang masuk ke dalam tag<script>
akan rusak. Selain itu lebih baik jangan memakai ini untuk memuat konten posting yang sungguhan. Takutnya mesin pencari nanti pada nggak mau mengindeks postinganmu.IRIL SAGITA
oww jd gitu ya kak, makasih sarannya, mudah-mudahan tetap bisa diindeks oleh google.
Anonim
Mas bikin scroll top seperti web DTE ini memakai perintah query seperti apa ya?
Bisa kasih tau gak tahap-tahapannya
Unknown
bantu jawab pertanyaan ah :D
itu pake jquery easing, nama efeknya kalo nggak salah
"easeOutQuart"
Taufik Nurrohman
→ /2013/06/cross-browser-scroll-to-top-animation.html
→ /2012/05/memodifikasi-tombol-back-to-top-menjadi.html
Anonim
Mas gimana caranya kita cuma ngambil 1 kategori aja dan cara mengambil url dari katregori tsb ?
Bisa kasih tau gak tahap-tahapannya
Taufik Nurrohman
Data tag posting Saya simpan di variabel
postTags
. Kalau mau mengambil satu saja tinggal dipanggil saja data tag yang berada pada indeks pertama:Unknown
maaf mas, OOT sedikit, boleh tau cara buat seperti gambar berikut ?
David Prasetyo
Thanks om lengkap !
Wahyu
Jujur, saya banyak belajar dari blog ini. Semenjak mengenal dan kagum dengan blog ini, saya langsung mencari tahu sosok di balik blog ini. Saya juga mencari tahu sejarah/awal-mula blog ini. Ternyata blog ini, lebih tepatnya kang Taufik, merupakan master blogger terdahulu.
Hampir setiap master blogger sekarang ini mendapatkan script2 untuk dibagikan kembali dari blog ini. Dan hampir setiap template yang saya jumpai tidak lepas dari fitur buatan kang Taufik, seperti related post, dll.
Dari blog ini pula saya mengenal Blogaziner Damar Zaky, Zhinto.blogspot.com, kang Agus o-om.com,dll. Terima kasih banyak kang Taufik, yang telah sangat menginspirasi saya. -Pemilik wahyupratama(dot)com
Taufik Nurrohman
Yup, sama-sama. Sekedar mengeluarkan uneg-uneg saja dari dalam pikiran supaya bisa menjadi sesuatu. Baguslah kalau karya-karya Saya akhirnya bisa dipakai. Maaf jarang blogwalking, untuk semuanya juga yang sedang membaca komentar ini, soalnya Saya dasarnya memang bukan blogger, cuma suka nulis dan membuat sesuatu saja :)
Unknown
pak, request yang "Bentuk Daftar" ditambahi "infinite scroll". :yaya:
IRIL SAGITA
Kalau aku lebih suka versi mentahnya seperti ini kak :
ErDev
Terimakasih banyak, Artikelnya sangat membantu :)
Sopala Multapa
Sopala Multapa
dan saya memanggilnya dgn
url: "/feeds/posts/default/-/" + t + "?alt=json-in-script&max-results=4",
Taufik Nurrohman
Kapan-kapan saja tak coba buatkan fungsi untuk memotong HTML posting.
Sopala Multapa
Gak ada solusi y mas ???
Saeful Rahman
Bagaimana menampilkan penulis artikel yang bukan admin/author dari blog tsb ? Karena kode tsb hanya berfungsi kalo penulis artikel merupakan author/admin, jika bukan maka akan ditampilkan sebagai anonymous
postAuthorName = post.author[0].name ? post.author[0].name.$t : config.text.anon, // The post/page author name
postAuthorURL = post.author[0].uri ? post.author[0].uri.$t : false, // The post/page author profile URL
postAuthorAvatar = post.author[0].gd$image.src.replace(/\/s\d+(\-c)?\//, '/s' + config.avatarSize + '-c/'), // The post/page author profile avatar URL
Taufik Nurrohman
Sudah dicoba mas? Hasilnya bagaimana?
Saeful Rahman
Sudah dicoba dan hasilnya dianggap Unknown, ketika penulis yang sudah pernah mem-publish artikelnya bukan lagi admin/author di blog tsb. Apakah terjadi perubahan semenjak Google plus ditutup ?
Sebelumnya saya mencoba memanfaatkan json ini untuk membuat kontributor penulis dengan menghitung total jumlah artikel dan komentar yang dipublikasikan dalam suatu blog, seperti diskusi pada komentar disini. Contoh penerapannya bisa di cek blog Saya mas.
https://diakali.blogspot.com/2019/07/testing-penulis-diluar-adminauthor-blog.html
Taufik Nurrohman
Berarti nilai bidang author postingan sifatnya dinamis dan tidak tersimpan di basis data secara permanen. Mungkin yang tersimpan hanya ID profilnya saja, bukan teks nama penulisnya, dengan harapan kalau penulis mengganti namanya di profil Blogger atau Google maka nama penulis di postingan akan mengikuti secara otomatis. Karena pada prinsipnya nama bisa diubah, tapi ID tidak.
Nah, kalau akses penulis di blog pusat sudah dihapus atau dibatalkan, berarti blog pusat yang dulu memiliki akses untuk memanggil data nama penulis melalui ID profil yang tersimpan sekarang sudah tidak bisa lagi.
Saeful Rahman
Yah, ternyata tidak bisa dilakukan untuk saat ini. Berharap blogger melakukan update dan menambah fitur2 baru agar lebih segar :D
Kimimaru
mas cara resize thumbnailnya gimana, kok hasilnya ukuran /s72-c/ ?
Taufik Nurrohman
Itu memang sudah standar ukuran keluku. Kalau mau ubah bisa pakai ekspresi reguler:
Kimimaru
kalo kode asli yg ini kayak gimana mas //i.exec(post.content.$t);
itu bisa di pake buat getelement gak?
Taufik Nurrohman
Mungkin seperti ini:
Kimimaru
selain monthnames, list label bisa dikustom juga gak mas? misalnya saya hanya mau nampilkan label blogger sama tips & trick saja, selain label itu gak tampil.
Taufik Nurrohman
Kimimaru
tambahinnya di bagian mana mas?