はてなダイアリーのようなURLの作り方
今回は、はてなダイアリーのURLのようにドメイン名に続いてユーザー固有のIDで始まるURL(自分のでいうとhttp://d.hatena.ne.jp/ngtn/)をCakePHPでどのように実現するかを考えてみました。
まず仮に
app/controllers/diaries_controller.phpファイルに定義された、DiariesControllerクラスのdisplayメソッドがユーザー固有のページを表示するものだと仮定します。
このメソッドは引数$userNameをとり、それがユーザーを識別するはてなIDのようなものだとします。
以降は$userNameの値を仮に'ngtn'として話をします。
<?php class DiariesController extends AppController { function display($userName){ //指定された$userNameから指定ユーザーの日記情報などを取得してviewにセット } } ?>
デフォルトでは
上記のメソッドへは/diaries/display/ngtn/といったURLでアクセスすることが出来ます。
それでは
実際どのように、はてなダイアリーのようなURLでアクセス出来るようにするかというと、routes.phpの設定を使います。
app/config/routes.phpの最終行に以下の一行を追加してください。
Router::connect('/*', array('controller' => 'diaries', 'action' => 'display'));
この設定によって/ngtn/というURLで、DiariesControllerクラスのdisplayメソッドに引数'ngtn'が渡されることになります。
上記は1.2系の書き方ですが、1.1系でもRouter::connectを$Route->connectに読み替えること同じことが出来ます。
但し!
routes.phpを上記のように設定すると、デフォルトで設定されている'/'、'/pages/*'、'/tests'以外のURLは全てDiariesControllerのdisplayメソッドが動くようになります。
他のコントローラーも使う場合は、手間ですが一つ一つ以下のような設定が必要になります。
Router::connect('/posts/:action/*', array('controller' => 'posts', 'action' => 'index')); Router::connect('/comments/:action/*', array('controller' => 'comments', 'action' => 'index')); Router::connect('/*', array('controller' => 'diaries', 'action' => 'display'));
他のコントローラーの設定は、'/*'の設定より前に記述する必要があります。
もう少しはてなダイアリーに近づけてみる
上記displayメソッドで出来るのはユーザーの個別ページの表示だけです。
しかし、はてなダイアリーは日付指定のURLで日付単位の表示(たとえばhttp://d.hatena.ne.jp/ngtn/20080208)、更に続けてタイムスタンプ(?)を指定することで記事単位の表示(たとえばhttp://d.hatena.ne.jp/ngtn/20080208/1202400164)が可能です。
これらを先ほどの例で実現するためには、displayメソッドの引数を追加して処理を振り分けることで可能になります。
かなり大雑把な例ですが、
<?php class DiariesController extends AppController { function display($userName, $date = null, $timestamp = null){ if( $timestamp != null ){ //ユーザー、日付、記事指定でデータの取得とrender処理 } elseif( $date != null ) { //ユーザー、日付指定でデータの取得とrender処理 } else { //ユーザー指定でデータの取得とrender処理 } } } ?>
といった感じになります。
これで、/ngtn/20080208/や、/ngtn/20080208/1202400164/といったURLにアクセスした時にdisplayメソッドの第2引数、第3引数に値を渡すことが出来ます。
まとめ
blogなどの会員系のサービスで、ユーザーの使いやすいURLを構築するのに役に立つかもしれないTipsの紹介でした。
もっとスマートなやり方を知っていたら、教えてもらえると嬉しいです。