Home

日記
おまけ: はてなダイアリー風のTrackBack受信確認を行う (17:35)Edit

自分で作るblogツール(PHP編)』のおまけ記事として、『はてなダイアリー風のTrackBack受信確認を行う』を追加しました。

Published At2005-04-01 00:00Updated At2005-04-01 00:00

日記
tDiaryのPHP版を作成しました (18:07)Edit

(念のため、これは4月1日の記事ですからねー)

データはtDiary互換となっており、現在ここのデータをそのまま使用しているβ版サイトを、http://pdiary.ishinao.net/index.phpで動作させています。URLからわかるようにpDiaryと名づけました。

tDiary: 2.1系に先駆けて、

  • フルUTF-8化!(β版サイトの文字コードを確認してください)
  • Rubyで書かれたtDiaryプラグインがそのまま動作!

などの特徴があります。

現在記法はWikiスタイルのみサポートしており、そのレンダリングエンジンにはPHP用汎用WikiParserを利用しています。

まだすべての機能が実装されていませんが、β版のソースコードはこちらからダウンロードできます。是非おためしください。

どうも上のダウンロードリンクがおかしいようなので

ソースを貼り付けておきます。

<?php
$url = 'http://tdiary.ishinao.net/index.rb?'.$_SERVER['QUERY_STRING'];
$html = file_get_contents($url);
$html = str_replace('tdiary.ishinao.net', 'pdiary.ishinao.net', $html);
$html = preg_replace('/\.\/([0-9]+)\.html/', './index.php?date=$1', $html);
$html = str_replace('"./?', '"./index.php?', $html);
$html = str_replace('ツッコミを入れる', 'ツッコミは入れれない', $html);
$html = str_replace('"投稿"', '"投稿できない"', $html);
$html = str_replace('<a href="http://www.tdiary.org/">tDiary</a> version 2.0.0', '<a href="http://pdiary.ishinao.net/index.php">pDiary</a> version 0.0.1', $html);
$html = str_replace('<a href="http://www.ruby-lang.org/">Ruby</a> version 1.8.1', '<a href="http://www.php.net/">PHP</a> version 4.3.10', $html);
$html = str_replace('euc-jp', 'utf-8', $html);
$html = mb_convert_encoding($html, 'utf-8', 'euc-jp');
header('content-type: text/html; charset=utf-8');
echo $html;
?>

Published At2005-04-01 00:00Updated At2005-04-01 00:00

日記
おまけ: はてなダイアリー風のTrackBack受信確認を行うEdit

最近TrackBack SPAMが増えてきているので、TrackBack SPAM対策としてはてなダイアリー風のTrackBack SPAM対策を実装してみる。

はてなダイアリー風のTrackBack SPAM対策とは、TrackBackが送られてきたら、TrackBack PingのURLパラメータで表される送信元URLのHTMLドキュメントを取得し、そのHTML中にTrackBack送信先(自サイトの)URLが含まれているかどうかを確認。送信先URLがHTML中に含まれない場合は、(記事中に言及されていない=SPAMの疑いが強い、として)TrackBackの受信を拒否する、という仕組みだ。

ただし今回は、HTMLドキュメントに送信先URLが含まれなかった場合も、TrackBackの受信を拒否するのではなく、非表示指定(削除フラグON)にしたTrackBackを受信することにする。そうしておくことで、もしも送信先URLが含まれていないが正当なTrackBackであったり、あるいは実際には送信先URLが含まれているのに解析に失敗した場合などに、削除フラグを無効にするだけで表示させることができる。

また、せっかくだから検索エンジン対策として導入されつつあるrel="nofollow"属性にも対応しておこう。HTMLドキュメント中のリンクタグ(<a href="~">)にrel="nofollow"属性を付与しておくと、そのリンクは主要な検索エンジンではPageRank的な評価(たくさんのサイトにリンクされているサイトほど、検索エンジンで検索した際に上位に出てきやすい)の対象に含めないようになり、TrackBack SPAMの効果を減らすことができるとされている。

/lib/trackbacklib.php

<?php
(省略)

function
add_trackback_data($trackback_data) {
    (
省略)

    
$now = time();  //投稿日時
    
$deleted = is_trackbacked_url_linked($filename, $trackback_data['url']) ? 0 : 1;   //削除フラグ

    
(省略)
}

// trackback送信元HTMLに、受信先URLが含まれるかを確認
function is_trackbacked_url_linked($filename, $trackbacked_url)
{
    
$my_url = BLOG_ROOT_URL.'entry.php/'.$filename;
    
$trackbacked_html = file_get_contents($trackbacked_url);
    if (
preg_match('/'.preg_quote($my_url, '/').'/', $trackbacked_html)) {
        return
TRUE;
    }
    return
FALSE;
}

(
省略)
?>

