2011年1月20日 星期四

-步驟-Blogger 首頁在文章底下,直接顯示回應留言,並自由開 / 關留言預覽(神奇的 ajax 效果!)
show and hide comments under each post on home page (and all non-item pages) with simple ajax implementation - my Blogger template tweak

hi, if you are using google translate on this article, please forget about the poor translation and check my notes below each important paragraph!


-- 2011-01-21 更新:在步驟 1 補上 jQuery 的語法 --

--
2011-01-23 update: add english description below important paragraphs
--

-- 2011-01-26 更新:由於 internet explorer 處理網頁的 cache 問題,導致本文使用的 jQuery .load() 語法在 ie 中沒有作用,可以參考這篇文章做修正,至於我的作法,是放一段偵測 browser 的 javascript 語法,如果目前瀏覽器是 ie ,網誌上方會跑出一段訊息,拜託他改用符合標準的瀏覽器。呵
2011-01-26 update: microsoft internet explorer has a cache problem that prevent jQuery .load() that i used in this article from working. to solve this problem, check this article. for me, i have enough of ie, so i just write a script which display a message in blog header while people are using ie, begging them for changing browser. ha.
--

前幾天,我的死黨發現,Blogger 網誌「在首頁無法看到文章的留言」!

在首頁裡,按文章的 comment 的話,畫面必須離首頁,連往文章頁面,等文章頁面整個讀取完以後,才會跳捲到底下回應的地方。

雖然這個過程,可能只要一兩秒鐘,如果是隨時都有一大堆留言的網誌,為了看留言等幾秒鐘也就罷了。不過,像我這麼冷門的網誌,為了一兩則回應,就要讀者這樣跳來跳去,實在是蠻浪費時間的。

網誌文章的回應,對於讀者來說,所代表的意義是「已經看過這篇文章的人有何感受」,也就是說,就像網路拍賣平台上的「買家/賣家評價」,可以讓交易雙方事先評估一樣,網誌文章的回應,除了讓作者和讀者互動之外,也可以讓後面的讀者在真正花時間進去看文章之前,先行判斷它究竟值不值得閱讀,值不值得自己為了它打開另一個網頁。所以說,在看文章前,讓讀者可以預覽留言,會令閱讀環境變得更友善。

上 Google 搜尋後發現,這個「在首頁顯示文章回應」功能,雖然有許多人詢問,但似乎沒有現成的實作方式。主要的原因是,Blogger 樣板依賴 data: 標籤撈資料出來,而文章回應的 data: 標籤,包括 data:comment.author(留言作者) data:comment.body(留言內容) 等,都只能夠在 pageType 是 item 的頁面,也就是單篇文章的頁面中使用。
* those data:comment.xxx tags can be used only at "pageType == item" pages, which mean the single post pages. that's why we can't just insert data tags into our templates. so we are going to do some simple javascript trick on it.

這是可以理解的,data:comment 標籤在多篇文章的頁面的話,會不知道要取哪一篇 post 的comment,所以限制只能在單篇 post 的頁面使用。(唉,是說,當初為什麼不設計成data:post.comment 呢?這樣就不必加上這層限制了。)

不過,對於立志成為程式設計師的的我來說,這點小限制,怎麼可以這樣就退縮呢?焦頭爛額了好一陣子之後,終於找到令我滿意的實作方式。原理就是利用現在流行的 ajax ,只要利用 jQuery 的 .toggle() 和 .load() 指令,就可以在 Blogger 首頁做出類似 facebook 展開留言那樣的效果。



樣板功能:在 Blogger 首頁、標籤瀏覽頁、封存頁... 等不是單篇文章的頁面中,按下文章底部的留言連結,不需另開網頁,即可原地預覽文章回應,並且自由打開 / 關上

連結文字從原本的「OO個回應」改成「預覽OO個回應」
* the original "OO comments" link text is changed to "preview OO comments"


按一下「預覽OO個回應」,留言會直接在文章底下展開,再按一下則會關上,以此類推,可以無限次數的打開跟關上。
* click "preview OO comments" link and comments will display just below post footer. click again will make them hidden



