[ruby-list:46797] ERBを利用した問合せメールシステム開発
From:
ShingoKintaka <kamuycikap@...>
Date:
2010-01-20 15:31:27 UTC
List:
ruby-list #46797
Shingo Kintakaです。
現在、会社等で利用される事の多い「問合せフォームCGI」を作成しております。
実行環境は@niftyが提供するLacoocanサービス。
先輩方の指摘と知恵を頂きたく、ソースコードをメール末尾に記述しております。
※ソースコードは ruby -c ./request_oem_chk.cgi として Syntax OK を確認しております。
※プログラムはrequest_oem_chk.cgiだけで、その他は画面表示用のhtmlファイル(テンプレート)とcssファイルです。
※問合せフォームのあるページは「request_oem.html」です。
長文です。
ERBを利用した問合せメールシステムを設計してみたのですが、テンプレートの読み込み表示処理が思うように動作しておりません。
理解できたフリや知ったかぶりをしてそれらしい質問を投げるよりも、現状の私の技術と問題をさらけだし、識者からの厳しい指摘を受けた方が良いと判断しソースコードを添付しております。
設計してみた問合せメールシステムを動作させる事もこの質問を投げる目的ではありますが、第一に私はどうしてもRubyを習得したい。
設計製造していて、こんなに楽しい言語は他にありません。
ERBを利用した技術を取得したい。もっともっと技術力を上げたい。
Rubyでもっともっと沢山の処理をこなせるようになりたいです。
是非、お力をお借りしたく、お願い申し上げます。
<仕様概略>
HTML(問合せ入力ページ)表示
↓
HTML(formのactionからcgiコール)
↓
HTML(問合せ入力ページ)のformタグ内にある入力パラメータを取得
↓
取得した入力パラメータの内容が正しいかどうかチェック
↓ ↓
HTML(確認画面)表示 HTML(エラー画面表示)
↓ ↓
HTML(確認画面formのactionからcgiコール) ※再び入力画面へ戻る
↓
sendmailを利用したメール送信
↓
ありがとうございました画面を表示
<抱えている問題>
HTMLと処理を行うcgiを分けたかった為、ERBを利用したテンプレートを読み込む仕様を設計してみました。
簡単なERBのサンプルを作ったのちに、本番の問合せフォームを作成したのでススっと出来ると思ったのですが。。。。
1.HTMLの中に<%= XXXX %>を埋め込んだテンプレートを正しく読み込めない
テンプレートである「errormsg.html」にある<%= err_msg %>は思う通りに表示できております。
※err_msgには入力チェックにひっかかった内容のエラー指摘文章が入っています。
動作させると、赤字でエラー文章が列挙されます。
しかしながら、新しく<%= hogehoge %>等をHTMLの中に追加すると、ブラウザに「500Internal_Error」と表示されます。
確認用画面のテンプレートである「affirmation_oem.html」も正しく値(@で始まるクラス変数)が表示されません。
※エラーを表示させるためのerr_cgiメソッドを作成し、begin〜endを利用してエラー表示させているはずなのですが。。???
テンプレートを読み込む処理は、RequestOEMChkクラスのメソッドに下記のように実装しております。
# 確認画面の表示
def show_inquiry
begin
templates = ERB.new(File.read(AFFIR_HTM),nil,"-")
templates.run
rescue
error_cgi
end
end
私のERBオブジェクトの使い方が間違っているのでしょうか???
2.エラー表示メソッドを実装しているはずなのに、「500Internal_Error」が表示される
私は、google検索と書籍「Ruby de CGI」を参考にして下記のメソッドを実装しました。
def error_cgi
print "*** CGI Error List ***<br>"
print "#{CGI.escapeHTML($!.inspect)}<br>"
$@.each { |x|
print CGI.escapeHTML(x), "<br>"
}
end
このメソッドをソースコードのメイン処理部分に下記の要領で実装しました。
if __FILE__ == $0
begin
req_oem_chk = RequestOEMChk.new # オブジェクト生成
req_oem_chk.get_form # 入力データを取得する
err_msg = req_oem_chk.data_check # 獲得したデータをチェックする
case err_msg # データチェック
when "OK" # OK
req_oem_chk.show_inquiry # 確認画面表示
else # NG
req_oem_chk.show_errorhtm(err_msg) # エラー画面表示
end
rescue
req_oem_chk.error_cgi # エラー処理 <----ココ
end
end
私の中では、この実装により「処理内部で発生するエラーは確実に拾える」と思っておりました。
それなのに何故「500Internal_Error」とブラウザに表示されるのでしょうか???
以上となります。
このメーリングリストがサポートセンターでは無く、メンバーの皆さんも忙しい何かを抱えている事も理解できているのですが、設計方法のまずさやコーディングに対する指摘など頂ければ幸いです。
以下がテンプレートのhtmlコードとcgiコードとなります。
--<問合せフォーム:request_oem.html>-- ここから
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>販売代理店・OEM お問い合わせフォーム</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<link rel="stylesheet" type="text/css" href="css/request_oem.css" media="all">
</head>
<body>
<h1>販売代理店/OEM お客様お問合せ</h1>
<p>
販売代理店/OEMに関する様々なお問合せは、電話または、こちらの問合せフォームより承っております。
<h2>電話でのお問合せ</h2>
<p>
商品の企画・開発およびPB商品の事など、気軽にお問合せください。<br>
<table class="line">
<tr>
<td>住所</td>
<td>
〒000-1111 サイド6ホワイトベース<br>
第13独立部隊 (だいじゅうさんどくりつぶたい)
</td>
</tr>
<tr>
<td>Tel</td>
<td>0000-11-2222</td>
</tr>
<tr>
<td>受付時間</td>
<td>平日10:30〜17:30</td>
</tr>
</table>
</p>
<h2>お問い合わせフォーム</h2>
以下のフォームより弊社宛のお問合せ内容を送信して下さい。<br>
内容を確認後、カスタマーサポート担当者からメールにて回答を返信いたします。<br>
<br>
なお、お問い合わせいただきました内容によっては協力会社等の関係部署に確認する必要があるため、<br>
ご返答までに1週間程度のお時間をいただく場合がございます。あらかじめご了承ください。 <br>
<br>
<span class="hissu">*</span>は入力必須項目です。
</p>
<form action="cgi/request_oem_chk.cgi" method="post">
<table>
<tr>
<td width="200">貴社名<span class="hissu">*</span></td>
<td width="356"><input type="text" name="CompanyName" size="40"></td>
</tr>
<tr>
<td>お問合せ種別<span class="hissu">*</span></td>
<td>
<select name="EnquiryClass">
<option value="SalesAgent">販売代理店</option>
<option value="OEM">OEM開発</option>
<option value="Other">その他</option>
</select>
</td>
</tr>
<tr>
<td>部署名</td>
<td><input type="text" name="PostName" size="40"></td>
</tr>
<tr>
<td>お名前(カナ)<span class="hissu">*</span></td>
<td><input type="text" name="NameKana" size="40"></td>
</tr>
<tr>
<td>お名前(漢字)<span class="hissu">*</span></td>
<td><input type="text" name="NameKanji" size="40"></td>
</tr>
<tr>
<td>郵便番号</td>
<td><input type="text" name="ZipCode" size="40"></td>
</tr>
<tr>
<td>都道府県</td>
<td><input type="text" name="AdministrativeDivisions" size="40"></td>
</tr>
<tr>
<td>市町村郡</td>
<td><input type="text" name="LocalAuthorityCounty" size="40"></td>
</tr>
<tr>
<td>番地</td>
<td><input type="text" name="HouseNumber" size="40"></td>
</tr>
<tr>
<td>電話番号<span class="hissu">*</span></td>
<td><input type="text" name="TelephoneNumber" size="40"></td>
</tr>
<tr>
<td>メールアドレス<span class="hissu">*</span></td>
<td><input type="text" name="EmailAddress" size="40"></td>
</tr>
<tr>
<td>メールアドレス(確認)<span class="hissu">*</span></td>
<td><input type="text" name="EmailAddressAff" size="40"></td>
</tr>
<tr>
<td height="109">お問い合わせ内容<span class="hissu">*</span></td>
<td><textarea name="ContentOfInquiry" rows="6" cols="70"></textarea></td>
</tr>
</table>
<input type="submit" value="確認"><input type="reset" value="リセット">
</form>
<br>
<a class="btn" href="http://hogehoge.jp/">TOPページ</a>
</body>
</html>
--<問合せフォーム:request_oem.html>-- ここまで
--<cgiコード:request_oem_chk.cgi>-- ここから
#!/usr/local/bin/ruby -Ke
#=問合せフォームによるメール配信
#
# Authors:: Shingo Kintaka
# Version:: 1.0 2010-01-02 S.Kintaka
# Copyright:: Copyright (C) S.Kintaka , 2006. All rights reserved.
# OEM/販売代理店向け問合せフォームの値を取得し、値をチェックした後に確認画面を表示する
#==開発履歴
# K20100119_00 新規開発
require "cgi" # CGIクラス
require "erb" # ERBクラス
require 'kconv' # 漢字コード変換用
ERRMSG_HTM = "./errormsg.html"
AFFIR_HTM = "./affirmation_oem.html"
#
#= お問い合わせフォームからパラメータを取得し確認テンプレート、またはエラーテンプレートを表示させる
#
class RequestOEMChk
# アクセサメソッド
attr_accessor :CompanyName # 貴社名
attr_accessor :EnquiryClass # お問合せ種別
attr_accessor :PostName # 部署名
attr_accessor :NameKana # お名前カナ
attr_accessor :NameKanji # お名前漢字
attr_accessor :TelephoneNumber # 電話番号
attr_accessor :EmailAddress # E-Mailアドレス
attr_accessor :EmailAddressAff # E-Mailアドレス
attr_accessor :ZipCode # 郵便番号
attr_accessor :AdministrativeDivisions # 都道府県
attr_accessor :LocalAuthorityCounty # 市町村郡
attr_accessor :HouseNumber # 番地
#
#= initialize
# イニシャライズ
#== Input
# Nothing
#
#== Result
# Nothing
def initialize
@cgi_form = CGI.new
end
#
# フォーム情報を取得する
# formタグに設定されているパラメータを取得する
#== Input
# Nothing
#
#== Result
# Nothing
def get_form
@CompanyName = @cgi_form["CompanyName"] # 貴社名
@EnquiryClass = @cgi_form["EnquiryClass"] # お問合せ種別
@PostName = @cgi_form["PostName"] # 部署名
@NameKana = @cgi_form["NameKana"] # お名前(カナ)
@NameKanji = @cgi_form["NameKanji"] # お名前(漢字)
@TelephoneNumber = @cgi_form["TelephoneNumber"] # 電話番号
@EmailAddress = @cgi_form["EmailAddress"] # E-Mailアドレス
@EmailAddressAff = @cgi_form["EmailAddressAff"] # E-Mailアドレス(確認用)
@ZipCode = @cgi_form["ZipCode"] # 郵便番号
@AdministrativeDivisions = @cgi_form["AdministrativeDivisions"] # 都道府県
@LocalAuthorityCounty = @cgi_form["LocalAuthorityCounty"] # 市町村郡
@HouseNumber = @cgi_form["HouseNumber"] # 番地
end
#
#= 入力データのチェック
# 必須項目の入力データをチェック(入力の有無)
# メールアドレスに関しては、正規表現を利用してメールアドレスの構成と確認用に入力した内容と同一であるかをチェックする
#== Input
# Nothing
#
#== Result
# error_message : エラーメッセージ文字列
def data_check
error_message = "" # エラーメッセージの初期値は""とする
# 貴社名が入力されているかチェック
if "" == @CompanyName then
error_message << "貴社名を入力してください<br>"
end
# お問い合わせ種別の選択が正しく行われているか
if "" == @EnquiryClass then
error_message << "お問合せ種別を選択してください<br>"
end
# 部署名が入力されているかチェック
if "" == @PostName then
error_message << "部署名を入力してください<br>"
end
# お名前(カナ)にデータが入力されているかチェック
if "" == @NameKana then
error_message << "お名前(カナ)を入力してください<br>"
end
# お名前(漢字)にデータが入力されているかチェック
if "" == @NameKanji then
error_message << "お名前(漢字)を入力してください<br>"
end
if "" == @TelephoneNumber then
error_message << "電話番号を入力してください<br>"
end
# メールアドレスが同じ内容でなければエラーとする
if @EmailAddress != @EmailAddressAff then
error_message << "入力されたメールアドレスと確認入力欄のメールアドレスの内容が異なります<br>"
end
# メールアドレスが正しく入力されているかチェック
if false == mail_check(@EmailAddress) then
error_message << "有効なメールアドレスを入力してください<br>"
end
# エラーが無ければ戻り値は"OK"とする
if error_message == "" then
error_message = "OK"
end
return error_message
end
#
#= 確認画面を表示する
# ERBを利用してテンプレート(htmlファイル)を読み込み確認画面を表示する
#== Input
# Nothing
#
#== Result
# Nothing
def show_inquiry
begin
templates = ERB.new(File.read(AFFIR_HTM),nil,"-")
templates.run
rescue
error_cgi
end
end
#
#= 入力値エラー画面を表示する
# ERBを利用してテンプレート(htmlファイル)を読み込みエラー画面を表示する
#== Input
# err_msg : エラーメッセージ
#
#== Result
# Nothing
def show_errorhtm(err_msg)
templates = ERB.new(File.read(ERRMSG_HTM),nil,"-")
templates.run
end
#
#= メールアドレスのエラーチェック
# 正規表現によるメールアドレスの書式チェック
#== Input
# Nothing
#
#== Result
# Nothing
def mail_check(mail_addr)
if mail_addr.downcase.scan(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/).length > 0
return true
else
return false
end
end
#
#= エラー処理
#== Input
# Nothing
#
#== Result
# Nothing
def error_cgi
print "*** CGI Error List ***<br>"
print "#{CGI.escapeHTML($!.inspect)}<br>"
$@.each { |x|
print CGI.escapeHTML(x), "<br>"
}
end
end
#
#= MainProgram
# メインプログラム
#== Input
# Nothing
#
#== Result
# Nothing
if __FILE__ == $0
begin
req_oem_chk = RequestOEMChk.new # オブジェクト生成
req_oem_chk.get_form # 入力データを取得する
err_msg = req_oem_chk.data_check # 獲得したデータをチェックする
case err_msg # データチェック
when "OK" # OK
req_oem_chk.show_inquiry # 確認画面表示
else # NG
req_oem_chk.show_errorhtm(err_msg) # エラー画面表示
end
rescue
req_oem_chk.error_cgi # エラー処理
end
end
--<cgiコード>-- ここまで
--<テンプレート 確認画面:affirmation_oem.html>-- ここから
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<link rel="stylesheet" type="text/css" href="../css/request_oem.css" media="all">
<title>販売代理店・OEM お問い合わせフォーム</title>
</head>
<body>
<h1>販売代理店/OEM お客様お問合せ内容の確認</h1>
<p>
<h2>入力内容の確認</h2>
<form action="http://foobar/cgi/request_oem_mail.cgi" method="post">
<table border="1">
<tr>
<td width="200">貴社名<span class="hissu">*</span></td>
<td width="356"><input type="text" name="CompanyName" size="40" style="display:none" value="<%= @CompanyName %>"><%= @CompanyName %></td>
</tr>
<tr>
<td>お問合せ種別<span class="hissu">*</span></td>
<td><select name="EnquiryClass" style="display:none">
<option value="SalesAgent">販売代理店</option>
<option value="OEM">OEM開発</option>
<option value="Other">その他</option>
<option selected="selected"><%= @EnquiryClass %></option>
</select>
<%= @EnquiryClass %></td>
</tr>
<tr>
<td>部署名<span class="hissu">*</span></td>
<td><td><input type="text" name="PostName" size="40" style="display:none" value="<%= @PostName %>"><%= @PostName %></td>
</tr>
<tr>
<td>お名前(カナ)<span class="hissu">*</span></td>
<td><input type="text" name="NameKana" size="40" style="display:none" value="<%= @NameKana %>"><%= @NameKana %></td>
</tr>
<tr>
<td>お名前(漢字)<span class="hissu">*</span></td>
<td><input type="text" name="NameKanji" size="40" style="display:none" value="<%= @NameKanji %>"><%= @NameKanji %></td>
</tr>
<tr>
<td>郵便番号</td>
<td><input type="text" name="ZipCode" size="40" style="display:none" value="<%= @ZipCode %>"><%= @ZipCode %></td>
</tr>
<tr>
<td>都道府県</td>
<td><input type="text" name="AdministrativeDivisions" size="40" style="display:none" value="<%= @AdministrativeDivisions %>"><%= @AdministrativeDivisions %></td>
</tr>
<tr>
<td>市町村郡</td>
<td><input type="text" name="LocalAuthorityCounty" size="40" style="display:none" value="<%= @LocalAuthorityCounty %>"><%= @LocalAuthorityCounty %></td>
</tr>
<tr>
<td>番地</td>
<td><input type="text" name="HouseNumber" size="40" style="display:none" value="<%= @HouseNumber %>"><%= @HouseNumber %></td>
</tr>
<tr>
<td>電話番号<span class="hissu">*</span></td>
<td><input type="text" name="TelephoneNumber" size="40" style="display:none" value="<%= @TelephoneNumber %>"><%= @TelephoneNumber %></td>
</tr>
<tr>
<td>メールアドレス<span class="hissu">*</span></td>
<td><input type="text" name="EmailAddress" size="40" style="display:none" value="<%= @EmailAddress %>"><%= @EmailAddress %></td>
</tr>
<tr>
<td height="109">お問い合わせ内容<span class="hissu">*</span></td>
<td><input type="text" name="EmailAddressAff" size="40" style="display:none" value="<%= @ContentOfInquiry %>"><%= @ContentOfInquiry %></td>
</tr>
</table>
<input type="submit" value="送信">
</form>
<br>
<table border="0" cellspacing="0" cellpadding="0" width="200">
<tr>
<td><a class="btn" href="javascript:history.back();">再編集</a></td>
<td><a class="btn" href="http://hogehoge.jp/">TOPページ</a></td>
</tr>
</table>
</body>
</html>
--<テンプレート 確認画面>-- ここまで
--<テンプレート エラー画面:errormsg.html>-- ここから
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>販売代理店・OEM お問い合わせフォーム</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<link rel="stylesheet" type="text/css" href="../css/request_oem.css" media="all">
</head>
<body>
<h1>販売代理店/OEM 入力エラー</h1>
<p>
<h2>不正なデータが入力されたか、必須項目にデータが入力されておりません</h2>
<br>
<p> <span class="hissu"><%= err_msg %></span><br>
該当する入力エラーを修正してください。<br>
<br>
必須項目は全て入力しなければなりません。<br>
メールアドレスはドメインネームまで正しく入力されていなければなりません。<br>
<br>
</p>
<table border="0" cellspacing="0" cellpadding="0" width="200">
<tr>
<td><a class="btn" href="javascript:history.back();">再編集</a></td>
<td><a class="btn" href="http://hogehoge.jp/">TOPページ</a></td>
</tr>
</table>
</body>
</html>
--<テンプレート エラー画面:errormsg.html>-- ここまで