この記事の内容は、時間経過およびプログラムやシステムのバージョン アップなどの事情によって、現状に正しくそぐわない内容、またはそれどころか、場合によっては問題を引き起こす可能性があります。参考程度に留め、関連記事やアーカイブを検索してみてください。
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['キー名']} という記述で値を自由に埋め込むことができます。例えば、次のようにして記述できます。
・CreateEntryListItem の例 第 {$entry['Ranking']} 位: <a href="{$entry['EntryPermalink']}">{$entry['EntryTitle']}</a> ({$entry['ReferCount']} Hits)<br /> <i>Posted by {$entry['EntryAuthorNickname']} at {$entry['EntryDate']}</i> ・CreateEntryList の例 <h4>■ 過去{$entry['nDivDay']}日間の人気記事 トップ{$entry['nTopEntry']}</h4> {$entry_list}
Step 2.までの設定が終わったら、テンプレートを再構築してランキング集計スクリプトを書き出します。そして、このランキング集計スクリプトを実行すれば、集計結果が szOutput に出力されます。ランキング集計はこのスクリプトが実行された瞬間に行われます。
スクリプトを実行する手段として
の何れかの方法が可能です。目的に合わせて適宜選択してください。
集計結果ファイルはそのまま表示することもできますし、PHP の include を利用してページに埋め込むこともできます。後々のメンテナンスのことを考えると、集計スクリプトで成形する HTML は最低限にし、それを取り込む側で本格的にデザインを施す方が簡単でしょう。
CreateEntryListItem と CreateEntryList で HTML を成形する場合、 エントリについてさらに細かな情報が必要になることがあります。 88 行付近の GetEntryList では、HTML の生成に必要なエントリの各種情報のテーブルを作成しています。ここに任意の名前でキー名を登録し、テンプレートタグを駆使してエントリの情報を取得するようにします。
・エントリの最新のコメントの日付が必要な場合の例 :(GetEntryList の一部) 'EntryAuthorNickname' => '<$MTEntryAuthorNickname encode_php="q"$>', 'EntryCategory' => '<$MTEntryCategory encode_php="q"$>', // ↓この行を追加します 'LastCommentedDate' => '<MTComments lastn="1"><$MTCommentDate encode_php="q"$></MTComments>', null));
この部分は PHP スクリプトとして実行される部分になりますので、encode_php タグ・アトリビュートを指定して、文字列を安全にしてください。
寄せられたコメント (全 17 件中、最新 5 件まで表示しています)
人気記事の一覧を Google Analytics から取得する:GADGET
http://www.magicvox.net/archive/2012/05101046/
自分はIDではなく、特定のファイル名を設定していたので、
<MTEntries lastn="0">
'/map/tokyo/furugi/<$MTEntryID$>.html' => <$MTEntryID$>,
</MTEntries>
で取得する事ができました!
最期に質問と言うか、要望?みたいなのになっちゃうのですが・・・(・∀・;)
hottopic300.phpをそれぞれ違うディレクトリに配置して、$szOutputと$gAllEntriesの設定値を変更し、
それぞれのカテゴリの集計結果をとろうと思っているのですが、まとめてhottopic300.phpを実行する方法は
ありますでしょうか?背景として、レンタルサーバ側のcronの個数が限られているので、複数のhottopic300.phpを
実行するのは難しいかなと思いまして。
このスクリプトは軽いのがメリットですので、そういった動作は想定されてないと思いますし、
本スクリプト機能以上の質問しているかもしれませんが、もし何か良い案がありましたら教えてください。
よろしくお願いします。
2.x で preg_match を使って集計対象の URL か否か判別していましたが、集計対象の URL だった場合には、更にその URL からブログ記事 ID を取得していました。正規表現は便利ですが複雑ですので、それならいっそ、集計対象の URL を羅列してしまえ、というのが 3.x の $gAllEntries 変数です。
ですので、$gAllEntries のキー文字列は末端のファイル名までのパスを含まなければなりません。まぶおさんの場合ですと、例えば
<MTEntries lastn="0">
'/map/tokyo/furugi/<$MTEntryID$>.html' => <$MTEntryID$>,
</MTEntries>
のようになると思います(HTML のファイル名は適当です)
$gAllEntries = array (
<MTEntries lastn="0">
'/map/tokyo/furugi/' => '<$MTEntryID$>',
</MTEntries>
null);
と記述して出力されませんでした。
原因がお分かりでしたら教えてください。
1、なるほど、$gAllEntries内で複数のディレクトリを指定し、集計する事が可能というわけですね!
ここで質問なんですが、3.00から$gAllEntriesは正規表現は使わないようになっているように見えます。
2.00で『 return (preg_match ("/^/map/tokyo/furugi/w+.html/", $url));』
と設定して、対象のカテゴリ記事を取得する事ができたのですが、
3.00で『 '/map/tokyo/furugi/' => '<$MTEntryID$>',』
と設定してもファイルを取得する事ができませんでした。
他に確認する箇所はありますでしょうか?