步驟如下:
  1. 首先,如果妳的網誌,過去沒有自己手動插入 jQuery 的話,請先在 Blogger 後台的 Design > page elements 中,在 footer 區段,按 add a gadget > html / javascript ,然後在裡面貼上下面這段文字:

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    如此,就可以使用下面會用到的便利的 jQuery 功能。
    * if you have never inserted this jQuery code into your template, please
    go to design > page elements,
    click "add a gadget" on footer section,
    select "html / javascript",
    paste the code above into gadget content and save.
    then you can use the jQuery javascript framework in your template.
  2. 在 Blogger 後台的 Design > edit HTML 中,將 打勾,展開小工具內的程式碼。
    * go to design > edit html, select "expand widget templates"
  3. 按 Ctrl + F 搜尋 b:includable id='comments' ,會找到像下面這一段文字:
    * press Ctrl + F to open the search box of your browser, search for b:includable id='comments' and you will find this:

    </b:includable>
    <b:includable id='comments' var='post'>
      <div class='comments' id='comments'>
        <a name='comments'/>
        <b:if cond='data:post.allowComments'>
  4. 把下面的文字,紅色部份選起來,按 Ctrl + C 複製,然後切到你的樣板程式碼頁面,在 b:includable id='comments' 這一行之上,按 Ctrl + V 貼上,貼上後看起來像這樣:(紅色字是貼上的部份)
    * insert the red part below to your template: (change the "看全部的回應" text to its english version "view all comments")

    </b:includable>
    <b:includable id='comment-preview' var='post'>
      <div expr:id='data:post.id + "_comment-preview"' style='display:none;'>
      <div expr:class='data:post.id + "_comment-preview"'/>
      <a class='comment-link' expr:href='data:post.addCommentUrl'>看全部的回應 »</a>
      </div>
    </b:includable>
    <b:includable id='comments' var='post'>
      <div class='comments' id='comments'>
        <a name='comments'/>
        <b:if cond='data:post.allowComments'>

    到這裡,我們就在樣板的 Blog widget 之內,自己建立了一個叫做 comment-preview 的留言預覽模組。
    接下來,要把這個孤零零的 comment-preview 模組,掛到 Blog 小工具的 main 模組之內,以便讓它真正的顯示出來。
  5. 按 Ctrl + F 搜尋 b:include data='post' name='post' ,會找到像下面這一段文字:
    * press Ctrl + F to open the search box of your browser, search for b:include data='post' name='post' and you will find this:

            <div class='post-outer'>
            <b:include data='post' name='post'/>
            <b:if cond='data:blog.pageType == "static_page"'>
              <b:include data='post' name='comments'/>
            </b:if>
            <b:if cond='data:blog.pageType == "item"'>
              <b:include data='post' name='comments'/>
            </b:if>
            </div>
  6. 把下面的文字,紅色部份選起來,按 Ctrl + C 複製,然後切到你的樣板程式碼頁面,在 b:include data='post' name='post' 這一行之下,按 Ctrl + V 貼上,貼上後看起來像這樣:(紅色字是貼上的部份)
    * insert the red part below to your template:

            <div class='post-outer'>
            <b:include data='post' name='post'/>
            <b:if cond='data:blog.pageType != "static_page"'>
            <b:if cond='data:blog.pageType != "item"'>
              <b:include data='post' name='comment-preview'/>
            </b:if>
            </b:if>
            <b:if cond='data:blog.pageType == "static_page"'>
              <b:include data='post' name='comments'/>
            </b:if>
            <b:if cond='data:blog.pageType == "item"'>
              <b:include data='post' name='comments'/>
            </b:if>
            </div>

    到這裡,就完成了「在 static_page 固定頁面以及 item 單篇文章頁面之外的地方,也就是文章的 comments 不會出現的地方,都在文章的下面,插入 comment-preview 外掛模組」的動作。
    接下來,要修改原本文章底下的回應連結,讓我們按下這個連結時,不是連到文章頁面去,而是在原地顯示這篇文章的回應,而且,在預覽打開的時候,只要再按一下,就可以把預覽的回應關起來,不然,有的文章留言很多的話,全部展開會變得很難閱讀。
  7. 按 Ctrl + F 搜尋 span class='post-comment-link' ,會找到像下面這一段文字:(紅色字是即將要被取代的部份)
    * press Ctrl + F to open the search box of your browser, search for span class='post-comment-link' and you will find this: (the red part is going to be replaced)

          <div class='post-footer-line post-footer-line-2'><span class='post-comment-link'>
            <b:if cond='data:blog.pageType != "item"'>
              <b:if cond='data:blog.pageType != "static_page"'>
                <b:if cond='data:post.allowComments'>
                  <a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><b:if cond='data:post.numComments == 1'>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
                </b:if>
              </b:if>
            </b:if>
          </span>
  8. 把下面的文字,紅色部份選起來,按 Ctrl + C 複製,然後切到你的樣板程式碼頁面,把上面那段文字中,紅色字的部份選起來,然後按 Ctrl + V 貼上,就可以取代原本的程式碼。貼上後看起來像這樣:(紅色字是貼上的部份)
    * paste the red part below to your template (and replace the original code) :
    (replace "留下回應" with "leave a comment" , and replace "預覽" with "preview")


          <div class='post-footer-line post-footer-line-2'><span class='post-comment-link'>
            <b:if cond='data:blog.pageType != "item"'>
              <b:if cond='data:blog.pageType != "static_page"'>
                <b:if cond='data:post.allowComments'>
                  <b:if cond='data:post.numComments == 0'>
                    <a class='comment-link' expr:href='data:post.addCommentUrl'>留下回應</a>
                  <b:else/>
                    <a class='comment-preview' expr:onclick='"var comments= \"" +data:post.id+ "_comment-preview\"; var url=\"" +data:post.addCommentUrl+ "\"; $(\"#\"+comments).toggle(); $(\".\"+comments).load(url+ \" #Blog1_comments-block-wrapper\");"' href='javascript:void(0)' title='預覽回應 preview comments'>
    預覽 <b:if cond='data:post.numComments == 1'>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
                  </b:if>
                </b:if>
              </b:if>
            </b:if>
          </span>
  9. ok! 大功告成!趕快儲存後試用看看吧 XD
    * it's done!