この部分が、TrackBack SPAM対策のコアの部分となる。trackbacklib.phpに1個関数を追加し、さらにtrackback保存処理にちょっと手を加えている。

TrackBackを保存する関数(add_trackback_data)から、送信元HTMLに受信先URLが含まれるかを確認する関数(is_trackbacked_url_linked)を呼び、その結果に応じてTrackBackデータを保存する際のデフォルトの削除フラグを設定している。is_trackbacked_url_linkedでは、単純にfile_get_contentsで送信元URLのHTMLを取得し、それの内容に対して正規表現で送信先URL文字列の検索を行っている。

/tmpl/trackback_list.tmpl

(省略)
    『<a href="<?=h($item['url']) ?>" rel="nofollow"><?=h($item['title'] != '' ? $item['title'] : $item['url']) ?></a>』
(省略)
</dt>

/tmpl/comment_list.tmpl

(省略)
    <a href="<?=h(preg_match('|^https?://|i', $item['url']) ? '' : 'mailto:') ?><?=h($item['url']) ?>" rel="nofollow"><?=h($item['name']) ?></a>
(省略)

rel="nofollow"対策を行うには、上記二つのテンプレートを書き換えればいい。trackback_list.tmplがTrackBack一覧の表示用、comment_list.tmplがコメント一覧の表示用となっている。

『自分で作るblogツール(PHP編)』サポートエントリーに戻る

Published At2005-04-01 17:29Updated At2005-04-01 17:29

日記
movable typeでRSS 1.0にcontent:encodedを含める方法 (06:18)Edit

blogmapではRSSのdescriptionかcontent:encodedの内容しか解析しないんだけど、MTの標準状態ではdescriptionにほとんど情報が含まれない。で、blogmap等のRSSベースの検索を行うサービスに情報を拾ってもらいたい場合、RSSにcontent:encodedとして必要な情報をつっこんでおくのが手軽。というわけで、そうしたい場合の設定方法。

MTの管理画面から「テンプレートの編集」を選択し、RSS 1.0の編集フォームを開く。

最初の方にあるxmlnsの設定のdcの設定の後ろあたりに、contentモジュールが利用できるように設定を追加する。

xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
↑この行を追加

各記事itemを出力しているあたりのdescriptionの次あたりに、content:encodedを出力する行を追加する。$MTEntryBodyが本文。$MTEntryModeが追記。上記の例だと全部出力しているけど、追記分はRSSに含めたくない場合は$MTEntryBodyのところだけ書いておいたりしてもいい。

<description><$MTEntryExcerpt encode_xml="1"$></description>
<content:encoded><$MTEntryBody encode_xml="1"$><$MTEntryMore encode_xml="1"$></content:encoded>
↑この行を追加

といった感じにしておくと、blogmapではそのサイトの記事に含まれるURLやらASINやらの情報をきちんと解析できるようになります。

長文を書く人の場合は、本文($EntryBody)に主要な情報(リンクやASIN情報)は全部つっこんでおくようにして、RSSには$EntryBodyだけ含ませるようにする方が無難かな。

<description><$MTEntryExcerpt encode_xml="1"$></description>
<content:encoded><$MTEntryBody encode_xml="1"$></content:encoded>
↑この行を追加

じゃないとRSSのデータサイズがでかくなりすぎるし。その場合、こんな感じの出力になります。

ちなみにtDiaryは標準(makerss.rb)でcontent:encodedに全文がつっこまれるんで、RSSさえ出力していれば上記のようなことは考えなくてもOKです。

追記:『MT hxxks - 概要 ( excerpt ) は有効活用されていない』より

少なくとも、 Movable Type では以前から概要 ( Movable Type の場合は description ではなく excerpt と表現していますが ) を自分で記述することはできました。

確かに「たいていの人はそういう(本文のみ書いて、その冒頭が自動的にdescriptionとなる)運用にしている」と書いておいた方が正確でしたね。

ちなみにはてなダイアリーは、

description をユーザが記述できるようになりました。 ( はてなダイアリー日記 - rssモジュールのdescription表示拡張について )

というのではなく、RSSにコンテンツの全文を掲載(content:encoded)できるようになった(はてなダイアリー日記 - RSSフィードの全文掲載機能について)んですよ。MTみたいな自前でexcerptを記述する機能は持ってません。

rssモジュールのdescription表示拡張ってのは、他サイトのRSSをサイドバー等に取り込むときに、descriptionを表示できるようになった(従来はタイトル、日付等しか表示できなかった)という話なんで、自サイトのdescriptionの話とはちょと違います。

ってまあそれはどうでもいい(本筋とは関係ない)話ですけど。

ちなみに真琴さんが『MT hxxks - 概要 ( excerpt ) の重要性』や『MT hxxks - 概要 ( excerpt ) を書くことのメリット』で説く主張はとても正しいし、そういう方向に進むのが理想的だと思います。

