
ファイルを添付という形で、画像も付けておくか。
ppBlog Warning: LINE 1117 of utils.php: preg_match(): The /e modifier is no longer supported, use preg_replace_callback instead
2008/8/5
ファイルを添付という形で、画像も付けておくか。
— posted by martin at 08:24 pm
Comment [0]
TrackBack [0]
2008/8/3
こんばんは。ppBlogでは、代表的なソーシャルブックマーク(SBM)の被リンク数を記事ごとに表示できる機能が付いていますが、いくつか古いAPIを用いていて、きちんとブックマーク数が取得出来ていないものもありました。なので最新のものを調べたのでメモがてら。
ppBlogで初めから用意しているSBMは、はてなブックマーク、del.icio.us、livedoorクリップ、Buzzurl(バザール)、Yahoo!ブックマークの5つです。グーグルも付けてはいますが(登録用のアイコン表示のみ)、グーグルには被リンク数を表示するAPIがないみたいなので、今回はスルーします。
以前は、被リンク数を取得するAPIとして、画像での提供のみのところもあったと思いますが、今では、この5つのどれもがJSON形式GあるいはXML形式での情報取得に対応しているので、幾分扱いやすくなっています。個別に見ていきましょう。各々、JSON(XML)へのリンクおよびカウンター値の形式を挙げています。カウンターの値は、正規表現などを用いて簡単に取り出せます。
補足しておくと、最後の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ブックマーク では、自分の知る限り、画像でのみ被リンク数の取得が可能です。この場合は、どうしたら数字を文字列として取り出せるでしょうか?
画像で提供しているところでは、たいてい数字を出力する画像ファイルにリダイレクトさせるという手段を講じているので、このリダイレクト先のURLを知ることが出来れば、文字列として取得可能です。PHPを使いたい場合、どうやるか? FC2を具体例に挙げると、画像カウンター取得URLは以下で与えられます。
http://bookmark.fc2.com/image/users/(取得したいURL)
まず、最初に考えるのは、とりあえず、PHP組み込み関数のfile_get_contents()関数 を用いて、出力してみること。
<?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() 関数を使いましょう。この関数を使うことで、まずサーバーが返す情報配列を得ることができて、それを解析すれば、リダイレクト先の情報もゲットできます。この場合は、以下のような配列を返します(一部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()関数の中身が変わっています。
— posted by martin at 09:59 am
Comment [0]
TrackBack [1]
2008/7/26
カテゴリー » 開発日誌 » JavaScript
日本を出る前後、昨年の9月頃から、このページでグーグルのAdsenseを利用しています。使いこなしていないせいか、広告収入が100$に達するのに、あと数年はかかりそうなペースです。さて、この広告表示は、JavaScriptのdocument.writeを使ってインラインフレーム(IFRAME)で書き出すということをしています。前回のエントリーで使用しているBLOCKQUOTEのボーダー枠を演出するJavaScriptの実行タイミングが遅いなと感じていたんですが、原因は、このdocument.writeの存在でした。ちょうど2年前に、これに関するエントリー (document.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; /* 上と同様に */ }
ちなみに、このサイトのwebRing は、「ページ作成機能」を使って作っていますが、表示スクリプトはBlogPeopleさん
のを利用しています。ここでも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
Comment [0]
TrackBack [0]
以前、ユーザーの方からのコメントで以下のような要望がありました。
2.アクセス解析の「リンク元」統計へのURL置換機能の実装
私が使っていたことのあるアクセス解析サービスにあった機能なのですが…… どういう機能かというと、登録してある文字列を含むアドレスを一つのリンク元として扱うようなものです。例えばgoogle.co.jpと登録しておけば、グーグルからのアクセスを全部まとめて何件、と表示します。 というのも、検索エンジンからのアクセス自体は別項目で詳しく見れますし、「リンク元」項目では逆に検索エンジンからのアドレス文字列が大量に羅列しているため一般サイトなどからのアクセスが判別しにくいという現状がありまして要望させていただきました。
これは、ごもっともな意見であるので、実装してみました。従来の「リンク元」の画面が、少し変わって、ドメインの部分がクリック出来るようになっています。クリックすると、ドメインをまとめたいか?と訊ねてくるので、「OK」ボタンを押すと、選んだドメインはまとめて集計するようになります。こうやって、いくらでもドメイン毎にまとめることが可能です。現状、登録のみで削除とかは、直接設定ファイル(stat/data/replace.ini.php)を弄るしかありませんが、まぁこれで良いかなと思います。
これを使って、このサイトのリンク元の主要なドメインを纏(まと)めてみました。検索エンジンのドメインがひとくくりに集計されるので、それ以外のマイナーなサイトからのリンクが見つけやすくなりました。
これを適用するためのファイルを添付しておきます。なお、従来のアクセス解析画面では、ページの一番下に[AdminTop]とか[BlogTop]とか付いていて、正直、使い辛いなと思ったので(インターフェイスも洗練されていない)、アイコン化して、ページの左上に固定表示させました(IE6にも対応)。そのためのアイコンやらCSSファイルも同梱してます。アイコンは、stat/iconディレクトリに入れて下さい。view.php, stat.cssは既存のものを上書き(いずれもstatディレクトリの中です)して下さい。ppBlogのバージョンは、最新でなくても1.6系以上(1.5系も?)であれば大丈夫だと思います。念のため、元のview.phpは保持しておくのがベターですが。
ご指摘があれば、どうぞ。「登録したら、もはやリンク表示にしなくていいんじゃない?」 とか。←2008-07-26 03:02:56 そうしました。
— posted by martin at 05:25 am
Comment [4]
TrackBack [0]
2008/7/25
こんばんは。この週末は時間が取れそうなので、マイナーアップデートを予定しています。さて、自分のブログを書いていて、不便に思ったところを改善してみたのでメモ。
この旅日記 のようにページ数が10ページとかなると、記事の編集時には、テキストエリアが縦にずらっと10個並ぶわけです。で、修正したいページのテキストエリアにたどり着くのに、ちょっと間を取られるので、(ログインモードで表示される)編集アイコンをクリックしたら、直接、表示しているページのテキストエリアにフォーカスが行き、かつ、その他のテキストエリアは、縮めた状態で表示させるようにしてみました。修正は、jsファイルのみで済みます。
記事の各ページはAjaxを利用して、該当ページの部分のみ動的に読み込んでいるので、ログイン中に記事タイトルの右横に表示される編集アイコンのリンクは、最初のページのままで変わりません。なので、記事ページを読み込んだタイミングで、この編集アイコンのリンクも書き換えるようにします。これはlib.jsのloadPage()をいじります。簡単でして、
if(o('a[href*=edit]', ownerDiv)){ o('a[href*=edit]', ownerDiv).each(function(a){a.href = (a.href.replace(/&?page=¥d+$/, '') + "&page=" + page);}); }
というのを追加するだけです。やってることは、記事DIV要素の中で、リンク先にeditを含むA要素を探し出して(これは2つあります)、それぞれのリンクhrefに表示しているページを追加してあげる、という単純なものです。
次に、editor.jsの方をいじります。この中のInitEditor()関数の最後の方に、以下のやつを追加。
var targetPage = /page=(¥d+)$/.exec(location.href); if(targetPage){ o('textarea[id^=Page]').each(function(page, index){ if(index + 1 == targetPage[1]){ resizeTextArea(page); ed = page; ed.focus(); o('#Page'+targetPage[1]+'Tab').view(1); } else o(page).css('height: 20px;'); }); }
やってることは、記事編集画面でのリンク先がpage=3とかで終わっていたら、該当する3番目のテキストエリアのみを適切な縦幅で表示させて(フォーカスも合わせる)、他のテキストエリアは縦幅20ピクセルに縮めておく、ということです。
尚、各テキストエリアの高さは、それぞれのリサイズバーをマウスでドラッグすることで自由に変えることが出来ますが、昔のマックのウィンドウシェード(MacOSXでも残っているのかな?)みたいに、ダブルクリックでトグルさせるようにするには、やはりInitEditor()関数の中に、次の記述を追加します。
o('.textareaHandler').on('dblclick', function(){ var tar = oParts.target().sib(-1); /* リサイズバーのひとつ前の要素、つまりテキストエリア要素を取得 */ if(tar.css('height') == 20) resizeTextArea(tar.$); else tar.css('height: 20px'); });
自分でいじりながら、JSファイルの修正だけで実現できたのは、ちょっと意外だったり この修正を施したjsファイルを添付しておきます。特に問題がなければ、次回アップデートに反映されるでしょう。
— posted by martin at 10:42 am
Comment [0]
TrackBack [0]
Comments