Blogger 提供讓你塞入 Sidebar 的文章匯總功能有三種介面,有階層(樹狀)、Flat 清單和下拉式選單,也可以調整排序和顯示的格式,不過,這樣總還是不夠。很多 BSP 提供的 Blog 都會有類似日曆的模組,除了會有類似萬年曆的功能,讓你知道「今夕是何夕」外,也可以透過這個日曆知道哪一天你發表過文章,透過點擊日期去知道當天你寫過什麼,所以這樣功能的日曆也叫做 "Archive Calendar",提供另外一種文章依日期分類匯總的檢視方法。
只是塞一個日曆並不困難,到處都可以找到 Javascript 程式複製貼上,但是要整合 Blogger 的 Archive 功能就麻煩了,以下分幾個步驟來進行。首先,在你的 Sidebar 上面要至少有一個 "Blog 存檔" (Archive) 的網頁元素 (Element),接下來去修改它的屬性,存檔頻率改成「每日」,勾選「先顯示最舊的文章」,樣式設成「Flat 清單」。因為 "Blog 存檔" 這個 Element 「看起來」只允許你存在一個,如果你想要有日曆而且原有的 Archive 也想保留,那就要去修改 HTML(不要展開小裝置範本),把下面這行複製一份,然後改一下 id(不重複就行),你就可以有兩個 "Blog 存檔",把新增的那個 Element 改成日曆就行了。不過如果你不需要那麼多 Archive 模組,這個動作就不要做了。
第二個步驟,塞入定義給 Calendar 用的 CSS (放在 <head> 標籤內就行,就是定義樣版的區段裡,請依照個人樣版修改,這次修改算是大變動,記得先完整備份你的 Template,這次要展開整個範本進行修改):
/* Archive Calendar Styles */
#Calendar {
margin: 0px;
}
#CalendarTable table {
border-collapse: collapse;
padding: 0px;
border: 0px;
}
#CalendarTable table th {
padding: 1px;
color: #777;
margin: 0;
}
#CalendarTable table td {
height: 25px;
color: #999;
text-align: center;
padding: 1px;
margin: 0;
}
#CalendarTable table td a {
display: block;
}
#CalendarTable .Today {
color: #fff;
background: #777;
}
#CalendarTable .Today a {
color: #fff;
}
#CalendarTable .Weekend {
color: #997777;
}
#Calendar .act {
color: #fff;
padding: 4px;
}
第三個步驟,也是是重頭戲:要貼入一堆 Javascript 函示。(一樣是貼在 <head> 標籤裡,如果你之前也有 Hack 放過 Javascript,放在一起就好)
<script type='text/javascript'>
//<![CDATA[
<!-- Script functions for generating Archive Calendar: ArchiveCalendar(), archiveurl(), YearMonth(), Calendar(), PrevMonth(), NextMonth(), function GoToday(), refreshTable() -->
function ArchiveCalendar() {
this.PrevMonth = PrevMonth;
this.NextMonth = NextMonth;
this.GoToday = GoToday;
this.refreshTable = refreshTable;
this.YearMonth = YearMonth;
this.Calendar = Calendar;
this.archiveurl = archiveurl;
this.week_label = new Array("一","二","三","四","五","六","日");
this.month_label = new Array("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12");
this.month_days = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
this.today = new Date();
this.cur_day = new Date();
this.blogarchivename = new Array ();
this.thisarchive = 0;
this.base = '';
}
function archiveurl(idx) {
url = this.base;
url += this.blogarchivename[idx].slice(0, 4) + '_' + this.blogarchivename[idx].slice(4, 6) + '_' + this.blogarchivename[idx].slice(6) + '_archive.html';
return url;
}
function YearMonth(date_obj) {
year = date_obj.getFullYear();
thisMonth = this.month_label[date_obj.getMonth()];
out = year+'-'+thisMonth;
return out;
}
function Calendar(date_obj)
{
year = date_obj.getFullYear();
thisDay = this.today.getDate();
thisMonth = this.month_label[date_obj.getMonth()];
nDays = this.month_days[date_obj.getMonth()];
if (date_obj.getMonth() == 1 &&(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)))
nDays = 29;
IsitNow = date_obj;
IsitNow.setDate(1);
startDay = IsitNow.getDay() - 1;
if (startDay < 0) startDay = 6;
var out='';
out+='<table>';
out+='<tr>';
for (var index=0;index<7;index++)
out+='<th style="width:25px;">'+ this.week_label[index]+'</th>';
out+='</tr>';
thisarchive=0;
while (thisarchive <= this.blogarchivename.length -1)
{
if(this.blogarchivename[thisarchive].slice(0,4) == year && this.blogarchivename[thisarchive].slice(4,6) == thisMonth)
break;
else
thisarchive++;
}
var tab_col=0;
for (index=0;index<startDay;index++) {
if (tab_col==0)
out+='<tr>';
out+='<td> </td>';
tab_col++;
}
var archiveday;
for (index=1;index<=nDays;index++) {
if (index<10) {
index_day = new Date(year+'/'+thisMonth+'/0'+index+' 00:01');
archiveday = '0' + index;
}
else {
index_day = new Date(year+'/'+thisMonth+'/'+index+' 00:01');
archiveday = index;
}
if (tab_col==0)
out+='<tr>';
if (index==thisDay && this.today.getMonth()==date_obj.getMonth() && this.today.getFullYear()==date_obj.getFullYear()) {
out+='<td class="Today">';
if (thisarchive < this.blogarchivename.length && this.blogarchivename[thisarchive].slice(4,6)==thisMonth && this.blogarchivename[thisarchive].slice(6,8)==archiveday) {
out+='<a href="'+this.archiveurl(thisarchive)+'" target="_top">'+index+'</a>';
thisarchive++;
}
else
out+=index;
out+='</td>';
}
else {
if (tab_col < 5)
out+='<td>';
else
out+='<td class="Weekend">';
if (thisarchive < this.blogarchivename.length && this.blogarchivename[thisarchive].slice(4,6)==thisMonth && this.blogarchivename[thisarchive].slice(6,8)==archiveday) {
out+='<a href="'+this.archiveurl(thisarchive)+'" target="_top">'+index+'</a>';
thisarchive++;
}
else
out+=index;
out+='</td>';
}
if (tab_col==6) {
out+='</tr>';
tab_col=0;
}
else
tab_col++;
}
if (tab_col>0) {
for (var si=0;si<(7-tab_col);si++) {
out+='<td> </td>';
}
out+='</tr>';
}
out+='</table>';
return out;
}
function PrevMonth() {
thisMonth = this.cur_day.getMonth()-1;
year = this.cur_day.getFullYear();
if (thisMonth<0) {
thisMonth = 11;
year = year-1;
}
thisMonth = this.month_label[thisMonth];
this.cur_day = new Date(year+'/'+thisMonth+'/1 00:01');
this.refreshTable();
}
function NextMonth() {
thisMonth = this.cur_day.getMonth()+1;
year = this.cur_day.getFullYear();
if (thisMonth>11) {
thisMonth = 0;
year = year+1;
}
thisMonth = this.month_label[thisMonth];
this.cur_day = new Date(year+'/'+thisMonth+'/1 00:01');
this.refreshTable();
}
function GoToday() {
this.cur_day = new Date();
this.refreshTable();
}
function refreshTable() {
document.getElementById('CalendarMonth').innerHTML = this.YearMonth(this.cur_day);
document.getElementById('CalendarTable').innerHTML = this.Calendar(this.cur_day);
}
//]]>
</script>
最後一個步驟,要修改範本顯示的版面囉!找到下面這一段:(如果你有兩個 Archive,要確認你找到的是要改的那一個)
<b:includable id='flat' var='data'>
<ul>
<b:loop values='data:data' var='i'>
<li class='archivedate'>
<a expr:href='data:i.url'><data:i.name/></a> (<data:i.post-count/>)
</li>
</b:loop>
</ul>
</b:includable>
然後整個取代改成下面這一段:
<b:includable id='flat' var='data'>
<!-- Generate Archive Calendar -->
<center>
<table border='0' cellpadding='0' cellspacing='0' id='Calendar'>
<caption>
<a href='javascript:;' onclick='Calendar.PrevMonth();' title='Previous Month'><< </a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href='javascript:;' onclick='Calendar.GoToday();' title='Back to Today'> <span id='CalendarMonth'/> </a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href='javascript:;' onclick='Calendar.NextMonth();' title='Next Month'> >></a>
</caption>
<tr>
<td class='act' id='CalendarTable'> </td>
</tr>
</table>
<script type='text/javascript'>
Calendar = new ArchiveCalendar();
Calendar.base = '你的 Blog 網址';
var offset = Calendar.base.length;
<b:loop values='data:data' var='i'>
archUrl = '<data:i.url/>'.slice(offset);
Calendar.blogarchivename.push(archUrl.slice(0,4) + archUrl.slice(5,7) + archUrl.slice(8,10));
</b:loop>
Calendar.refreshTable();
</script>
</center>
</b:includable>
其中,紅色的網址記得要改成自己的喔!範本存檔,然後預覽看看,如果日曆有出來,就可以存檔收工囉!其實原理和標籤雲 (Label Cloud) 類似,利用 Javascript 搭配 Template 提供的資料(Daily Archive),將 Element 的樣式動態改變,變成想要的樣子,就是這個多功能的日曆囉!再嚴謹一點,最後一段可以加入 <noscript> 的判斷,套用原來那一段,如果使用者的瀏覽器不支援 Javascript (或是關掉),那麼Archive 的功能也還是存在能夠使用~(這裡懶得改了)
參考文章:
為 Blogger Beta 加上日曆
備註:
實際掛上這個模組,又看了原始碼以後,發現如果 Blog 的文章很多,搞 Daily Archive 文章會很多很慢,尤其當 Blog 成立越久,為了依照日期填入日曆的「每一天」的存檔,會增加首頁載入的時間,發表天數越長越嚴重!我還蠻喜歡這個日曆的,看看要不要改個 Monthly Archive 的版本,效能應該會比較好才是~
修改:
根據網友意見,我把日曆的第一天從原來的禮拜天改成禮拜一,也比較符合自己的習慣,另外日曆週末的部分也稍稍改變顏色(class: weekend),用來標示,也可以自行修改樣式。
(2007/04/02) 修正 bug,如果有其他 style 的問題,請看看下面的意見和回覆的內容能不能解決。
回應: 93