ppBlog Warning: LINE 1117 of utils.php: preg_match(): The /e modifier is no longer supported, use preg_replace_callback instead

ppBlog official

[ カテゴリー » 開発日誌 ]

チェックボックスを一度に複数選択したい

category-icon

 こんばんは。イベントに関するJavaScriptの話をば。

 ppBlogでは、管理画面で記事の削除やコメントの削除が出来ますが、現状、ひとつずつしか削除できません。削除したいものが沢山あるときは大変なので(あまりそういう機会はないと思うけれど)、次回アップデート版では、チェックボックスでチェックした複数の記事などを1度に削除出来るようにする予定です。実際のスクリーンショットは以下。

shot1
開発版ですよ

 チェックボックスをチェックする操作というのは、数が少ない内は良いけど、数が多くなるとマウスで逐一クリックしていくのが億劫になります。なので、シフトキー(SHIFT)を活用できるようにします。つまり、最初の方のチェックボックスをチェックしておいて、シフトキーを押した状態で、下の方のチェックボックスをクリックすると、その間のチェックボックスも自動的にチェックされた状態になるというものです。この手のインターフェイスはよく使われていて、例えば、Gメールでも、そういう操作が可能です。以下に実際のデモを載せておきます(下のデモはスクリーンショットじゃなくて、ちゃんと操作できますよ)。

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
選択: すべて  なし

 さて、この手のことを実装するには、シフトキー(SHIFT)が押された状態というのをJavaScriptで検知する必要があります。最初は、

var shift, e = oParts.evt, k = e.keyCode ? e.keyCode : e.which;
shift = e.shiftKey ? e.shiftKey : (k == 16 ? true : false);
if(shift){ // シフトキーが押されていれば

なんてのを思いつきましたが、キーボードイベントは、以前の知識しかないなぁ、と思って、新しい情報をwebで探してみました。したら、えらく新しいのがありました(今年七夕の記事です:))。

 JavaScript Madness: Keyboard EventsLink

 もはや、event.whichなんてのは不要で、event.keyCodeでこと足りるんですね。しかも、どのブラウザでも、event.shiftKeyを認識してくれそうです。なので、最終的には、この部分は、

