2008-10-27

內嵌的文章留言 (Embedded Comment Form)

自從四個月前 Blogger in Draft 發表了多項新功能後,其中除了 Import / Export 這個備份功能外,我最感興趣的就是終於有內嵌式的文章留言了。當然第一時間我也玩了一下,功能面我很滿意,但是在自訂外觀和手動調整方面限制很多,一方面懶、另一方面想說等正式版公佈後再花時間研究,所以遲遲沒有套用在 Blog 上。終於在上禮拜,Blogger 官方 Blog 宣佈這個功能在正式版上可以使用,當然我也掛來玩,發現在 Draft 上的限制依舊,但功能更完整和強大了,既然都是正式版了,那還是來更新一下吧!

官方說明該功能要啟用很簡單,只要登入 Blogger 的後台介面,在「設定」、「意見」的地方,將「意見欄位置」,從原來的地方改成「已內嵌下列文章」(Embedded below post, 嵌入文章下方,翻譯的真爛)就好了!但如果這樣啟用,在文章的下方卻沒看到可以直接回應文章的表單的話,那代表你使用了非官方的樣板、或像我曾經改動過程式碼,讓系統找不到能嵌入原始碼的地方,為求安全起見,Blogger 不敢硬塞破壞原來的版面,所以啟用後才會看不見,如果仍堅持要用這個功能,請乖乖修改程式碼 Hack 一下,才能正確啟用囉!(如果你到這個步驟就看得到內嵌的意見欄,那下面就可以跳過啦!)

嵌入式留言功能的設定方法(順利的話這個步驟就能完成)

動手修改之前,我比較了一下前後程式碼的差別。官方為了實現這個功能,產生了一段多的程式碼(照理來說這段每個人的樣板裡都有,打開「版面配置」、「修改HTML」、「開啟小裝置範本」,搜尋一下就找得到),讓使用者能 include 這個「模組」,這段原始程式碼如下(如果找不到,自己找類似的地方複製貼上):

<b:includable id='comment-form' var='post'>
  <div class='comment-form'>
    <a name='comment-form'/>
    <h4 id='comment-post-message'><data:postCommentMsg/></h4>
    <p><data:blogCommentMessage/></p>
    <data:blogTeamBlogMessage/>
    <a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
    <iframe allowtransparency='true' class='blogger-iframe-colorize' frameborder='0' height='275' id='comment-editor' scrolling='auto' src='' width='100%'/>
    <data:post.iframeColorizer/>
  </div>
</b:includable>

顧名思義,這個 comment-form 模組就是顯示「內嵌意見欄」的程式碼定義,仔細一看,沒錯,是用之前曾經人人喊打的 iframe 語法,如果端詳一下原始碼,會發現嵌入 iframe 裡的是一隻 Javascript 程式,不過為了實現很多神奇的功能(容後述),似乎也不得不這樣做。但也因為意見欄完全由內嵌 iframe 的 Javascript 產生,如果更要改樣式內容就變得很困難(這就是我前面說的限制),還好那個程式寫得還不錯,當嵌入 Blog 後,會根據你 Blog 的背景和文字樣式自動調整,所以顏色字型不至於格格不入。如果樣板裡有發現上面那段程式碼,接下來才進到 Hack 的重點:要找到「內嵌意見欄」程式碼的正確位置,然後塞進顯示的程式碼。

程式碼很短,但找到正確的位置很不容易(人眼都不一定看得出來,也難怪 Blogger 系統找不到),我 Google 了一些修改的文章,裡面範例的程式碼和我的樣板不大一樣,所以這裡只能交代一下「大原則」,不要問我為什麼你的樣板裡面找不到(尤其是只想 search & replace 的人),因為每個人的樣板都不一樣。原來樣板裡的「發表留言」,程式碼只不過是一行帶你到留言介面的「連結」,這個連結會塞在首頁,以及文章的後面,連結的程式碼為:

<a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><data:postCommentMsg/></a>

所以你在搜尋上面這段的時候,如果有多筆就要判斷一下(只有一筆就直接改啦),基本上是在 <p class='comment-footer'> 這一行下面、最靠近它的那一筆,才是嵌入文章下方的正確位置。上面這一行的內容是找出留言的連結網址 (a expr...)、還有顯示發表留言的訊息(<data:postCommentMsg/>,像我的 Blog 這個訊息就是「張貼意見」),要嵌入意見欄、哪天不想用又可以改回來(到「設定」、「意見」切換回「整頁模式」就行),把上面那一行取代成下面這樣(如果你原始碼裡有其他樣式定義,請自行補足):

