HTTP_ACCEPT_LANGUAGEで表示ページを変える

利用者の使用言語に応じて表示ページを変えようと思ったのだけれども、簡単、かつ、うまい方法が見つからない。

広告は、お客様が選択したターゲットとする言語と地域のオプション (詳細は次のトピックを参照) に基づいて、特定のユーザーに表示されます。 このオプションを利用して、AdWords では、お客様がご希望とされるユーザーに対して表示することができます。
ユーザーが GoogleGoogle ネットワークのサイトで検索を行うと、Google ではユーザーの次の情報を基にして掲載する広告を決定します。

  • Google ドメイン
  • 入力されたクエリ (クエリ分析 と呼ばれます)
  • インターネット プロトコル (Internet Protocol、IP) のアドレス
  • 言語設定

Google Adwordsの方法では、クエリ分析とIPアドレスから言語と地域を割り出すしかないが、それは簡単とは思えない。そこで、次善の策としてブラウザのHTTP_ACCEPT_LANGUAGEで表示ページを変えることにする。具体的には、HTTP_ACCEPT_LANGUAGEの優先順位がもっとも高い言語のページにリダイレクトで飛ばす。

HTTP_ACCEPT_LANGUAGEについて以下のページを参考とした。

ざっとみたかぎりでは、HTTP_ACCEPT_LANGUAGEの構造は、擬似BNF記法で書くと以下のとおり。(参考:wikipeida.ja

<HTTP_ACCEPT_LANGUAGE> ::= <ELEMENT>{,<ELEMENT>}
<ELEMENT> ::= <LANGUAGE>[-<COUNTRY>][;q=<PRIORITY>]

という構成になっている様子。LANGUAGEはISO 639(参考:wikipedia.ja)で定義されている国略称にしたがっている様子。COUNTRYはどういうルールなのかわからない。PRIORITYは0から1の数字になっているのではないかと予想。

あと、言語に応じたページにLocationを用いてリダイレクトするのは筋の悪いやり方みたい。

たぶん、きれいなソースではないけれども、一応ご参考まで。Internet Exploler 7, Firefox 2.0, MacSafariでは、ちゃんと日本語のページへリダイレクトされた。%urlにURLがかかれている言語は、そのURLへ飛ばす。そうでなければ、英語のページへ飛ばす。%urlのキーはISO 639で定義されている2文字の国略称を用いること。

#!/usr/local/bin/perl
use strict;
use CGI; # デバッグ用、なくても良い
use CGI::Carp qw(fatalsToBrowser); # デバッグ用、なくても良い

my %url = {};
my %lang = {};

$url{'ja'} = 'http://hogehoge/jpn/';
$url{'en'} = 'http://hogehoge/eng/';

my @acceptLanguage = split(/,/,$ENV{'HTTP_ACCEPT_LANGUAGE'});
foreach my $value (@acceptLanguage){

    if($value =~ /^([a-z]*)-([a-zA-Z]*);q=(.*)/){
        $lang{$1} = $3 if($lang{$1} < $3);
    }
    elsif($value =~ /^([a-z]*);q=(.*)/){
        $lang{$1} = $2 if($lang{$1} < $2);
    }

    elsif($value =~ /^([a-z]*)-([a-zA-Z]*)/){
        $lang{$1} = 1;
    }
    elsif($value =~ /^([a-z]*)/){
        $lang{$1} = 1;
    }
    else{
        $lang{'en'} = 1;
    }

}

foreach my $name (sort {$lang{$b} cmp $lang{$a}} keys %lang){
    if($name =~ /[a-z]{2,3}/){
        unless($url{$name} eq ''){
            my $site = $url{$name};
            print "Location: $site\n\n";
        }
        else{
            my $site = $url{'en'};
            print "Location: $site\n\n";
        }
    }
    else{
        print "Content-type: text/html\n\n";
        print "<html><head></head><body>Unexpected Symbol \"$name\"</body></html>";

    }
    last;
}

exit;