if(oParts.evt.shiftKey){ // シフトキーが押されていれば

と非常に短く記述することが出来ますね。ppBlog向けの、上に上げたデモのソースコードを載せておきます。

o(document).on("click", function(){ // Event delegation
  var tar = oParts.evt.target; 
  if(tar.nodeName.toLowerCase() == "input" && tar.type.toLowerCase() == "checkbox"){
   var tr = tar.parentNode.parentNode;
   if(tar.checked == false){
    tr.style.backgroundColor = (tr.rowIndex % 2 == 0) ? "#eff1f3" : "#fff";
   } else tr.style.backgroundColor = "highlight";
   if(oParts.evt.shiftKey){
    var i = tr.rowIndex - 1, item, cb = o("td > input[type=checkbox]");
    for(i; i > 0; i--){
     item = cb.item(i).$;
     if(item.checked == true) break;
     item.checked = true;     
     item.parentNode.parentNode.style.backgroundColor = "highlight";
    }
   }
  }
 });

function resetAll(){ // すべてのチェックボックスを解除する
 o("td > input[type=checkbox]").each(function(e, i){
  if(e.checked){
   e.checked = false;
   e.parentNode.parentNode.style.backgroundColor = (i % 2 == 0) ? "#eff1f3" : "#fff";
  }
 });
}

function setAll(){ // すべて選択する
 o("td > input[type=checkbox]").each(function(e){
  e.checked = true;
  e.parentNode.parentNode.style.backgroundColor = "highlight";
 });
}

 ppBlogでは、多くのマウスイベント処理がありますが、ほとんどはEvent DelegationGを 活用しています。上のデモでも、チェックボックス1つひとつにイベントを登録していくのではなくて、クリックされた要素がチェックボックスであれば・・・、という捉え方をしています。イベントは、バブリング(伝達)していくものなので、最上位要素でモニターして、そのターゲットさえ掴めれば良いというわけです。

 Event Delegation versus Event HandlingLink  

— posted by martin at 06:34 am   commentComment [0]  pingTrackBack [0]

 

Gメールからのモブログテスト

category-icon

300(W)×225(H) 18.4

 ケータイからのモブログは、ここフランスでは、よく調べていないので現状無理だけど、モブログでの挙動を調べる必要があったので、Gメールをケータイに見立てて、モブログのテスト。自動投稿モードです。

 ファイルを添付という形で、画像も付けておくか。

— posted by martin at 08:24 pm   commentComment [0]  pingTrackBack [0]

ソーシャルブックマークでの被リンク数を取得する最新APIまとめ

category-icon

 こんばんは。ppBlogでは、代表的なソーシャルブックマーク(SBM)の被リンク数を記事ごとに表示できる機能が付いていますが、いくつか古いAPIを用いていて、きちんとブックマーク数が取得出来ていないものもありました。なので最新のものを調べたのでメモがてら。

 ppBlogで初めから用意しているSBMは、はてなブックマークdel.icio.uslivedoorクリップBuzzurl(バザール)、Yahoo!ブックマークの5つです。グーグルも付けてはいますが(登録用のアイコン表示のみ)、グーグルには被リンク数を表示するAPIがないみたいなので、今回はスルーします。

 以前は、被リンク数を取得するAPIとして、画像での提供のみのところもあったと思いますが、今では、この5つのどれもがJSON形式GあるいはXML形式での情報取得に対応しているので、幾分扱いやすくなっています。個別に見ていきましょう。各々、JSON(XML)へのリンクおよびカウンター値の形式を挙げています。カウンターの値は、正規表現などを用いて簡単に取り出せます。

はてなブックマークLink
http://b.hatena.ne.jp/entry/json/?url=(エンコードしたURL)
JSONでのカウンター取得値:"count":"(¥d+)"
del.icio.usLink
http://badges.del.icio.us/feeds/json/url/blogbadge?hash=(md5ハッシュ化したURL)
JSONでのカウンター取得値:"total_posts":"(¥d+)"
livedoorクリップLink
http://api.clip.livedoor.com/json/comments?link=(エンコードしたURL)
JSONでのカウンター取得値:"total_clip_count":(¥d+),
Buzzurl(バザール)Link
http://api.buzzurl.jp/api/counter/v1/json?url=(エンコードしたURL)
JSONでのカウンター取得値:"users":(¥d+),
Yahoo!ブックマークLink
http://num.bookmarks.yahoo.co.jp/yjnostb.php?urls=(エンコードしたURL)
XMLでのカウンター取得値:ct="(¥d+)"

 補足しておくと、最後のYahooでの指定ではJSONではなく、以下のようなXMLを返します。直接、カウント数を取得することが出来ます。

<?xml version="1.0" encoding="utf-8" ?>
<results>
<SAVE_COUNT u="http%3A%2F%2Fp2b.jp%2Findex.php%3FUID%3D1188848148" ct="6" />
</results>

 先ほど述べたように、カウント数は、JSON形式や、XML形式で取得できるので、さらにそれをパースして・・・とやっても良いでしょうが、ここはPHPの正規表現のみで簡単に取り出せるので、それで十分でしょう。

 さて、上記で挙げたSBMサービスでは、このようにJSONといった文字列でカウンターを取得できますが、他のSBMサービスによっては、画像カウンターでしか取得できないところもあります。例えば、FC2ブックマークLink では、自分の知る限り、画像でのみ被リンク数の取得が可能です。この場合は、どうしたら数字を文字列として取り出せるでしょうか?

 画像で提供しているところでは、たいてい数字を出力する画像ファイルにリダイレクトさせるという手段を講じているので、このリダイレクト先のURLを知ることが出来れば、文字列として取得可能です。PHPを使いたい場合、どうやるか? FC2を具体例に挙げると、画像カウンター取得URLは以下で与えられます。

http://bookmark.fc2.com/image/users/(取得したいURL)

まず、最初に考えるのは、とりあえず、PHP組み込み関数のfile_get_contents()関数Link を用いて、出力してみること。

<?php
$url = 'http://bookmark.fc2.com/image/users/http://p2b.jp/index.php?UID=1188848148';
echo file_get_contents($url); // とにかく書き出してみる
?>

結果は、まぁ当たり前ですが、リダイレクトされた後のPNG画像(ヘッダーを正しく出力していないので文字化けするけど)が出力されます。リダイレクト後のURLは、この場合、被リンク数がゼロなので(--)

http://bookmark.fc2.com/icons/00000.png

となっています。この00000.pngの部分を取り出すことが出来ればよいわけです。PHPには、最初から色々便利な関数が準備されているので、それを利用します。ここでは、stream_get_meta_data()Link 関数を使いましょう。この関数を使うことで、まずサーバーが返す情報配列を得ることができて、それを解析すれば、リダイレクト先の情報もゲットできます。この場合は、以下のような配列を返します(一部Xの文字で情報を隠しています)。

Array
(
    [wrapper_data] => Array
        (
            [0] => HTTP/1.1 302 Found /* 多くのクライアントは、このステータスコードをリダイレクトと解釈する */
            [1] => Date: Sun, 03 Aug 2008 00:19:03 GMT
            [2] => Server: XXXXXXXXXXXXXXXXXXXXXXXXXX
            [3] => X-Powered-By: XXXXXXXXXXXXX
            [4] => Set-Cookie: CAKEPHP=XXXXXXXXXXXXXXXXXXXXX; path=/
            [5] => P3P: CP="XXXXXXXXXXXXXX"
            [6] => Location: http://bookmark.fc2.com/icons/00000.png /* リダイレクト先 */
            [7] => Content-Length: 0
            [8] => Connection: close
            [9] => Content-Type: text/html
            [10] => Content-Language: en
            [11] => HTTP/1.1 200 OK
            [12] => Date: Sun, 03 Aug 2008 00:19:03 GMT
            [13] => Server: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
            [14] => Last-Modified: Fri, 25 Aug 2006 09:03:28 GMT
            [15] => ETag: "XXXXXXXXXXXXXX"
            [16] => Accept-Ranges: bytes
            [17] => Content-Length: 90
            [18] => Connection: close
            [19] => Content-Type: image/png
            [20] => Content-Language: en
        )

    [wrapper_type] => http
    [stream_type] => tcp_socket
    [mode] => r+
    [unread_bytes] => 90
    [seekable] => 
    [uri] => http://bookmark.fc2.com/image/users/http://p2b.jp/index.php?UID=1188848148
    [timed_out] => 
    [blocked] => 1
    [eof] => 
)

wrapper_dataというキーの値が更に配列になっていて、その中のLocation:という文字列がある行を探し出せばOKです。具体的には以下のような記述になるでしょう。

$url = 'http://bookmark.fc2.com/image/users/http://p2b.jp/index.php?UID=1188848148';

if($fp = @fopen($url, 'r')){
 $meta = stream_get_meta_data($fp);
 foreach($meta['wrapper_data'] as $r) {
  if(substr(strtolower($r), 0, 9) == 'location:') {
   $count = preg_replace('{^.+/(¥d+)¥.(?:png|gif)$}', '¥¥1', $r); /* 画像カウンタはほぼPNGかGIFファイル */
   break;
  }
 }
 $count = sprintf('%d', "$count");
} else $count = 0;

 最新版のutils.phpでは、この画像カウントのものは採用していませんが、この記述を組み込めば、画像カウンターからの取得も可能ですね。

 一応、これを反映させた最新版のutils.phpを添付しておきます。1895行目からのsocialBookmark()関数の中身が変わっています。

添付ファイル: utils.phpattachedIcon 

— posted by martin at 09:59 am   commentComment [0]  pingTrackBack [1]

Google Adsenseの表示タイミングを制御する

category-icon

 日本を出る前後、昨年の9月頃から、このページでグーグルのAdsenseを利用しています。使いこなしていないせいか、広告収入が100$に達するのに、あと数年はかかりそうなペースです。さて、この広告表示は、JavaScriptのdocument.writeを使ってインラインフレーム(IFRAME)で書き出すということをしています。前回のエントリーで使用しているBLOCKQUOTEのボーダー枠を演出するJavaScriptの実行タイミングが遅いなと感じていたんですが、原因は、このdocument.writeの存在でした。ちょうど2年前に、これに関するエントリーLinkdocument.write()の実行タイミングをずらす方法)を書いていたのを思い出し、早速、このサイトにも適用させてみました。

 効果はてきめんで、先にBLOCKQUOTEの装飾が終わり、その後、Google Adsenseが表示されるようになりました。ppBlogでは、DOMの構築が終わるタイミングで実行されるJavaScriptが多いので(これはドキュメントの読み込み完了前に実行される)、document.write()に起因する描画遅延対策は大切ですね。

 具体的に行った対処法は、シンプルです。テーマのtemplate.phpを弄ります。このサイトのベーシックなテーマでは、左側のカラム(サイドバー)にGoogle Adsense用のDIVタグ(IDはgoogle-ads)を用意してます。