<b:if cond='data:post.embedCommentForm'>
  <b:include data='post' name='comment-form'/>
<b:else/>
  <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><data:postCommentMsg/></a>
</b:if>

有點程式基礎的應該看得懂,我用了一個 if 的判斷句,如果在設定那邊開啟「已內嵌下列文章」(cond='data:post.embedCommentForm'),那就使用 comment-form 這個模組,不然,請使用可以跳到留言介面的連結,順利的話這樣就搞定啦~如果你對留言的樣式不滿意,就像上面講的,iframe 裡面定義的玩意很難改動,我唯一有做的,就是把這個意見欄寬度,改得和我 Blog 文章一樣,不然就那麼一小塊看起來怪怪的。改法也不難,就是在 CSS 樣式區段裡 (<b:skin> 後面)、加入覆蓋原定義的宣告:

/* The comment-form width */
.comment-form {
  max-width: 650px !important;
  width: 650px !important;
}

紅色的值請照每個人樣板的寬度自行調整。我個人覺得原來另外跳出的留言介面(整頁模式)其實也很不錯,不但不用改就能顯示頭像、留言的身份和登入系統整合的也比較完整,重點還有防垃圾留言的機制。內嵌的意見欄雖然比較簡潔、也符合一般 Blog 的習慣,但功能還不夠齊全,還好未來 Blogger 官方只要修改 iframe 嵌入的那隻 Javascript,應該也能無痛升級,這點就請各位期待囉~

這個內嵌意見欄比起一般 Blog 的留言有幾個特異功能,首先是留言的身份,除了最基本的匿名、提供名字網址、用 Blogger 身份,還有像 AOL、OpenID 或幾種常見的 Blog 系統帳號,當然,只要你有輸入過,它也會 Log 起來,不過特別的是它把紀錄的 cookie 直接整合進下拉的 combo list 上面,這樣就不用仰賴瀏覽器的「自動完成」啦!再者,由於提供多種系統的登入支援,登入資訊是用 popup 的小視窗動態顯示在 iframe 裡,所以登入、文章預覽和留言結果,都是塞在 iframe 的範圍內,這樣好不好見仁見智,但至少不用跳轉下一頁、而且又不會破壞版面 Layout。最後,也是網友熱烈要求的「訂閱」功能,只要使用者留言時的「身份」裡面有正確的 e-mail,點下「訂閱」的連結,只要該文章的留言有更新或回覆時,系統都會主動寄 e-mail 來通知你,這樣對留言發問的人來說,就不用一直盯著留言等回應了~

留言身份的整合機制、留言的訂閱功能

其實除了嵌入式的留言介面,還有 RankingStar Rating 評分機制,和最新的「追蹤者」紀錄、還有 iGoogle 的文章發表 Widget ,都看得出來 Blogger 一直在成長和進步,而且都不需要 Hack 修改就能用(反而,如果你像我去 Hack,會導致這些新功能不能用,就像這個嵌入式留言還要修改才出得來)。所以如果是新手使用者、沒時間或能力來修改,就和一般 BSP 一樣,直接用官方的樣板和模組,套用起來既簡單又方便,像我一樣不安於室的、或嫌官方功能不好用的,才需要手動亂改,而且要擔的風險就像這個 Hack 一樣,一日 Hack 就終身都要 Hack 了,雖然可以隨心所欲把 Blog 調整成自己想要的樣子,但手動調整功能和定期維護都是免不了的啦~

回應: 77

 

2008-10-24

網誌存檔預設收合 (Archives Default Collapsed)

原先我是用「網誌存檔」這個 Blogger 的預設模組來做 Archive Calendar,後來搞出 Feed Calendar 後,這個 Archive 模組還是保留(就是我現在版面、旁邊的 MONTHLY ARCHIVE),而且恢復了它的原貌。我喜歡用的樣式是「階層」(Hierarchy)、每月存檔一次,好處是可以依年月動態展開自己發表的文章,方便統計和依時間快速索引。不過這個樣式有個缺點,就是預設會展開、讓在 Sidebar 這個模組變得很長,偏偏 Blogger 並沒有調整預設不要展開的選項,所以只好手動 Hack 一下。

