2006-06-20

在Blogger上安插月曆( Calendar)


月曆?mmmmm..我不是講掛在牆上的月曆。這東西還有很多名稱,英文叫 Calendar ,另外也有人叫它行事曆,總之就是你在這個blog右下角 Archives 區塊內所看到的東西。要在 Blog 內安裝一個月曆並不難,隨便上網以 「Javascript 月曆」這兩個關鍵字去做搜尋就可以找到一大堆教學與範例了。但沒事在 blog 上顯示一個月曆也沒有什麼用。如果只是要查時間幾乎人人都有手錶,沒有手錶起碼也會有手機,在不然電腦上通常也會顯示時間 ( 如果你很大聲的反駁我你就是以上三者都,那這篇談論技術與科技的文章對於生活習慣還停留在五六零年代的你也沒有什麼意義了 ) 。的確單純的月曆並沒有存在的必要,由 Blogger 遲遲不願推出此功能也可以感受到。好吧,試想一個情況好了。因為老板突然聽到了blog這東西也興匆匆的要了每個人的網址。而你「忘記」你是否在兩個月前的文章上寫過老闆的壞話,你「必須」要確認一下。你覺得用條列式的 archives 搜尋好呢?還是希望有一個月曆的介面可以點選? ( 不過我想最大的啟示應該是沒事別亂寫文章,世事難料誰也不知道你的文章會被誰看到)。說這就是在blog上放月曆的理由有點牽強(但也難講,哪天google的員工遭遇此危機或許隔天就會釋出月曆的功能了),但blog是相當零散的媒體,若將月曆與 archive 整合對於文章的搜尋有一定的幫助。其實在很多的blog系統上都提供了此功能,不過很可惜的是blogger並沒有,所以也只好靠使用者自己開發了。

為了要在blog上加入月曆的畫面,我花了約一天的時間找資料與修改。如果你也想自己來,可以參考這兩位強者的 blog
ecmanaut: Adding calendar navigation to your Blogger template
Mr. Zenith's 成長日記
Calendar做得很華麗,但我只要簡單的就好。另外還找到一個較為簡易的版本,但在我的blog上總是失敗。無奈之下只好從頭撰寫了。既然是軟體不免俗的總要先來個版權宣告,javascript由於source code人人都看得到要保護版權實在有點麻煩,不過還是要說一下這個程式我是以一位大陸網友在blog上釋出的月曆程式原始碼
日历与my web - 哈斯日志
修改來的。用javascript寫出一個單純的月曆並不困難,不過我是個懶人,就省略這段直接先用別人寫好的吧。

要在你的blog上植入這套我修改過的月曆程式,首先要將
blog存檔的「頻率」設定為「每日」,
「日期標題格式」設定為 「2006-06-20」
「把索引日期格式存檔」設定為 「2006-06-20」
若你不想修改日期格式,你也可以去程式碼中找到這段敘述
for (var x in blogarchivename)
{
blogarchivename[x] = blogarchivename[x].slice(0,4) + blogarchivename[x].slice(5,7) +blogarchivename[x].slice(8);
}

修改配合你自己的日期格式去修改,只要最後是以20060220這樣的格式存入 blogarchivename即可。
接下來開始修改blog的範本吧。如果你對於HTML, CSS 與 JavaScript不是很熟悉,那建議你在修改前先備份原始的範本。先找到範本中存放 Style 的位置(通常是放在head內)加入下列敘述
/* Calendar v0.3
----------------------------------------------- */
#Calendar {
border:1px solid #222;
margin:0px;
}
#Calendar caption {
color:#fff
}
#Calendar caption a:link, #Calendar caption a:visited, #Calendar caption a:hover, #Calendar caption a:active {
color:#777;
text-decoration:none;
}
#Calendar caption today{
font-weight:light;
font-size:smaller;
}
#CalendarTable a:link, #Calendar a:visited, #Calendar a:active{
text-decoration:none;
//background: #444;
font-weight:bold;
Text-decoration:underline;
color: #fff;
}
#CalendarTable a:hover {
text-decoration:none;
}
#CalendarTable table {
border-collapse:collapse;
padding:0px;
//width:173;
//height:220px;
border: 0px;
}
#CalendarTable table th {
font-family:Arial;
font-size:12px;
padding: 1px;
color:#777;
margin: 0;
}
#CalendarTable table td {
font-family:Arial;
font-size:12px;
width:25px;
height:25px;
border: 1px solid #444;
color:#777;
text-align:center;
padding: 1px;
margin: 0;
}
#CalendarTable table td a {
display: block;
}
#CalendarTable .Today {
background: #444;
color: #fff;
}
#CalendarTable .Today a {
}
#CalendarTable .Lastday {
}
#Calendar .act {
color:#000;
padding:4px;
}

這些是用來設定月曆外觀的CSS設定。然後在head標記結束前(或是任何你想放置的位置,只要放置在顯示月曆的html碼之前就可以了)放入下列javascript
<script language="javascript" type="text/javascript">
var week_label = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
var month_label = new Array("01", "02", "03", "04", "05", "06", "07", "08",
"09", "10", "11", "12");
var month_days = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

var today = new Date();
var cur_day = new Date();

var blogarchivename = new Array ();
var blogarchiveurl = new Array ();
var thisarchive = 0;
<BloggerArchives>
blogarchivename.push("<$BlogArchiveName$>");
blogarchiveurl.push("<$BlogArchiveURL$>");
</BloggerArchives>