<div id="google-ads">
 /* この中にグーグルからの広告用javascriptを貼り付けている */
</div><!--#google_ads-->

で、この中身を以下のようにします。既存のグーグルのコードをいじることはないです。

<div id="google-ads">
 <script type="text/javascript">
  (function (){
   var alts = [];
   d._write = d.write;    /* オリジナルのdocument.writeをコピーしておく */
   d.write = function(s){ alts.push(s);};  /* 新たにdocument.writeを定義。ここでは、単に配列に入れるだけ */
   oParts.start(function(){  /* DOM構築完了のタイミングで実行されるように登録する */
    o("#google-ads").html(alts.join("")); /* 配列に入れた本来のdocument.writeの中身を書き出す */
    d.write = d._write;   /* オリジナルのdocument.writeに戻す */
   });
  })();
 </script>
   /* 以下、既存のコード */
 <script type="text/javascript"><!--
   google_ad_client = "pub-XXXXXXXXXXXX";
   google_ad_slot = "XXXXXXXX";
   google_ad_width = 180;       /* 広告の幅 */
   google_ad_height = 150;     /* 広告の高さ */
 //--></script>
 <script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
 </div><!--#google_ads-->

 基本的には、これでOKです。後は、予め広告のサイズが分かっているので、見栄えとしてCSSファイルを少しいじるだけです。このサイトでは以下のように指定しています。