這個 Hack 要修改樣板的原始碼。到「版面配置」、「修改 HTML」、勾選「展開小裝置範本」(記得先手動備份樣板),先找到「網誌存檔」的區段(type='BlogArchive'),找到下面這一段:

<li expr:class='&quot;archivedate &quot; + data:i.expclass'>

然後取代成下面這樣(如果找不到,找關鍵字 data:i.expclass 也行),意思是預設將網誌存檔的樹狀結構收合折疊起來:

<li expr:class='&quot;archivedate collapsed&quot;'>

這樣是收起來了沒錯,但是怎麼預設的箭頭符號還是展開的啊?這一點也要修正。找一下下面這段程式碼:

<b:includable id='toggle' var='interval'>
  <b:if cond='data:interval.toggleId'>
  <b:if cond='data:interval.expclass == &quot;expanded&quot;'>
    <a class='toggle' expr:href='data:widget.actionUrl + &quot;&amp;action=toggle&quot; + &quot;&amp;dir=close&amp;toggle=&quot; + data:interval.toggleId +       &quot;&amp;toggleopen=&quot; + data:toggleopen'>
        <span class='zippy toggle-open'>&#9660; </span>
    </a>
  <b:else/>
    <a class='toggle' expr:href='data:widget.actionUrl + &quot;&amp;action=toggle&quot; + &quot;&amp;dir=open&amp;toggle=&quot; + data:interval.toggleId +         &quot;&amp;toggleopen=&quot; + data:toggleopen'>
          <span class='zippy'>

就修改紅色的地方,把 close 改成 open (預設是展開的,所以連結點下去會收合,改成預設收合後,連結點下去就是 open 囉!),然後把 &#9660; 改成 &#9658;(更改圖示),這樣才算是完整地修改預設的畫面顯示和操作。最後,因為預設這些展開、收合的圖示是用 ASCII 碼中的特殊符號,在 IE6 裡面一樣會莫名其妙放大(再罵一次,IE 真爛),如果你覺得礙眼,一樣可以透過 CSS 來修正。在 CSS 區段(標籤 <b:skin> 後面)裡加入下面的定義就搞定了:

#ArchiveList .toggle-open {  /* Fixed for IE */
  _font-size: 90% !important;
}

其實這篇不是什麼新的玩意,我一直都有在用,只不過用過當時忘了記錄下來,突然臨時發生狀況時不知所措,才趕緊再去找一下解決方案,然後再筆記起來。

參考文章:收縮Blog Archive!

回應: 13

 

2008-10-22

自訂樣板的變數 (Blogger Template Variable)

自從上次發生 Google Pages 放出即將停止的消息,相信很多人和我一樣,原本將 Google Pages 當圖床的,紛紛轉換地方用來 Hosting 部落格專用的圖檔。不知道大家是不是覺得很麻煩,要去找出樣板裡所有 Hard-code 的圖檔網址和檔名,然後一一取代到新圖床的位置。尤其像我用了不少 Hack,還要一個個模組檢查,真是辛苦。本來想說就做一次而已,認了~但,最近重灌電腦,預設的 IE 回復成 6.0,有天瀏覽自己 Blog 時發現,怎麼所有透明底圖和動態的 GIF 都不透明了 (GIF transparency)?雖然在 IE7 和 Firefox 是正常的,但還在用 IE6 的人應該還不少吧!Google 完發現好像是我新圖床:Google Sites 的問題!這可不是開玩笑的,Bug 修正前我只好暫時再回去用 Google Pages 頂一下,不過,之前做過一次更改圖片路徑的事情又要全部重作一次,實在好累啊!

後來思考,程式寫多了,能不能搞一個類似全域變數,用一個變數來指定圖床的網址,以後有任何更改,只要改這一個變數內容就行啦!試了很多辦法,包含用 Javascript 做,都沒辦法做到我希望看到的程度,回頭看看 Blogger 的原始樣板,沒錯,在 CSS 區段內是有 Blogger 樣式變數的定義,官方也有文件解釋使用方法和語法,不過文件中標明了「這是用來自訂文字和顏色」使用的(也就是用在「版面配置」、「字型和顏色」的版面設定),type 也只有 font 和 color 兩種,沒搞頭啊!不過反骨的我當然不放棄,管他的,先試了再說。開始前先講一下這種樣板變數的預設用法。在樣板裡面,定義樣式變數的區段是在 <b:skin> 標籤的後面,拿我的樣板擷取部份來舉個例子:

