最新留言欄(不含網主回應)
真的很多很多網友想設定「最近的回應」欄啊,豆丁沒有使用這個功能,所以一心想偷懶不寫,但是需求太大,最後還是於心不忍^^""
好的~ 豆丁今天決定教大家設定「最新留言」欄,大家還可以選擇顯示留言數目,而且,應大家要求,不顯示網主自己的留言回應。(豆丁先把主題樂園文放在一邊@@,日後發文時,大家記得支持啊!)
大家可以先到以下的測試版測試效果:
http://dauhahaha.blogspot.com/
參考資料:Help Blogger
http://helplogger.blogspot.com/2013/03/recent-comments-widget-with-hide-author.html
由於豆丁是參考Help Blogger的程式碼,再作少量修改,所以,想保留Help Blogger的網址。因此,大家可以看到"Recent Comments Widget"字樣,並有連結:
步驟1)請到「版面配置」,在心水位置按「新增小工具」。
步驟2)選擇「HTML/JavaScript」
步驟3)在標題輸入欄名(豆丁選用了「最新留言」作為欄名)
步驟4)複製以下的程式碼,貼到處理文字的軟件上(建議:Word Document),按豆丁括號內的指示修改程式碼。修改程式碼後,把所有括號文字刪除。
*顏色、線條款式的程式碼?請參考《Blogspot教學:為文章加框線》。
覺得困難的話,直接使用豆丁的程式碼,然後看「步驟5」吧!但記得把所有括號文字刪除。
========== 程式碼開始 ==========
<style type="text/css">
.rc{margin-left: 0px; (<-- 這是「最新留言欄」的左空白大小)
margin-right: 0px; (<--這是右空白大小) padding-top: 5px; padding-bottom: 5px; (<--這是留言顯示間的距離)
border-bottom: 1px dotted;} (<--留言顯示分隔線的粗幼與款式)
.rc-ico img {display:none; }
.rc-header{}
.rc-header a{color: #1745FC;} (<--訪客名稱的顏色)
.rc-body{font-style: italic; font-size: 12px; (<--留言內容的字款與大小)
color: #B78A00; (<-- 留言內容的顏色)
border: 0px dotted #FDD017;} (<--留言內容加框)
#rcw-cr {font-family: Arial,Tahoma;font-size:7px;
padding-top:5px;display:block;} (<-- "Recent Comments Widget"字樣的字款與大小)
</style>
<script type="text/javascript">
var numRecentComments = 5; (<--留言顯示數目)
var maxCommentChars = 50; (<-- 每個留言顯示的長度限制)
var trueAvatars = true;
var urlMyAvatar = '';
var urlMyProfile = ''; var cropAvatar = true;
var sizeAvatar = 50;
var urlAnoAvatar = 'http://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&s=' + sizeAvatar;
var txtMore = '';
var txtWrote = '[user] commented on [title]';
var txtAnonymous = '';
var maxResultsComments = "";
var numPerPost = 2;
var maxPostTitleChars = 50;
var getTitles = true;
var maxResultsPosts = "";
var txtTooltip = 'Date: [date MM-dd-yyyy hh:mm]';
var urlToTitle = {};
function replaceVars(text, user, title, date) {
text = text.replace('[user]', user);
text = text.replace('[date]', date.toLocaleDateString());
text = text.replace('[datetime]', date.toLocaleString());
text = text.replace('[time]', date.toLocaleTimeString());
text = text.replace('[title]', title.replace(/\"/g,'"'));
var i = text.indexOf("[date ");
if(i > -1) {
var format = /\[date\s+(.+?)\]/.exec(text)[1]; if(format != '') {
var txtDate = format.replace(/yyyy/i, date.getFullYear());
txtDate = txtDate.replace(/yy/i, date.getFullYear().toString().slice(-2));
txtDate = txtDate.replace("MM", String("0"+(date.getMonth()+1)).slice(-2));
txtDate = txtDate.replace("mm", String("0"+date.getMinutes()).slice(-2));
txtDate = txtDate.replace("ss", String("0"+date.getSeconds()).slice(-2));
txtDate = txtDate.replace("dd", String("0"+date.getDate()).slice(-2));
//or: txtDate = txtDate.replace("dd", date.getDate());
txtDate = txtDate.replace("hh", String("0"+date.getHours()).slice(-2));
//or: txtDate = txtDate.replace("hh", date.getHours());
text = text.replace(/\[date\s+(.+?)\]/, txtDate)
}
}
return text;
}
if(urlMyProfile == "") {
var elements = document.getElementsByTagName("*");
var expr = /(^| )profile-link( |$)/;
for(var i=0 ; i<elements.length ; i++) if(expr.test(elements[i].className)) {
urlMyProfile = elements[i].href;
break;
}
}
function getPostUrlsForComments(json) {
for(var i = 0 ; i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i];
for (var k = 0; k < entry.link.length; k++ ) {
if (entry.link[k].rel == 'alternate') {
href = entry.link[k].href;
break;
}
}
urlToTitle[href] = entry.title.$t;
}
}
function showRecentComments(json) {
var postHandled = {};
var j = 0;
if(numPerPost) {
while(numPerPost < numRecentComments) {
for(var i = 0 ; i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i]; if(entry.author[0].name.$t=="豆丁") continue;
if(entry["thr$in-reply-to"]) { if(!postHandled[entry["thr$in-reply-to"].href])
postHandled[entry["thr$in-reply-to"].href] = 1;
else
postHandled[entry["thr$in-reply-to"].href]++;
if(postHandled[entry["thr$in-reply-to"].href] <= numPerPost)
j++;
}
}
if(j >= numRecentComments)
break;
numPerPost++;
j = 0;
postHandled = {};
}
if(numRecentComments == numPerPost)
numPerPost = 0;
}
postHandled = {};
j = 0;
for(var i = 0 ; j < numRecentComments && i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i]; if(entry.author[0].name.$t=="豆丁") continue;
if(numPerPost && postHandled[entry["thr$in-reply-to"].href] && postHandled[entry["thr$in-reply-to"].href] >= numPerPost)
continue;
if(entry["thr$in-reply-to"]) { if(!postHandled[entry["thr$in-reply-to"].href])
postHandled[entry["thr$in-reply-to"].href] = 1;
else
postHandled[entry["thr$in-reply-to"].href]++;
j++;
var href='';
for (var k = 0; k < entry.link.length; k++ ) {
if (entry.link[k].rel == 'alternate') {
href = entry.link[k].href;
break;
}
}
if(href=='') {j--; continue; }
var hrefPost = href.split("?")[0];
var comment = "";
if("content" in entry) comment = entry.content.$t;
else comment = entry.summary.$t;
comment = comment.replace(/<br[^>]*>/ig, " ");
comment = comment.replace(/<\S[^>]*>/g, "");
var postTitle="-";
if(urlToTitle[hrefPost]) postTitle=urlToTitle[hrefPost];
else {
if(hrefPost.match(/\/([^/]*)\.html/)) postTitle = hrefPost.match(/\/([^/]*)\.html/)[1].replace(/_\d{2}$/, ""); postTitle = postTitle.replace(/-/g," ");
postTitle = postTitle[0].toUpperCase() + postTitle.slice(1);
}
if(maxPostTitleChars && postTitle.length > maxPostTitleChars) {
postTitle = postTitle.substring(0, maxPostTitleChars);
var indexBreak = postTitle.lastIndexOf(" ");
postTitle = postTitle.substring(0, indexBreak) + "...";
}
var authorName = entry.author[0].name.$t;
var authorUri = "";
if(entry.author[0].uri && entry.author[0].uri.$t != "")
authorUri = entry.author[0].uri.$t;
var avaimg = urlAnoAvatar;
var bloggerprofile = "http://www.blogger.com/profile/";
if(trueAvatars && entry.author[0].gd$image && entry.author[0].gd$image.src && authorUri.substr(0,bloggerprofile.length) == bloggerprofile)
avaimg = entry.author[0].gd$image.src;
else {
var parseurl = document.createElement('a');
if(authorUri != "") {
parseurl.href = authorUri; avaimg = 'http://www.google.com/s2/favicons?domain=' + parseurl.hostname;
}
}
if(urlMyProfile != "" && authorUri == urlMyProfile && urlMyAvatar != "")
avaimg = urlMyAvatar;
if(avaimg == "http://img2.blogblog.com/img/b16-rounded.gif" && urlNoAvatar != "")
avaimg = urlNoAvatar;
var newsize="s"+sizeAvatar;
avaimg = avaimg.replace(/\/s\d\d+-c\//, "/"+newsize+"-c/");
if(cropAvatar) newsize+="-c";
avaimg = avaimg.replace(/\/s\d\d+(-c){0,1}\//, "/"+newsize+"/");
if(authorName == 'Anonymous' && txtAnonymous != '' && avaimg == urlAnoAvatar)
authorName = txtAnonymous;
var imgcode = '<img height="'+sizeAvatar+'" width="'+sizeAvatar+'" title="'+authorName+'" src="'+avaimg+'" />';
if (authorUri!="") imgcode = '<a href="'+authorUri+'">'+imgcode+'</a>';
var clsAdmin = "";
if(urlMyProfile != "" && authorUri == urlMyProfile)
clsAdmin = " rc-admin";
var datePart = entry.published.$t.match(/\d+/g); // assume ISO 8601 var cmtDate = new Date(datePart[0],datePart[1]-1,datePart[2],datePart[3],datePart[4],datePart[5]);
var txtHeader = txtWrote;
if(txtWrote.indexOf('[')==-1)
txtHeader = authorName + ' ' + txtWrote;
else
txtHeader = replaceVars(txtHeader, authorName, postTitle, cmtDate);
var tooltip = replaceVars(txtTooltip, authorName, postTitle, cmtDate);
if(!/#/.test(href)) href += "#comments";
document.write('<div title="'+tooltip+'" class="rc'+clsAdmin+'">');
document.write('<div title="'+tooltip+'" class="rc-header'+clsAdmin+'"><div title="'+tooltip+'" class="rc-ico'+clsAdmin+'">'+imgcode+'</div><a title="'+tooltip+'" href="' + href + '">' + txtHeader + ' </a></div>');
if(comment.length < maxCommentChars)
document.write('<div title="'+tooltip+'" class="rc-body'+clsAdmin+'">' + comment + '</div>');
else {
comment = comment.substring(0, maxCommentChars);
var indexBreak = comment.lastIndexOf(" ");
comment = comment.substring(0, indexBreak); document.write('<div title="'+tooltip+'" class="rc-body'+clsAdmin+'">' + comment + '...</div>');
if(txtMore != "") {
var moretext = replaceVars(txtMore, authorName, postTitle, cmtDate);
document.write('<div title="'+tooltip+'" class="rc-footer'+clsAdmin+'"><a title="'+tooltip+'" href="' + href + '">' + moretext + '</a></div>');
}
}
document.write('<div style="clear:both;"></div></div>');
}
}
}
if(getTitles)
document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/posts/summary?redirect=false'+maxResultsPosts+'&alt=json-in-script&callback=getPostUrlsForComments"></'+'script>');
document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/comments/default?redirect=false'+maxResultsComments+'&alt=json-in-script&callback=showRecentComments"></'+'script>');
</script>
<span id=rcw-cr><a href=http://helplogger.blogspot.ro/2013/03/recent-comments-widget-with-hide-author.html>Recent Comments Widget</a></span> (<--不想顯示"Recent Comments Widget"的話,可以刪除這個綠色部分。)
========== 程式碼結束 ==========
步驟5)把程式碼中的「豆丁」(共出現兩次)換成你的留言名稱。
步驟6)把程式碼貼到「內容」,按「儲存」。
成功了!恭喜恭喜~~~~~
喜歡豆丁的教學,記得"like"、"+1"或與朋友分享啊~
謝謝你的鼓勵^^~
網友的溫馨提示
網友劉比蒂又細心,又熱心!她留意到有些訪客留言後又刪除留言,但卻沒有按「永久刪除」,這樣,他們的名字會繼續顯示,並且列明留言被刪除。大家如果不想刪除留言後仍然留有大名,記得選擇「永久刪除」啊!(當然,網主亦可再「永久刪除」^^~)
>> 閱讀豆丁的其他《Blospot教學》?
>> 歡迎閱讀豆丁的其他專欄:
*《豆丁遊世界》
*《微故事@豆氏村》
*《簡單食譜》
*《嘰哩咕嚕》
好的~ 豆丁今天決定教大家設定「最新留言」欄,大家還可以選擇顯示留言數目,而且,應大家要求,不顯示網主自己的留言回應。(豆丁先把主題樂園文放在一邊@@,日後發文時,大家記得支持啊!)
大家可以先到以下的測試版測試效果:
http://dauhahaha.blogspot.com/
參考資料:Help Blogger
http://helplogger.blogspot.com/2013/03/recent-comments-widget-with-hide-author.html
由於豆丁是參考Help Blogger的程式碼,再作少量修改,所以,想保留Help Blogger的網址。因此,大家可以看到"Recent Comments Widget"字樣,並有連結:
步驟1)請到「版面配置」,在心水位置按「新增小工具」。
步驟2)選擇「HTML/JavaScript」
步驟3)在標題輸入欄名(豆丁選用了「最新留言」作為欄名)
步驟4)複製以下的程式碼,貼到處理文字的軟件上(建議:Word Document),按豆丁括號內的指示修改程式碼。修改程式碼後,把所有括號文字刪除。
*顏色、線條款式的程式碼?請參考《Blogspot教學:為文章加框線》。
覺得困難的話,直接使用豆丁的程式碼,然後看「步驟5」吧!但記得把所有括號文字刪除。
========== 程式碼開始 ==========
<style type="text/css">
.rc{margin-left: 0px; (<-- 這是「最新留言欄」的左空白大小)
margin-right: 0px; (<--這是右空白大小) padding-top: 5px; padding-bottom: 5px; (<--這是留言顯示間的距離)
border-bottom: 1px dotted;} (<--留言顯示分隔線的粗幼與款式)
.rc-ico img {display:none; }
.rc-header{}
.rc-header a{color: #1745FC;} (<--訪客名稱的顏色)
.rc-body{font-style: italic; font-size: 12px; (<--留言內容的字款與大小)
color: #B78A00; (<-- 留言內容的顏色)
border: 0px dotted #FDD017;} (<--留言內容加框)
#rcw-cr {font-family: Arial,Tahoma;font-size:7px;
padding-top:5px;display:block;} (<-- "Recent Comments Widget"字樣的字款與大小)
</style>
<script type="text/javascript">
var numRecentComments = 5; (<--留言顯示數目)
var maxCommentChars = 50; (<-- 每個留言顯示的長度限制)
var trueAvatars = true;
var urlMyAvatar = '';
var urlMyProfile = ''; var cropAvatar = true;
var sizeAvatar = 50;
var urlAnoAvatar = 'http://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&s=' + sizeAvatar;
var txtMore = '';
var txtWrote = '[user] commented on [title]';
var txtAnonymous = '';
var maxResultsComments = "";
var numPerPost = 2;
var maxPostTitleChars = 50;
var getTitles = true;
var maxResultsPosts = "";
var txtTooltip = 'Date: [date MM-dd-yyyy hh:mm]';
var urlToTitle = {};
function replaceVars(text, user, title, date) {
text = text.replace('[user]', user);
text = text.replace('[date]', date.toLocaleDateString());
text = text.replace('[datetime]', date.toLocaleString());
text = text.replace('[time]', date.toLocaleTimeString());
text = text.replace('[title]', title.replace(/\"/g,'"'));
var i = text.indexOf("[date ");
if(i > -1) {
var format = /\[date\s+(.+?)\]/.exec(text)[1]; if(format != '') {
var txtDate = format.replace(/yyyy/i, date.getFullYear());
txtDate = txtDate.replace(/yy/i, date.getFullYear().toString().slice(-2));
txtDate = txtDate.replace("MM", String("0"+(date.getMonth()+1)).slice(-2));
txtDate = txtDate.replace("mm", String("0"+date.getMinutes()).slice(-2));
txtDate = txtDate.replace("ss", String("0"+date.getSeconds()).slice(-2));
txtDate = txtDate.replace("dd", String("0"+date.getDate()).slice(-2));
//or: txtDate = txtDate.replace("dd", date.getDate());
txtDate = txtDate.replace("hh", String("0"+date.getHours()).slice(-2));
//or: txtDate = txtDate.replace("hh", date.getHours());
text = text.replace(/\[date\s+(.+?)\]/, txtDate)
}
}
return text;
}
if(urlMyProfile == "") {
var elements = document.getElementsByTagName("*");
var expr = /(^| )profile-link( |$)/;
for(var i=0 ; i<elements.length ; i++) if(expr.test(elements[i].className)) {
urlMyProfile = elements[i].href;
break;
}
}
function getPostUrlsForComments(json) {
for(var i = 0 ; i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i];
for (var k = 0; k < entry.link.length; k++ ) {
if (entry.link[k].rel == 'alternate') {
href = entry.link[k].href;
break;
}
}
urlToTitle[href] = entry.title.$t;
}
}
function showRecentComments(json) {
var postHandled = {};
var j = 0;
if(numPerPost) {
while(numPerPost < numRecentComments) {
for(var i = 0 ; i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i]; if(entry.author[0].name.$t=="豆丁") continue;
if(entry["thr$in-reply-to"]) { if(!postHandled[entry["thr$in-reply-to"].href])
postHandled[entry["thr$in-reply-to"].href] = 1;
else
postHandled[entry["thr$in-reply-to"].href]++;
if(postHandled[entry["thr$in-reply-to"].href] <= numPerPost)
j++;
}
}
if(j >= numRecentComments)
break;
numPerPost++;
j = 0;
postHandled = {};
}
if(numRecentComments == numPerPost)
numPerPost = 0;
}
postHandled = {};
j = 0;
for(var i = 0 ; j < numRecentComments && i < json.feed.entry.length ; i++ ) {
var entry = json.feed.entry[i]; if(entry.author[0].name.$t=="豆丁") continue;
if(numPerPost && postHandled[entry["thr$in-reply-to"].href] && postHandled[entry["thr$in-reply-to"].href] >= numPerPost)
continue;
if(entry["thr$in-reply-to"]) { if(!postHandled[entry["thr$in-reply-to"].href])
postHandled[entry["thr$in-reply-to"].href] = 1;
else
postHandled[entry["thr$in-reply-to"].href]++;
j++;
var href='';
for (var k = 0; k < entry.link.length; k++ ) {
if (entry.link[k].rel == 'alternate') {
href = entry.link[k].href;
break;
}
}
if(href=='') {j--; continue; }
var hrefPost = href.split("?")[0];
var comment = "";
if("content" in entry) comment = entry.content.$t;
else comment = entry.summary.$t;
comment = comment.replace(/<br[^>]*>/ig, " ");
comment = comment.replace(/<\S[^>]*>/g, "");
var postTitle="-";
if(urlToTitle[hrefPost]) postTitle=urlToTitle[hrefPost];
else {
if(hrefPost.match(/\/([^/]*)\.html/)) postTitle = hrefPost.match(/\/([^/]*)\.html/)[1].replace(/_\d{2}$/, ""); postTitle = postTitle.replace(/-/g," ");
postTitle = postTitle[0].toUpperCase() + postTitle.slice(1);
}
if(maxPostTitleChars && postTitle.length > maxPostTitleChars) {
postTitle = postTitle.substring(0, maxPostTitleChars);
var indexBreak = postTitle.lastIndexOf(" ");
postTitle = postTitle.substring(0, indexBreak) + "...";
}
var authorName = entry.author[0].name.$t;
var authorUri = "";
if(entry.author[0].uri && entry.author[0].uri.$t != "")
authorUri = entry.author[0].uri.$t;
var avaimg = urlAnoAvatar;
var bloggerprofile = "http://www.blogger.com/profile/";
if(trueAvatars && entry.author[0].gd$image && entry.author[0].gd$image.src && authorUri.substr(0,bloggerprofile.length) == bloggerprofile)
avaimg = entry.author[0].gd$image.src;
else {
var parseurl = document.createElement('a');
if(authorUri != "") {
parseurl.href = authorUri; avaimg = 'http://www.google.com/s2/favicons?domain=' + parseurl.hostname;
}
}
if(urlMyProfile != "" && authorUri == urlMyProfile && urlMyAvatar != "")
avaimg = urlMyAvatar;
if(avaimg == "http://img2.blogblog.com/img/b16-rounded.gif" && urlNoAvatar != "")
avaimg = urlNoAvatar;
var newsize="s"+sizeAvatar;
avaimg = avaimg.replace(/\/s\d\d+-c\//, "/"+newsize+"-c/");
if(cropAvatar) newsize+="-c";
avaimg = avaimg.replace(/\/s\d\d+(-c){0,1}\//, "/"+newsize+"/");
if(authorName == 'Anonymous' && txtAnonymous != '' && avaimg == urlAnoAvatar)
authorName = txtAnonymous;
var imgcode = '<img height="'+sizeAvatar+'" width="'+sizeAvatar+'" title="'+authorName+'" src="'+avaimg+'" />';
if (authorUri!="") imgcode = '<a href="'+authorUri+'">'+imgcode+'</a>';
var clsAdmin = "";
if(urlMyProfile != "" && authorUri == urlMyProfile)
clsAdmin = " rc-admin";
var datePart = entry.published.$t.match(/\d+/g); // assume ISO 8601 var cmtDate = new Date(datePart[0],datePart[1]-1,datePart[2],datePart[3],datePart[4],datePart[5]);
var txtHeader = txtWrote;
if(txtWrote.indexOf('[')==-1)
txtHeader = authorName + ' ' + txtWrote;
else
txtHeader = replaceVars(txtHeader, authorName, postTitle, cmtDate);
var tooltip = replaceVars(txtTooltip, authorName, postTitle, cmtDate);
if(!/#/.test(href)) href += "#comments";
document.write('<div title="'+tooltip+'" class="rc'+clsAdmin+'">');
document.write('<div title="'+tooltip+'" class="rc-header'+clsAdmin+'"><div title="'+tooltip+'" class="rc-ico'+clsAdmin+'">'+imgcode+'</div><a title="'+tooltip+'" href="' + href + '">' + txtHeader + ' </a></div>');
if(comment.length < maxCommentChars)
document.write('<div title="'+tooltip+'" class="rc-body'+clsAdmin+'">' + comment + '</div>');
else {
comment = comment.substring(0, maxCommentChars);
var indexBreak = comment.lastIndexOf(" ");
comment = comment.substring(0, indexBreak); document.write('<div title="'+tooltip+'" class="rc-body'+clsAdmin+'">' + comment + '...</div>');
if(txtMore != "") {
var moretext = replaceVars(txtMore, authorName, postTitle, cmtDate);
document.write('<div title="'+tooltip+'" class="rc-footer'+clsAdmin+'"><a title="'+tooltip+'" href="' + href + '">' + moretext + '</a></div>');
}
}
document.write('<div style="clear:both;"></div></div>');
}
}
}
if(getTitles)
document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/posts/summary?redirect=false'+maxResultsPosts+'&alt=json-in-script&callback=getPostUrlsForComments"></'+'script>');
document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/comments/default?redirect=false'+maxResultsComments+'&alt=json-in-script&callback=showRecentComments"></'+'script>');
</script>
<span id=rcw-cr><a href=http://helplogger.blogspot.ro/2013/03/recent-comments-widget-with-hide-author.html>Recent Comments Widget</a></span> (<--不想顯示"Recent Comments Widget"的話,可以刪除這個綠色部分。)
========== 程式碼結束 ==========
步驟5)把程式碼中的「豆丁」(共出現兩次)換成你的留言名稱。
步驟6)把程式碼貼到「內容」,按「儲存」。
成功了!恭喜恭喜~~~~~
喜歡豆丁的教學,記得"like"、"+1"或與朋友分享啊~
謝謝你的鼓勵^^~
網友的溫馨提示
網友劉比蒂又細心,又熱心!她留意到有些訪客留言後又刪除留言,但卻沒有按「永久刪除」,這樣,他們的名字會繼續顯示,並且列明留言被刪除。大家如果不想刪除留言後仍然留有大名,記得選擇「永久刪除」啊!(當然,網主亦可再「永久刪除」^^~)
>> 閱讀豆丁的其他《Blospot教學》?
>> 歡迎閱讀豆丁的其他專欄:
*《豆丁遊世界》
*《微故事@豆氏村》
*《簡單食譜》
*《嘰哩咕嚕》