沒穿方服

索引

顯示╱隱藏內文
顯示具有 blogger 標籤的文章。 顯示所有文章
顯示具有 blogger 標籤的文章。 顯示所有文章

2012-09-22: 現在插入的 HTML 不一定有 <div class="separator"> 部分,script 也改為沒有這個 div 也能取代。

Blogger 文章編輯器「上傳圖片」自動插入的 HTML 為:

做了一支 bookmarklet 把它改成以下格式:

將 bookmarklet 加進書籤 → 清理 blogger 插入的圖片標籤
在文章編輯器的 HTML 模式執行就立刻取代,不保證原文的安全,請自己保重。


原始碼

var
  $textarea = document.getElementById('postingHtmlBox'),
  pattern = [
    '(<div class="separator" style="clear: both; text-align: center;">\n)?',
    '<a href="(.+)"',
    ' imageanchor="1" style=".*"><img border="0" height=".+" width=".+" ',
    'src="(.+)" /></a>(</div>)?'
  ].join(''),
  re = new RegExp(pattern, 'g');

if ($textarea) {
  $textarea.value = $textarea.value.replace(re, function (str, p1, p2, p3, p4, p5) {
    return [
      '<a href="', p2, '">',
      '<img src="', p3, '" alt="" /></a>'
    ].join('');
  });
} else {
  alert('錯誤,找不到 textarea#postingHtmlBox。');
}

可以插好多的表單

最近有些 blogger 管理者把留言表單拿掉了,換成彈出視窗,或整頁模式。

這支 bookmarklet 會試著把表單塞回網頁:
自助嵌入 blogger 留言表單


用了沒反應,蛤~怎會這樣?

1)僅在「單篇文章」頁面有用。 2)因各人模板不同,也可能沒效。 3)只支援 Firefox、Google Chrome、Opera 和 Safari 等。

原始碼拆開如下:

var cmt_div = document.getElementById("comments");
var url, anchor, a = cmt_div.getElementsByTagName("a");
for( i = 0 ; i < a.length ; i++ ) {
  if( a[i].hasAttribute("href") && a[i].getAttribute("href").match(/g\?blogID=([0-9]+)\&postID=([0-9]+)/) ) {
    url = 'http://www.blogger.com/comment-iframe.g?blogID=' + RegExp.$1 + '&postID=' + RegExp.$2;
    anchor = a[i];
  }
}
cmt_iframe = document.createElement("object");
cmt_iframe.setAttribute('data', url);
cmt_iframe.setAttribute('style', 'display:block; width:100%; height:250px; color:#000; background-color:#f4f1f4; opacity:0.95; padding:0 4px; margin:2px 0; border:2px solid #fff;');
anchor.parentNode.insertBefore( cmt_iframe, anchor.nextSibling );
window.scrollTo( cmt_div.offsetLeft, cmt_div.offsetTop );

不曉得哪時候開始,用 ie 開某些 blogger 的單篇文章會顯示「操作已中止」錯誤:

讀取到一半,操作已中止 然後就無法顯示網頁

重現方法之一,是在 blogger 後台「意見設定」將「意見欄位置」改為「已內嵌下列文章」,然後在「版面配置」新增 MyBlogLog 的小工具,再用 ie 6 開啟單篇文章網址,就爆了。

關鍵是 blogger 內嵌意見表單的原始碼,裡面的 BLOG_CMT_createIframe 跟 ie 不合,如果把這句延到頁面讀完再執行,可以避開「操作已中止」錯誤:

// 以下是在模板內
if ( document.addEventListener ) {
  document.addEventListener( &quot;DOMContentLoaded&quot;, function(){
    BLOG_CMT_createIframe(&#39;<data:post.appRpcRelayPath/>&#39;, &#39;<data:post.communityId/>&#39;);
  }, false );
}
else if ( document.attachEvent ) {    // ie 跑這邊
  window.attachEvent(&quot;onload&quot;, function(){
    BLOG_CMT_createIframe(&#39;<data:post.appRpcRelayPath/>&#39;, &#39;<data:post.communityId/>&#39;);
  });
}

不過即使如此,測試留言功能依然失敗,送出時會發生「存取被拒」。


我的建議是:除了內嵌表單,最好也弄個鏈結到留言頁面,例如這個 blog 在單篇文章可以點「張貼意見」旁的小傘標 ☂(ie 可能會顯示方框)看到效果。原理可參考舊文 內嵌留言表單 + 彈出留言視窗 中的 手動插入「彈出留言視窗」鏈結

不然使用者關掉 JavaScript 會找不到地方留言。

陽春的 blogspot 連留言編號都要自己做,來龍去脈請見 Abin's Tech Note: 增加文章留言回應的編號 寫得很清楚。作法方面除了該篇採用的 JavaScript 外,也可考慮 CSS counter,在樣式裡加上:

.comments {counter-reset: count;}
.comment-timestamp:before {
  content: counter(count) '.';
  counter-increment: count;
}

其中 count 變數可以隨意改名,content 屬性也可作變化,稍微搜尋一下應該就有參考了。

格式可以稍做變化

※很舊的瀏覽器不支援(我真好心,每次都提這個)

Blogger 預設模板 <header> 中有一行 <b:include data='blog' name='all-head-content'/> 會自動插入有用的 meta(版權、編碼等)、link(預設 Feed 網址等)和其他。

幾個原因考慮刪除:

  1. 會自動插入預設的 favicon,順序沒弄好的話會蓋掉手動加的 favicon。
    參考這篇 Blogger Buster: Fixing Custom Favicons for Blogger Blogs
  2. 會自動插入 MSSmartTagsPreventParsing 這個 meta 項目,防止微軟跑聰明標籤?
  3. 最近又默默加了一段語法,內容可參考 七月佑安: 解決Blogger下jstiming和_WidgetManager未定義的錯誤(但該文結尾並不刪除 'all-head-content');這段語法除了無預警塞進來外,裡面的 & 符號也會在 HTML 驗證造成 9 個錯誤。

只是如第三點的連結中所說,要是刪了,日後說不定又會出問題。

上傳新範本時遇到的 bX-928o1o 錯誤,狀況如下:

  1. 小裝置即將刪除:

    列出的小裝置就是需要檢查的

  2. 很抱歉:

    bX-928o1o

搜尋一下會找到解答,把 <b:widget id='XX1' 裡的數字改正即可。

具體作法是參考舊的範本(就是管理介面「修改 HTML」那個),裡面有類似 <b:widget id='Feed1' 這樣的東西,但要上傳的範本裡可能是 <b:widget id='Feed4',兩邊 1 跟 4 沒對上就會出問題。

所以請修改要上傳的範本,把 widget id 改成跟舊的一樣即可。像前面例子就是要改成 Feed1

※ 把 widget 砍光再新增,id 好像就會重排的樣子,這樣改舊的 widget 來適應新範本應該也可行。

以下是 blogger 文章編輯器「上傳一張圖片」自動產生的原始碼:

夾雜許多用途不明的東西,而且 bp.blogspot.com 這樣的鏈結會讓某些 lightbox 特效掛掉。 (2009-05-19: 後來發現 lightbox 掛掉其實是鏈結中「-h」禁止外連造成的。
所以我做了一支 bookmarklet 把它清理成下面的格式:

將 bookmarklet 加進書籤 → 清理 blogger 插入的圖片標籤
在文章編輯器的「修改 Html」模式點了就立刻執行,不會多問,所以請自己保重(文章弄壞、Ctrl + Z 又沒用的話,我也沒辦法負責啊。)

原始碼拆解如下:

javascript:
document.getElementById(&apos;textarea&apos;).value = document.getElementById(&apos;textarea&apos;).value.replace(
  /<a onblur=\".+\" href=\"(.+)\"><img style=\".+\" src=\"http:\/\/(\d)+\.bp\.blogspot\.com\/(.+)" border=\"0\" alt=\"\"id=\".+\" \/><\/a>/g,
  function(str, p1, p2, p3) {
    return &apos;<a href="http://lh&apos; + (parseInt(p2)+2) + &apos;.ggpht.com\/&apos; + p3.replace(/s(\d)+(-h)?\//,&apos;&apos;) + &apos;"><img src="http://lh&apos; + (parseInt(p2)+2) + &apos;.ggpht.com\/&apos; + p3 + &apos;" alt="" /></a>\n&apos;;
  }
);void 1
Known Issues .blogspot

幾乎所有 blogger.com 的 blog 送交 W3C Markup Validator 都能驗出錯誤,其中很多是 blogger 自動產生的原始碼,想改也改不掉。

這個問題至少 2006 年起就有人在 Blogger Help Group 留言或寄信反應,但是官方一直沒修正,儘管問題看起來好像很簡單——以此 blog 來說,只剩下新/舊文章連結的 & 要改成 &amp;、留言內容的標籤名稱要改成小寫,兩個地方而已。

當然 invalid 未必有什麼毒害,只是 Google 擺著幾個小問題(假設是小問題)不管以致無法通過檢驗,教人煩悶。

回報方式除了 Blogger Help Group 外,說明中心有個 Wishlist,另好像也有 Contacting Support 不過我找不到信箱位址……根據論壇使用者說法,官方回信這問題被歸為「低優先性」所以進展較慢。至於有多慢呢?至少在 Known Issues for Blogger 還找不到,可見 valid XHTML 真是沒有普遍需求的東西啊。

唉~沒有相機,只能貼擷圖

Blogger in Draft 的新裝備 Embedded Comment Form(中文版很擰巴地譯為已內嵌下列文章)隱藏了「以電子郵件傳送後續意見」和「預覽」等舊功能,恐有干擾使用習慣之慮。

在 blogger 變更規格前,暫且自行插入「彈出留言視窗」鏈結吧,如圖中傘形符號,點下去就會另開視窗。

以下具體說明,需要表單已內嵌才適用:(別忘了備份模版以防萬一)

手動插入「彈出留言視窗」鏈結

在模版中找到 <b:includable id='comment-form' var='post'> ……(中略) </b:includable> 一段,裡面會有 <h3><data:postCommentMsg/></h3>,該 h3 就是內嵌表單上方的「張貼意見」幾個字。接著插一行鏈結的原始碼進去,變成:

<h3>
  <data:postCommentMsg/>
  <a class="comment-link" title="彈出留言視窗" expr:href='&quot;http://www.blogger.com/comment.g?blogID=把我改掉&amp;amp;postID=&amp;quot; + data:post.id + &quot;&amp;amp;isPopup=true&quot;' onclick='javascript:window.open(this.href, &quot;bloggerPopup&quot;, &quot;toolbar=0,location=0,statusbar=1,menubar=0,scrollbars=yes,resizable=yes,width=400,height=740&quot;); return false;'>彈出視窗</a>
</h3>

其中 blogID(把我改掉)要改成自己的 blog 號碼,有疑問請參考官方說明 我的 Blog ID 號碼是多少?
其餘文字和 width 什麼的參數比較不重要,可以視需要修改。

至此就完成了…… 其實「內嵌」與「彈出視窗」應該可以共存才對,沿用彈出視窗的模板 <a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'>彈出視窗</a> 也比較單純,不過目前這樣寫 data 都沒東西,似乎跟「表單已內嵌」相衝的樣子。

ie6 有時可以看到驗證碼 Opera 上的樣子

2008-07-01:不需要自己亂改了,Blogger in draft 已提供 Embedded comment form 來做這件事。中文改造法可參考 小Ken思路不轉彎: [Blogger in draft] 新功能:Embedded Comment Form和Star Ratings安裝
我的情形是在後台設定意見表單位置,然後找地方插入 <b:include data='post' name='comment-form'/> 就差不多了。

偶然逛到一個 blog: fREE2Software 發現他的留言表單就直接擺在頁面下方(首頁沒放,單篇文章才有),這配置我在 google 上找了很久都沒見過,現在才看到活生生、還會跑的。立刻看了他 blogger hack 分類下的文章,可惜暫時沒有寫到,於是自己試做,結果摘要:

  1. 寫成一般的 JavaScript,用修改模板的方式套用。
  2. 使用流程:按下留言按鈕後,才在頁面上顯示留言表單(iframe)。
  3. 未解決問題:ie 有時候看不到「視覺驗證」圖片。
  4. Firefox 頁面未完全載入時,開出來的 iframe 內容不保證正確。要修正的話,可以等頁面完全載入再用 JavaScript 改留言按鈕的 onclick 屬性。
  5. 表單還是很醜怪…… 所以我最後還是沒用它

試用方式:

  1. 在模板的 </header> 前面加上:
    <script type='text/javascript'><!--
      var iframeHereHeight = '210px';   // iframe 高度
      function tryCommentHere(a,href) {
        // 若已有 iframe, 只做展開/收合
        if( a.nextSibling && a.nextSibling.nodeName.toLowerCase()=='iframe' && a.nextSibling.src==href ) {
          if( a.nextSibling.style.display != 'none'  ) {
            a.nextSibling.style.display = 'none';
          }
          else {
            a.nextSibling.style.display = 'block';
          }
          return;
        }
        // 若沒有 iframe, 建立新的 iframe
        var newIframeNode = document.createElement('iframe');
        newIframeNode.setAttribute('src', href);
        newIframeNode.setAttribute('style', 'display:"block";');
        newIframeNode.setAttribute('margin', 'auto');
        newIframeNode.setAttribute('width', '90%');
        newIframeNode.setAttribute('height', iframeHereHeight);
        newIframeNode.setAttribute('frameborder', '1');
        newIframeNode.setAttribute('scrolling', 'auto');
      if( !a.nextSibling ) { a.parentNode.appendChild(newIframeNode); }
      else {
        a.parentNode.insertBefore( newIframeNode, a.nextSibling );
      }
    };
    //--></script>
  2. 然後找到「留下意見」連結的標記,類似 <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'>留下意見</a>,把 onclick 內容改為 onclick="tryCommentHere(this, this.href); return false;" 就行了。

初嘗 blogger

生食 blogger

blogger 吃起來像陽春的自助餐,申請帳號就能得到一個托盤,接著開始找不著地方揀菜;或者找到餐台,卻發現食材都是生的 ——很有彈性。

以上就是我初試 blogger 的感覺,為了弄出想要的功能,總要面對一連串問題;以下記錄幾個做過的調整,以及修改時的考量。


  1. JavaScript Library

    有個 jQueryPrototype 為基礎,寫 JavaScript 的工作會變得很快樂。
    理想作法是跟隨阿土伯發展的 blogger-ext2,裡面就包含了短小精幹的 jQuery,也不必重寫一些基本的功能,更別說 blogger-ext2 的設計本身就值得我們學習。

    不過很可惜我沒用過 jQuery!所以還是選比較熟悉但很龐大的 Prototype (122 kb) 和 script.aculo.us。(上面的精美圖片約 30 kb,可見 Prototype 有多大。)

  2. 繼續閱讀

    官方作法是用 <span class="fullpost">全文</span><div class="fullpost">全文</div> 配合範本和 CSS 讓裡面的內容在首頁不顯示。

    而一般作法是用 JavaScript 找出要隱藏的部份,建立一個開關來收合/展開,可參考 CJH繼續閱讀懶人加強版。我也是依循此想法,因為無論怎麼做,文章都是完整下載到瀏覽器了,沒特殊需求的話應該不必把它藏起來。

    另外看過最有趣的是 blogger-ext2 用的 ##CONTINUE## 標記,真是有夠懶。

  3. 最新回應

    簡單作法是在範本中加入一個資訊提供 ( feed ) 元素,網址為
    http://你的blog.blogspot.com/feeds/comments/summary,但是這樣最多只能顯示 5 則留言,而且內容不會即時更新,實用性低迷。(我用的就是此方式。)

    另一方法是用 JavaScript 取得前述網址傳回的 JSON 物件,可取得 99 則最新的留言,但是有個共同難題—— Feed 裡頭沒有「文章標題」的資料,所以無法知道該留言是回應哪一篇文章,這對訪客來說是不方便的。如果還記得前言中的自助餐譬喻,這個 feed 就可比為沒清乾淨的大腸。

    有個確實解法在 LVCHEN 製作的 Recent Comment Widget for Blogger,做法看來是另外取得文章的 feed(內有標題)再跟回應的 feed 比對,解出文章標題。原以為這樣很沒效率,不過實際上看起來都很快。

    至於選擇陽春做法的原因,因為 blogger 提供的 feed 不但缺少文章標題,同時沒有留言者網址,也無法取得「已被刪除」的留言。離我想做的有段距離,乾脆不去解它了。

  4. 留言的重新導向

    沒辦法在文章下面直接留言(而必須進入另一個頁面),可參考 blogger 關於連結透過 google.com 和 blogger.com 重新導向的說明。看來只能忍受那個無法改樣式的留言表單了…… 這裡可自訂比較有影響的是「設定 -意見 - 在彈出式視窗中顯示意見」,我把它改成彈出視窗,至少防止訪客被導向到風格不同的表單而受驚。

  5. 較舊/較新的文章 的 XHR 讀取

    按下「較舊的文章」後 blogger 預設會使用 XHR 的方式讀取文章,不必重讀整個頁面,很棒的功能,不過沒有照顧到瀏覽器的上一頁/下一頁。當一個 blog 只有「較舊的文章」採用 XHR,其他部份卻是傳統連結的時候,可能會造成困惑。

    對這般上一頁/下一頁問題已有許多解法,我試著引進 Brad NeubergReally Simple History 但很快就放棄了…… 所以還是選擇沒有 XHR 的方式,關掉它的方法是將範本中

    <b:if cond="data:newerPageUrl">
      <a expr:id="data:widget.instanceId + '_blog-pager-newer-link'" expr:href="data:newerPageUrl">
        <data:newerpagetitle></data:newerpagetitle>
      </a>
    </b:if>
    <b:if cond="data:olderPageUrl">
      <a expr:id="data:widget.instanceId + '_blog-pager-older-link'" expr:href="data:olderPageUrl">
        <data:olderpagetitle></data:olderpagetitle>
      </a>
    </b:if>
    兩個 <a> 標籤的 id 改掉,例如 expr:id='"no_" + data:widget.instanceId + "_blog-pager-newer-link"' 讓 blogger 找不到它們即可。