[Hiki-dev:00528] リクエストによってメッセージの言語を変更

Back to archive index

Kouhei Sutou kou****@cozmi*****
2004年 4月 8日 (木) 14:20:02 JST


須藤です.

# 変なメールアドレスで出してしまって申し訳ありません.
# MLに流れていないということは管理者に配送されたのかしら.
# もしそうなら削除してください.

従来のHikiはhiki.confで$langを設定することにより,ひとつの
Hikiでひとつの言語を扱っていましたが,ブラウザからのリクエス
トによって言語($lang)が変更するようにしてみました.
# あまりきれいではありませんが(Command#init_lang中で$charset
# を設定していたりとか),叩き台ということで.
## もしかして,ひとつのHikiでひとつの言語というのがポリシー
## だったりしますか?そうであれば,このメールは無視しちゃっ
## てください.

言語指定の優先順位は

  (1) クエリのlパラメタの値
  (2) HTTPヘッダのHTTP_ACCEPT_LANGUAGEの値
  (3) $langの値

となっています.


問題として,ナビとかのメッセージが変わるだけでコンテンツは変
わらないので文字化けする場合があります.

ぱっと思い付く解決案としてはこんな感じでしょうか.

  * UTF-8化

  * hiki/db/*が言語毎に情報を持つようにする.

    textdir なんかは File.join($pages_path, $lang, page_name)
    を返すとか?

あと,試していないのではっきりいえませんが,hikidとか
mod_rubyとかだと,うまく動かない気がします.


最後に,作っている途中で気になった事をいくつか挙げてみます.

  * $charsetはhiki/global.rbではなくてmessages/#{$lang}.rbで
    設定した方がいいのではないか.
    
    $template_pathも$langを使って初期化しているので気になる
    ところですが...

  * メッセージはHiki::Messagesをトップレベルでincludeするの
    ではなくて,$lang用のメッセージは
    Hiki::Messages::#{$lang.capitalize}に定義して,トップレベ
    ルのmethod_missingで現在の$lang用のメッセージを返すよう
    にしたらどうか.
    
    イメージ:
    def method_missing(name, *args)
      if Hiki::Messages.const_defined?($lang.capitalize)
        Hiki::Messages.const_get($lang.capitalize).__send__(name, *args)
      else
        super
      end
    end

    問題点: プラグイン中にべた書きされているmsg_*はどうやっ
    て上書きしよう? -> べた書き禁止?

  * 新しくエラークラス(Hiki::MessageNotFound)を作らなかった
    方がよかったのかしら.
-------------- next part --------------
Index: hiki/command.rb
===================================================================
RCS file: /cvsroot/hiki/hiki/hiki/command.rb,v
retrieving revision 1.9
diff -u -p -r1.9 command.rb
--- hiki/command.rb	6 Mar 2004 01:02:07 -0000	1.9
+++ hiki/command.rb	7 Apr 2004 10:29:45 -0000
@@ -9,18 +9,18 @@ require 'hiki/plugin'
 require 'hiki/aliaswiki'
 require "style/#{$style}/parser"
 require "hiki/hiki_formatter"
-require "messages/#{$lang}"
 
 include Amrita
 include Hiki::Util
-include Hiki::Messages
 
 module Hiki
   class Command
     def initialize(cgi, db)
-      @db     = db
-      @params = cgi.params
       @cgi    = cgi
+      @params = cgi.params
+      init_lang
+
+      @db     = db
       @cmd    = @params['c'][0]
       @p = case****@param*****
            when 0
@@ -582,6 +582,40 @@ module Hiki
 
       if redirect_mode and result
         redirect(@cgi, @plugin.hiki_url(@p))
+      end
+    end
+
+    def init_lang
+      lang = nil
+      langs = @params['l'].collect{|l| l.untaint} + accept_language + [$lang]
+      langs.each do |l|
+        begin
+          require "messages/#{l}"
+          Object.__send__(:include, Hiki::Messages)
+          $lang = lang = l
+          case $lang
+          when 'en', 'fr', 'it'
+            $charset = 'ISO-8859-1'
+          end
+          load 'hiki/global.rb'
+          break
+        rescue LoadError
+        end
+      end
+      raise MessageNotFound.new(langs) if lang.nil?
+    end
+
+    def accept_language
+      @cgi.accept_language.split(',').collect do |entry|
+        lang, quality = entry.split(';')
+        if /^q=(.+)/ =~ quality
+          quality = $1.to_f
+        else
+          quality = 1.0
+        end
+        [lang, quality]
+      end.sort {|e1, e2| e2[1] <=> e1[1]}.collect do |lang, quality|
+        lang.untaint
       end
     end
   end
Index: hiki/util.rb
===================================================================
RCS file: /cvsroot/hiki/hiki/hiki/util.rb,v
retrieving revision 1.8
diff -u -p -r1.8 util.rb
--- hiki/util.rb	15 Feb 2004 02:48:35 -0000	1.8
+++ hiki/util.rb	7 Apr 2004 10:29:45 -0000
@@ -46,6 +46,16 @@ end
 module Hiki
   class PluginException < Exception; end
 
+  class Error < StandardError; end
+
+  class MessageNotFound < Error
+    attr_reader :langs
+    def initialize(langs)
+      @langs = langs
+      super("available message doesn't found in #{@langs.inspect}")
+    end
+  end
+
   module Util
     CONF_S = %w($site_name $author_name $mail $theme $password $theme_url $sidebar_class $main_class $theme_path)
     CONF_F = %w($mail_on_update $use_sidebar $auto_link)


Hiki-dev メーリングリストの案内
Back to archive index