Movable Type で構築したサイトで、各記事ごとのアクセス数を集計できれば、"今週の人気記事 トップ 10"のような機能が実現できるでしょう。丁度、ここのホストでも Apache のアクセスログがユーザに解放されているので、これを利用することができそうです。
結果、特にプラグインを追加せず、PHP を使用することで、サイトデザインの容易性、他ホストでの可搬性を高めつつ、これを実現することができました。また、記事のファイル名がエントリ ID 以外(日付やキーワード)で生成されている場合にも対応でき、cron による定期実行やブラウザからのランキング更新も可能です。
先ずは、この人気記事ランキングを実現する方法について Web を検索したところ、"Masahiko Isshiki WEB SITE:MT で人気記事のランキングを表示する" という記事が大変参考になりました。ここでは Jeff Borlik 氏のT-MostVisited Pluginを使用してこれを実現する方法が、インストール手順から詳しく説明されています。このプラグインは MT の再構築時にアクセスログの集計と表示を行うためのもので、比較的簡単に導入し実現することができそうです。
しかしながら、このプラグインでは記事ファイル名が記事 ID を含む必要があり、これ以外の書式、例えば日付を基に生成されている場合(/2005/1234_1234.html)などでは、このプラグインを使用することができません。これは単純に、アクセスログに残ったファイル名から記事 ID を特定できないことから、その記事のタイトルや投稿者といった情報にアクセスできないためだと思われます。
また、ランキングのリアルタイム性を確保するために、これに続く"MTで人気記事ランキングの定期自動実行"で、Perl のスクリプトを別に用意し JavaScript を併用する方法が紹介してあります。このように MT 以外のところで様々なギミックが必要となり、結果的にランキング表示周りの複雑性が増すことになっているようでした。
今回、紹介する方法は以下の点に重点が置かれています。
ダウンロードしたファイルは、
「『アクセスログの集計を行うための PHP スクリプト』のためのインデックステンプレート(あぁ、ややこしい)」のため、
このままでは実行できません。
このファイルを MT 管理画面から[テンプレート]-[インデックステンプレート]に登録します。
このテンプレートの構築を行って初めて、
"出力ファイル名"で指定されたファイルが実行可能な PHP スクリプトとなります。
また"再構築オプション"は"自動で再構築"でも構いません。
再構築時の負荷はマスターアーカイブの生成と同程度と思います。
この段階で構築はできると思いますが、設定が済んでいないので実行はできないでしょう。
次の各種設定に続きます。
スクリプトの動作設定を行います。テンプレートの 15〜30 行付近にある以下の項目を修正してください。
サーバによってアクセスログのファイル名が様々です。37 行付近の GetLogFileNames という関数内でアクセスログのファイル名を生成しているので、
お使いのサーバのアクセスログのファイル名に合わせて修正してください。毎日日付ファイル名でログを残すものや、過去ログを gzip 圧縮するもの、直近の数日のみ残すものなど様々です。
ログファイルを一つも読めていないような場合は、szLogDir の設定とここの設定を疑ってみてください。
お使いの MT のカスタマイズによって、個別アーカイブの生成ファイル名は様々かと思います。
76 行付近の IsTargetURL はアクセスログに残されたファイル名が
ランキング集計対象か否かを判定するための関数です。
ランキング集計したいファイル名にマッチするよう Perl の正規表現を修正してください。
スクリプト実行時の標準出力を見て、1 件も集計されいないような場合、
ここのパターンマッチングで失敗していることが考えられます。
集計結果を成形して書き出すためにCreateEntryListItem(111 行付近) と CreateEntryList(126 行付近) のうち、それぞれ 2 つの /******** コメント ********/ で囲まれた範囲を修正してください。とりあえず動作を見たいという御仁は、このステップを飛ばされても構いません。
1 つのエントリにつき CreateEntryListItem が呼び出されて、1 つ分の HTML を生成します。
次にこれが nTopEntry 回だけ繰り返されて、
CreateEntryList でその結果を含めた HTML が 生成されるようになっています。
HTML 部分は HTML タグや MT のテンプレートタグをそのまま使うことができます。
またランキングの集計結果を使う場合は {$entry['キー名']} という記述で値を自由に埋め込むことができます。例えば、次のようにして記述できます。
Step 2.までの設定が終わったら、テンプレートを再構築してランキング集計スクリプトを書き出します。そして、このランキング集計スクリプトを実行すれば、集計結果が szOutput に出力されます。ランキング集計はこのスクリプトが実行された瞬間に行われます。
スクリプトを実行する手段として
の何れかの方法が可能です。目的に合わせて適宜選択してください。
集計結果ファイルはそのまま表示することもできますし、PHP の include を利用してページに埋め込むこともできます。後々のメンテナンスのことを考えると、集計スクリプトで成形する HTML は最低限にし、それを取り込む側で本格的にデザインを施す方が簡単でしょう。
CreateEntryListItem と CreateEntryList で HTML を成形する場合、 エントリについてさらに細かな情報が必要になることがあります。 88 行付近の GetEntryList では、HTML の生成に必要なエントリの各種情報のテーブルを作成しています。ここに任意の名前でキー名を登録し、テンプレートタグを駆使してエントリの情報を取得するようにします。
この部分は PHP スクリプトとして実行される部分になりますので、encode_php タグ・アトリビュートを指定して、文字列を安全にしてください。
寄せられたコメント (全 10 件中、最新 5 件まで表示しています)
こんにちは、ランキングについて質問させて下さい
step3のところでどうしても集計結果の出力ファイルが作成されません。
集計スクリプトを実行したところ、一番下に
(Warning: fopen(/virtual/zox/public_html/review/outrank.php)
[function.fopen]: failed to open stream: Permission denied in
/virtual/zox/public_html/review/rank.php on line 333)
このようなエラーが出てしまいます。
http://zox.s119.coreserver.jp/review/rank.php
↑は集計スクリプトです。
原因が全然分からなくて、すみませんが何かアドバイスを頂けないでしょうか。
こんばんは、初めてコメントします。人気ランキングで1つ分からないことがあり、
質問させて下さい><
return (preg_match ("/^ / d{4} / d{2} /( w+)/ .php/", $url));
ここの正規表現の記述がどうしてもわからず、教えて頂きたいのですが、
yyyy/mm/entry-basename/index.php
↑の場合だとどのように記述すればよろしいでしょうか?
お手数ですが、宜しくお願いします。
>にゃお さん
画面に全く何も出ないというのが謎なんですが,スクリプトファイルの所々に
if (0) /*set 1 for DEBUG*/
という箇所が何箇所かあると思います。これを
if (1)
に書き換えて実行してみてくださいますか?
もしスクリプトとして動いているなら,どこで止まっているのかヒントになるかもしれません。
あと,これは全く自身が無いんですが(ぉぃ) 1行目にある
#!/usr/local/bin/php
を消してみてください。ホント度々すみません。
またまたご返信ありがとうございます。
phpinfoで見たところzlib有効になっていました。
う。。。んサーバー側で問題ありなんですかね。。。
>にゃお さん
アクセスログのパスを間違っていたり,正規表現に全くマッチしなかった場合でも,プログラムが動作した場合には何らかのメッセージが表示されるようになっています。それすら表示されずに画面が真っ白ということは,PHP スクリプトとして正しく実行されていないのだと思われます。
ところで,phpinfo() を実行した時に,zlib のサポートが有効になっているか見て頂けますか? このスクリプトではgzip圧縮されたログを読み込む目的のためにzlibの関数を利用しています。