/* Variable definitions
   ====================
   <Variable name="bgcolor" description="Page Background Color"
             type="color" default="#000" value="#000000">
   <Variable name="textcolor" description="Text Color"
             type="color" default="#ccc" value="#cccccc">
   <Variable name="linkcolor" description="Link Color"
             type="color" default="#9ad" value="#99aadd">
......

這一段是用來宣告和定義 CSS 使用的自訂變數型態和內容,像是 bgcolor 變數,就是設定 Blog 的背景顏色,textcolor 想當然是文字顏色。當在調整 CSS 顏色或字型時,像是某個區塊要指定 Blog 背景色為該模組的背景、文字也套用整個 Blog 的字型顏色,在 CSS 定義裡就可以寫成像:

code.cmd {
  color: $textcolor;
  background: $bgcolor;
}

是的,呼叫的方式就是直接用 $變數名稱。進入重點,我們來自己定義一個變數,當作外連圖片的網址:

<Variable name="imgURL" description="Image hosting URL"
             type="automatic" value="http://abinlee.link.googlepages.com">

其中變數名稱叫 imgURL,變數的內容(網址)為 value 裡的定義(請自行修改),那麼只要在 Blogger 專用的 CSS 區段裡(<b:skin> </b:skin>),都可以用 $imgURL 來取用圖片網址這個變數囉!還記得我在這篇「在版面格式中放入小圖示」的文章中提到,把常用圖片從 <img> 標籤改成了 <span> 定義、以 CSS 取代傳統圖片連結,這時候又派上用場,「所有」 Blog 裡用到的小圖片我都用 CSS 定義取代,也因此這些圖片的網址就都能用這個自訂變數啦!舉個例,我 Blog 常見的一個小動態 GIF 的定義變成:

.sign-icon {
  background: url($imgURL/sign.gif) no-repeat left;
  padding-left: 11px;
}

把 <img> 變成了 background 圖檔(聽說改成這樣還好處多多,圖片可以背景讀入提昇網頁效率),記得加個 padding-left(值就是該圖檔的寬),而實際的使用上從:

<img src="http://abinlee.link.googlepages.com/sign.gif" title="Sign">

變成了:

<span class=sign-icon title="Sign">&#160;</span>

程式碼變的比較短(少了固定圖片網址)、更有彈性(用 CSS 就能調整圖片樣式),還可以得到加速載入(背景讀取)以及套用樣板變數的好處,真是有百利而無一害啊!哪天 Google Sites 又修好、想換圖床的時候,我只要改 imgURL 的變數值,整個樣板模組不大需要變動,很快就可以搞定了!

不過別高興的太早,還有最後一個步驟。剛剛提到我們的各種圖檔都搞成背景讀入,這樣很棒,但在 IE6 又有一個狀況(IE 真是個爛瀏覽器),背景讀入的圖片被預設取消 Cache,也就是說每當你游標移到這些「背景讀入」的 GIF 檔,它又會重新載入、看起來像是閃爍一樣,這個問題要透過 Javascript 去調整 BackgroundImageCache 的預設值。請在 Javascript 的區段加入:

<!-- Used for Fixing IE6 background image cache problem  -->
<script type='text/JavaScript'>
try {
  document.execCommand(&#39;BackgroundImageCache&#39;, false, true);
} catch(e) {}
</script>

這個設定在其他瀏覽器都是正常無害的,專門針對 IE6 開啟。

最後總結一下。本文是利用 Blogger 內建專屬的樣式變數,拿來實現樣板全域變數的需求,接著把所有用到 <img> 標籤的圖檔,統統轉換成 CSS 的樣式控制,以便能使用剛定義的全域變數,達到用一個變數控制所有圖檔網址路徑的目的。最後再修正 IE6 對 CSS 樣式背景圖不 Cache 的問題,這樣就大功告成了!這裡也可以倡導一下好的程式寫作概念,所有宣告都應該模組化以保持彈性,避免 Hard-code 任何可能需要修改的資訊在程式主體裡,才能避免未來找不到或沒改到,未來還可以預留樣式調整的彈性。

回應: 6