無限次數打開 / 關上留言預覽,是用 jQuery 的 .toggle() 做的。而載入文章留言,則是用 jQuery 的 .load() 達成。

.load() 所要載入的網址,設定成該篇文章的網址,意思是說,當我們按下「預覽回應」的時候,就載入這篇文章的網頁,以便抓取文章頁面上的留言。不過,因為 .load() 可以設定成單獨擷取某個區塊,而不需要讓瀏覽器讀取整個頁面,所以,即使要另外載入一個新的網頁,也不會顯得笨重。據說這就是所謂的 ajax 的原理... 啊!一年前,ajax 對我來說還是個恐怖的名詞,沒想到現在可以光明正大的在網誌上寫出這四個字,爽 XD

除了主要的預覽留言功能外,手賤的我又小改了一個地方,當文章沒有留言時,會顯示「留下回應」,按了之後,畫面會跳到該篇文章獨立頁面的底部,撰寫留言的地方。

而原本就有留言的文章,則會顯示「預覽OO個回應」,按下去之後,會在原本頁面的文章底下,顯示該篇文章的留言(前200則)。然後在這些留言下面,還附上一個「看全部的回應 >>」連結,按下之後才會連到該篇文章的獨立網址,並將畫面跳捲到留言開始的地方。

以上就是本菜鳥這幾天以來的得意之作,是否也符合妳的需求呢?

9 則留言:

  1. 有鑑於本冷格大部分的文章都沒有留言... 為了提供預覽效果,自己先留一個留言 XD

    回覆刪除
  2. 這太強大了,雖說我自己應該不會用到,但有這種功能真的太炫了,炫到--根本不知道可以這樣點開……

    回覆刪除
  3. 噗哈!
    點到的話,應該要在畫面上放煙火,恭喜他懂得我的品味!!XD

    回覆刪除
  4. Hi, in you 8 steps, does chinese words in red color affect its application?
    I tried your steps, but didn't work.

    Thanks

    回覆刪除
  5. Hi, the Chinese words will not affect its function.

    The problem may be:

    1. If you see it work in my blog -> try this instead

    https://gist.github.com/870036

    2. If you see it don't work in my blog ->

    It seems your are using internet explorer as your web browser, which has problem with jQuery .load() function. For now, I don't have a nice solution yet. I will keep trying! :-(


    Can you see it work in my blog anyway?

    回覆刪除
  6. 成功了
    謝謝你的教學!!

    回覆刪除
  7. @joe 對了,我後來把「看全部的回應 >>」的「>>」改成 「»」,感覺這樣比較好看,剛才文章內容也跟著修正了,覺得好看的話也可以試試 XD

    回覆刪除
  8. XML error message: The element type "b:if" must be terminated by the matching end-tag ""

    回覆刪除
  9. 請問有不用按,直接顯示全部的功能嗎 ??

    回覆刪除