URLの中でコロン(:)などの予約語を使う

Mojoliciousのルーターは、細かい設定などができて、とても便利です。けれども、使ってみると:#*.が予約語になっているということに気づくと思います。

これらの記号をURLの中で利用したい場合はあきらめるしかないのでしょうか(#はURLの中でフラグメントとしての意味を持つので除く)。以下のような指定では正しくパラメーターを取得することができません。

# 間違い (/20101114:mainでパラメータを正しく取得できない)
get '/(:date):(:id)' => sub {
  my $self = shift;
  
  my $date = $self->param('date');
  my $id = $self->param('id');
  
  $self->render(text => "$date $id");
};

コロンは予約語なので、このようなルートの指定はうまくいきません。

解決策として、正規表現による制約を利用する

けれども、Mojoliciousのルーターはきわめて柔軟なので、通常のルータと正規表現を組み合わせることができます。

つまり、予約語を含むような部分は正規表現で記述すれば、すっきりとはいきませんが、解決できます。

# 正しい (/20101114:mainでパラメータを正しく取得できる)
get '/:date_id' => [date_id => qr/[^:]+?:[^:]+/] => sub {
  my $self = shift;
  
  my $date_id = $self->param('date_id');
  my ($date, $id) = $date_id =~ /([^:]+?):([^:]+)/;
  
  $self->render(text => "$date $id");
};

プレースホルダーを$data_idという名前にして、これに対して正規表現を使って制約を記述しています。/20101114:mainにマッチするルートを記述できています。

後は、同じ正規表現を使って、分割するだけです。

関連情報