CGI プロセスの内部構造 メソッド FML::CGI:: の階層にあるクラス(たとえば FML::CGI::ML)では、 以下のメソッド群を実装して下さい。 html_start() run_cgi_main() run_cgi_title() run_cgi_navigator() run_cgi_menu() run_cgi_command_help() run_cgi_options() html_end() ここで html_start() は、 ようするに HTML の先頭部分、たとえば DOCTYPE から BODY あたりを、 html_end() は /BODY と /HTML を表示する部分をカスタマイズするために用います。 「run_なんとか」は HTML BODY の中身を定義するメソッド群です。 $curproc の run() メソッドは html_start() run_cgi_XXX() 群を実行(3x3 テーブル状に出力を配置、9 メソッドあります) html_end() を順番に実行しています。 つまり CGI プロセスの実行のフロー( FML::Process::Flow 参照)は new() prepare() verify_request() run() html_start() run_cgi_○○() (9 メソッドあります) html_end() finish() ということになります。 CGI の画面の作りとメソッド &fml8; CGI スクリプトでは典型的な画面が次のように分割されると考えています。 ヘッダ ◎ メニュー ◎ バー1 メイン バー2 ◎ メニュー ◎ フッタ なお、バー1と2の部分は navigation などと呼ばれます。 ヘッダ部分(HTTP ヘッダではなく、HTML の DOCTYPE から BODY あたり)や、 フッタの部分は html_start() および html_end() で HTML コードを生成しています。 一方、 HTML BODY の中身は中央の3x3テーブル状の部分で、 run_cgi() から呼ばれるメソッドが生成しています。 (1) run_cgi() の粒度をあげる(中身をより細かくする)、 (2)「画面上のどの部分をどのメソッドが記述するのか」を指定できるメソッド、 が必要でしょう。 また、 これにあわせて BODY の中身もより細かく次のような3x3の精度で表現されています。 nw north ne west center east sw south se 現在の CGI の画面の構造 以下のような3x3のテーブル構造をとっており、 それぞれ次のメソッドが表示を担当しています。 run_cgi_main run_cgi_title run_cgi_navigator run_cgi_menu run_cgi_command_help run_cgi_options HTML のレベルでは、 TABLE 命令を使って疑似的なナビゲーションバーを作っています。 そして、 ハッシュテーブルで定義されている関数を決められた順番で実行し、 テーブルを作成しています。 run_cgi_main() は何らかの処理をしない限り何も表示しません。 たいていは「なし」か「OK …」程度です。 エラーメッセージを表示することもあります。 また、 この関数はML一覧などをきちんと最新の情報にするために、 画面を描く前に実行する必要があります。 ちなみに、 run_cgi_main() は個々の関数を呼び出すためのトップレベルのアダプター層で、 FML::CGI::Menu::Admin に定義されています。 個々のコマンドは、makefml の時と同様に、この関数経由で実行されます。 ただし、 ログやメンバーリスト一覧のように run_cgi_menu() から結果の表示をしているものもあります。 これは表示のオプションの指定をさせるために、 run_cgi_main() ではなく run_cgi_menu() 経由で表示しているともいえるのですが、 なにしろコマンドの結果の表示が長いので、 今のように menu() 経由のほうがよいと思います。 画面とトランポリン機構 CGI を表示する実体部分は FML::Command:: 以下のクラスに移動させました。 しかしながら、 FML::Command:: の中に実体があるとは限らず object composition の形式で FML::CGI:: クラスが提供するメニュー生成クラスを使うことになっています。 たとえば subscribe の場合 FML::CGI::Admin::Main → FML::Command::Admin::subscribe → FML::CGI::Admin::User → メニューの表示 などとなっていて、 Mach のトランポリン機構のように、いったりきたりしています。 備考: FML::CGI::Admin:: ではハードコーディングするしかないのか? たとえば FML::CGI::Admin::User では $comname と maps の関係がハードコーディングされていますが、 設定ファイルに移動するには非常に多くの変数が必要になりそうなので、 ある程度のハードコーディングは仕方ないでしょう。 できるだけ config.cf で変更可能であるように心がけたいとは思うのですが… §.internal.cgi.examples;