#google-ads { 
  margin: 70px auto 0 10px;
  padding: 0;
  width: 180px;    /* 広告の幅に合わせる */
  height: 150px;   /* 上と同様に */
}

 ちなみに、このサイトのwebRingLink は、「ページ作成機能」を使って作っていますが、表示スクリプトはBlogPeopleさんLink のを利用しています。ここでもdocument.writeが使われているので、それに対処した記述をしています。その中身をさらしておきます。

<div class="center" style="color:#2f4f4f;">
<h2>ppBlog's webRing</h2>
<p style="padding:1em;font-size:14px;width:300px;margin:auto;">
ppBlog使いの方々です。随時募集中。
<br />多分に見落としなどもあると思いますので,このサイトもお願いしますというのがあれば
気兼ねにメール下さい。自薦他薦問いません。</p>
<div id="_webRing" style="margin: 2em auto;width:300px;text-align:left;"></div>
  /* ここから */
<script type="text/javascript">
 (function (){
   var alts = [];
   d._write = d.write;
   d.write = function(s){ alts.push(s);}
   oParts.start(function(){
    o("#_webRing").html(alts.join(""));  /* 上で用意した DIV#_webRing に流し込む */
    d.write = d._write;
   });
  })();
</script>
  /* ここまでがポイント */
<script type="text/javascript" charset="utf-8"
 src="http://www.blogpeople.net/display/usr/0f0d40535b5b4103.js"></script>
</div>

 

— posted by martin at 11:08 pm   commentComment [0]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0049 sec.
prev
2021.4
next
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30