for (var x in blogarchivename)
{
blogarchivename[x] = blogarchivename[x].slice(0,4) +
blogarchivename[x].slice(5,7) +blogarchivename[x].slice(8);
}

function YearMonth(date_obj)
{
year = date_obj.getFullYear();
thisMonth = month_label[date_obj.getMonth()];
out = year+'-'+thisMonth;
return out;
}

function Calendar(date_obj)
{
year = date_obj.getFullYear();
thisDay = today.getDate();
thisMonth = month_label[date_obj.getMonth()];

nDays = 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);
//get the day of the week (0~6)
startDay = IsitNow.getDay();
var out='';
out+='<table>';
out+='<tr>';
for (var index=0;index<7;index++)
{
out+='<th>'+week_label[index]+'</th>';
}
out+='</tr>';

thisarchive=0;
while (thisarchive <= blogarchivename.length -1)
{
if(blogarchivename[thisarchive].slice(0,4) == year &&
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 class="Lastday"> </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 && today.getMonth()==date_obj.getMonth() &&
today.getFullYear()==date_obj.getFullYear())
{
out+='<td class="Today">';
if (thisarchive < blogarchivename.length &&
blogarchivename[thisarchive].slice(4,6)==thisMonth &amp;&
blogarchivename[thisarchive].slice(6,8)==archiveday)
{
out+='<a href="'+blogarchiveurl[thisarchive]+'" target="_top">'+index+'</a>';
thisarchive++;
}
else
{
out+=index;
}
out+='</td>';
}
else
{
out+='<td class="Lastday">';
if (thisarchive < blogarchivename.length &&
blogarchivename[thisarchive].slice(4,6)==thisMonth &amp;&
blogarchivename[thisarchive].slice(6,8)==archiveday)
{
out+='<a href="'+blogarchiveurl[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 class="Lastday"> </td>';
}
out+='</tr>';
}
out+='</table>';
return out;
}

function PrevMonth()
{
thisMonth = cur_day.getMonth()-1;
year = cur_day.getFullYear();
if (thisMonth<0)
{
thisMonth = 11;
year = year-1;
}
thisMonth = month_label[thisMonth];
cur_day = new Date(year+'/'+thisMonth+'/1 00:01');
refreshTable();
}

function NextMonth()
{
thisMonth = cur_day.getMonth()+1;
year = cur_day.getFullYear();
if (thisMonth>11)
{
thisMonth = 0;
year = year+1;
}
thisMonth = month_label[thisMonth];
cur_day = new Date(year+'/'+thisMonth+'/1 00:01');
refreshTable();
}

function GoToday()
{
cur_day = new Date();
refreshTable();
}

function refreshTable()
{
document.getElementById('CalendarMonth').innerHTML = YearMonth(cur_day);
document.getElementById('CalendarTable').innerHTML = Calendar(cur_day);
}
</script>

最後,在要出現行事曆的位置(通常是sidebar)放上下面這幾行程式碼
<table border="0" align="center" cellpadding="0" cellspacing="0"
id="Calendar">
<caption>
<a href="javascript:;" class="today" onClick="GoToday();">Today </a>
<a href="javascript:;" onClick="PrevMonth();" >&lt;< </a>
<span id="CalendarMonth"> </span>
<a href="javascript:;" onClick="NextMonth();"> &gt;></a>
</caption>
<tr>
<td class="act" id="CalendarTable"> </td>
</tr>
</table>
<script type="text/javascript">
refreshTable();
</script>

好啦,在正式發佈之前先預覽看看吧。順利的話應該會看到月曆出現在你的blog上囉,這下總算可以用行事曆來查詢過往的文章了。不過這個月曆其實也存在這部分限制,這等下篇文章提到介面的微調時在來介紹吧。

7 則留言:

shizo 提到...

壩子你好:關於這篇月曆教學,我已經在我的blog安裝成功了,而且我用FireFox和Safari瀏覽都沒有問題(我沒IE,沒法測試),可是朋友使用IE卻看不到月曆,請問您的情況是否如此呢?目前我先把月曆拿掉!回復到之前的狀態了:(

Bart 提到...

抱歉抱歉造成你的困擾。不知道你是使用上面的程式碼還是複製自我目前 blog 網頁的原始碼呢?其實我後來還有在做一些小測試與修改,經過你的提醒才發覺我的 blog 網頁在 IE 下會有日曆無法顯示的情形。原因出在於我為了將網頁符合 xHTML ,將 Javascript的起始與結束部分改為:
 <script type="text/javascript">
//<![CDATA[
<!--
造成 IE 的誤判。將多餘的 <!-- 與 -->與拿掉就可以囉。如果有什麼問題可以在跟我聯絡。

Nike小周 提到...

感謝您喔~"聰明"壩子...^^
你的這個月曆實在是"棒呆了"!
令我受用無窮呀~呵呵...

匿名 提到...

真的是感謝你啊!!
這樣一來我的網誌功能又更齊全了!!謝謝!!

匿名 提到...

請問有辦法直接在Page Elements 加入一個HTML/JavaScript 區塊 然後直接貼在區塊裡面嗎?

bluesky 提到...

壩子

請問,現在的blogger裡有個『網頁元素』功能,
如果我要從網頁元素裡增加您的月曆功能表,
該如何放上JavaScript碼呢?
謝謝!

Janice Ong 提到...

你好關於archive calender
我在修改html的時候
blogger說我的"<$BlogArchiveName$>"有錯誤
請問是為什麼啊