ただ、多分大多数の人はblogの更新に最低限の手間しかかけたがらない=きちんとした概要を書こうという主張はなかなか受け入れられにくいだろうということで、ローコストでblogmap的にありがたい結果が得られる手法として、上記の対策を紹介してみたりしているわけです。思想のない手段の提供って感じですか。

Published At2005-04-02 00:00Updated At2005-04-02 00:00

日記
花見 (00:14)Edit

昨日は会社の花見だったんだけど、ここのところ花粉症がひどいし、いつもの渋谷近辺ではなく上野会場ってことでいまいち土地勘もないし、面倒くさいなーと思いつつも、終わる時間頃を狙ってちょっとだけ顔を出しに行った。けど、場所取り予定地近辺にそれらしい集団は見つからず。携帯に電話してまで合流すると二次会に連れて行かれそうな気がしたんで、上野公園内を散歩して偶然であったら合流しようと思いつつ1時間ほどうろうろしたけど、結局出会えず。まあいいかってことでそのまま帰ってきた。ちなみに桜は1割くらいが咲いている感じ。一分咲きとかではなく、1割の木がほぼ満開になっている、って感じね。

Published At2005-04-03 00:00Updated At2005-04-03 00:00

日記
JavaScriptでpreg_replace_callback 2 (11:14)Edit

JavaScriptでpreg_replace_callback』の続き。replaceの第2引数で関数が呼べることがわかったんで、それならオブジェクトのメソッドも呼べるだろうと、以下のように書いてみた。

function Test()
{
this.prop = 1;
}
function Test_replace()
{
var str = 'abcde';
var result = str.replace(/bcd/, this.callback);
return result;
}
Test.prototype.replace = Test_replace;
function Test_callback()
{
return this.prop;
}
Test.prototype.callback = Test_callback;
test = new Test();
alert(test.replace());

確かにthis.callbackという表現でcallbackが呼べる。けど、実際にはthis.callbackが呼ばれているのではなく、単にTest_callbackが呼ばれているっぽい。

this.callback内で参照しているthisが、呼び出し元のthisじゃなく、windowオブジェクトになっちゃっている(Test_callbackの中身を「return this.location.href;」とかするとそのように動く)。だからthis.propで1に置換されることを期待しても、callback内ではthis.propが見つからず(未定義)、上記の結果はIEなら「ae」、Firefoxなら「aundefinede」になっちゃう。

うーん、replaceのコールバック関数として、オブジェクトのメソッドを呼ぶ方法はないのかなー。WikiParserを移植するに当たっては、オブジェクトのプロパティ(パーサーオブジェクトごとに固有の設定値)を参照したいんだけどなー。グローバル変数領域をそれなりに汚染しつつパラメータを受け渡すしかないのかなー。

ところでJavaScriptでの文字コード変換って、『Escape Codec Library: ecl.js』のライブラリを使わせてもらうってのが、現時点では一番妥当な選択なのかなー。 

Published At2005-04-03 00:00Updated At2005-04-03 00:00

日記
『movable typeでRSS 1.0にcontent:encodedを含める方法』に追記しました(T/O) (12:50)Edit

Published At2005-04-03 00:00Updated At2005-04-03 00:00

日記
MapServerをひとまずインストールだけしてみた (13:54)Edit

実際に入れたのは、ちょっと古い国際化バージョンの方だけど。

具体的な使い方はさっぱりわからんけど、一応表示できているっぽいな。これであとは「GISデータパック」(全国一括98,000円:1サーバーライセンス)ってのを買えばいいのか。うーん、思ったよりお手軽っぽい。迷うなー。

Published At2005-04-03 00:00Updated At2005-04-03 00:00

日記
WikiParserのJavaScript移植版 (18:50)Edit

基本文法部分はほとんどそのまま移植しているんで、PHP版のWikiParserをサーバーサイドで使っている場合のクライアントサイドのプレビュー用に使ったりすると、再現性が高くていいかもしれない。tDiaryのWikiスタイルとの互換性も結構高いはずだから、tDiary Wikiスタイルのクライアントサイドプレビュー用にも使えるかな。

端折っているのは、プラグイン周りとInterWiki。InterWikiについては、文字コード変換処理をどうするか迷って、結局載せていない。これはまあ方針さえ決まれば載せられる。プラグインも載せるのは簡単そうだけど、JavaScriptでプラグインを書く人はいないような気がしてきたんで、いらないかなーと思いつつある。

というわけで、初めてJavaScriptで見た目の動きをいじったりする以外のコードを書いてみたけど、結構ちゃんと書けるね。

Published At2005-04-03 00:00Updated At2005-04-03 00:00

日記
おまけ: 過去ログ・カテゴリー表示機能の作成 (12:34)Edit

Published At2005-04-04 00:00Updated At2005-04-04 00:00