• ベストアンサー

cgi+htmlテンプレート使用

「cgiファイルからhtmファイルを読み込んで、部分的に差し替えの上、再度htmファイルに書き出す」ということを考えています。 で、htmファイルのソースの中に<-- start --><-- end -->のようなタグを仕込んでおいて、cgiの方からその間の部分に情報を挿入するという形を考えています。 具体的には、 open(IN, $htm_file) || error("読込エラー"); print "Content-type: text/html\n\n"; while (<IN>) { if (.....<--start-->があったなら......) { .......$jouhouを挿入する........ } ........................................ } close(IN); のような感じを漠然と想定しているのですが、どんなもんでしょうか。どうやってやればイイのか、検討がつかないもので。うまいやり方を、お分かりの方がいましたら教えていただけませんか。

質問者が選んだベストアンサー

  • ベストアンサー
  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.5

書いた本人にも100%理解できていないのでうまく説明できる自信もありませんが・・・ ((?:(?!<!-- end -->).)*) を内側のカッコから分解すると (?!<!-- end -->) → <!-- end -->ではない (?:~.) → 任意の一字(後方参照を作らないグループ化) (~*) → 0回以上の繰り返し 要約すると <!-- end -->ではない任意一字の0回以上の繰り返し→ (<!-- start -->の後ろから)<!-- end -->までの間の0桁以上の任意の文字列。

benneb
質問者

お礼

恐れ入りました。 いろいろイジって(ピリオドをとってみたりとか)試してみましたが、この式のままでないとうまく動きませんね。 いろいろと勉強になりました。 ありがとうございました。(^з^)-☆Chu!!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.4

> $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; > の1行について、くわしく解説いただけないでしょうか。 やろうとしているのは <!-- start -->何か<!-- end --> を <!-- start -->$data[n番目]<!-- end --> に置換しています。 細かい事についてはとにかく正規表現について読み漁ってください。 参考URLに必要なことは全部書いてあると思います。 キーワードは ・置換 ・正規表現 ・s///演算子用オプション、gとs ・文字列のグループ化と後方参照 ・拡張構文、(?:..)と(?!式) 等々。。。

参考URL:
http://www.rfs.jp/sitebuilder/perl/02/09.html
benneb
質問者

補足

詳細な解説ありがとうございます。 いや~、拡張構文ですか・・・ε-(´o`)) 正規表現って驚きですね。 で、 ((?:(?!<!-- end -->).)*) の部分だけがどうしても分かりません。もし気の向くことがあったなら、アホな私メに教えていただければありがたいです。

全文を見る
すると、全ての回答が全文表示されます。
  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.3

思いっきり簡単に書くと以下のようになります。 (正規表現のあたりはもっと簡潔に書けるかもしれませんがあまり得意でないので。) あとは、置換するデータを入力フォームから受取るとかCGIとしての一般的な体裁を加えれば実用的になるかと思います。 #!/usr/bin/perl my @data = qw{123 ABCD あいうえお};# 置換するデータ my $count = 0; #読み込み open IN,'hoge.html'; read IN, my $buf, -s 'hoge.html'; close IN; #置換 $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; #書き出し open OUT,'> hoge.html'; print OUT $buf; close OUT; #終了メッセージ print <<__MESSAGE__; Content-type: text/html; <html> <head> <title>完了</title> </head> <body> <h1>完了</h1> <p>$count 置換完了</p> </body> </html> __MESSAGE__ なお、テンプレートを扱うといっても、本件ではそのテンプレート自体を更新しようとしている(置換のための制御文を残さないといけない)のでHTML::Templateモジュールはあまり向いていないと思います。 もちろん、テンプレートと表示/更新するファイルを分ければ問題ないのですが。

benneb
質問者

補足

回答ありがとうございます。 これ、うまいこと動きますね。 もしよろしければ、 $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; の1行について、くわしく解説いただけないでしょうか。 (当方、cgi学習始めたばかりなもので・・・。話は別ですが、このgooの掲示板のシステム、分かりにくいですね。使い方がまだ良く把握できてません(涙)。)

全文を見る
すると、全ての回答が全文表示されます。
  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.2

ご本人がおっしゃるとおり漠然としすぎてあまり具体的な回答は難しいのですが、start / end が一組だけなら正規表現を使った置換でも充分だと思います。 あと、参考URL(のa-Update)のような配布物もあるので検討してみては?(条件によっては有料です。) 話はそれますが、 <-- start --><-- end -->よりも <!-- start --><!-- end -->のほうがHTMLとしては格好がいいかと思います。

参考URL:
http://www.appleple.com/cgi/
benneb
質問者

お礼

回答ありがとうございます。 挿入箇所は複数ある上に、 htmソース中の<!-- start --><!-- end -->の間をカットしたいのです。 ちょっと無理っぽいですかね。 おすすめのツール、参考にしてみます。

全文を見る
すると、全ての回答が全文表示されます。
  • you-m
  • ベストアンサー率58% (190/327)
回答No.1

いわゆるテンプレートライブラリというものがあります。 Perlの場合は、HTML::Templateモジュール が有名ですかね。CPANで探すと似たようなモジュールがたくさん見つかります。車輪の再発明を嫌うならこういうものを活用するのがいいと思います。 自作のライブラリをするのであっても、こういう既成のライブラリのソースは参考になると思いますよ。 解説系の情報もありますが、たいてい個人サイトなので、ここには載せられません。サーチエンジンで検索してみてください。

benneb
質問者

お礼

回答ありがとうございます。 HTML::Templateモジュールのことは知ってはいたのですが、ちょっと調べてみます。 質問者が掲載するのもナンですが、 http://homepage3.nifty.com/hippo2000/perltips/html/template.htm が分かりやすそうです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 振り分けcgiについて

    現在下記のように書かれているcgiでトップページの振り分けをしています。今までは各htmに飛ばしていたのですが、今度モバイルのみcgi へ飛ばしたいのですが、i.htmの部分をmi.cgiと書き換えてもうまく飛びません。どうしたらcgiへ飛ぶようになるのでしょうか? $vjump='.i.htm'; #SoftBank用 $ijump='./i.htm'; #i-MODE用 $ejump = './i.htm'; #EZWEB用 $pcjump = './index.htm'; #PC,その他 $USR = $ENV{'HTTP_USER_AGENT'}; if ($USR =~ /^DoCoMo/) { $lct = $ijump; } elsif ($USR =~ /UP\.Browser/) { $lct = $ejump; } elsif ($USR =~ /^SoftBank/ || $USR =~ /^Vodafone/ || $USR =~ /^J-PHONE/) { $lct = $vjump; } else { $lct = $pcjump; } &go; exit; sub go { print "Content-type: text/html\n\n"; open(IN, $lct); while (<IN>) { print; } close(IN); } exit;

    • 締切済み
    • CGI
  • CGI経由でのPDFファイルをダウンロード

    こんにちは。 CGIの初心者です。 今CGI経由でのPDFファイルをダウンロードするというプログラムを作っています。 ただ、ダウンロードしたファイルは開けなく、エラーが出ます。ファイルを確認すると0バイトです。原因はよく分からないので、誰かが教えてください。ありがとうございます。 コードです: $filename = './data/sheet.pdf'; $source = $filename ; print qq|Content-type: text/plain\n|; print qq|Content-Disposition: attachment; filename="$filename"\n|; print qq|\n|; #-- ファイルを読み込んで出力 open(FILE,"$source"); binmode FILE; binmode STDOUT; while(read(FILE, $value, 4096)){ print $value; } close FILE;

    • 締切済み
    • CGI
  • ファイルを返すCGI

    http://tohoho.wakusei.ne.jp/lng/200003/00030611.htm などを参考にしていますが、例えばそれなら、 print <IN>;の後にclose IN;は不要ですか? ファイルを返すCGIについての説明があるサイトを教えてください。

  • Apacheでcgiができないんです。

    以下のホームページと同じように、設定したのですが。。。 http://www.futomi.com/lecture/apache/config.html 下のcgiは実行できます。 #!/usr/local/bin/perl print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE>Apache</TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; print "<H2>Welcome to my computer, Apache Server!</H2>\n"; print "</BODY>\n"; print "</HTML>\n"; しかし、下のcgiは実行できません。htmlファイル、cgiファイル共に、あるホームページからコピペしたので、間違いないと思います。ここではhtmlファイルは書きませんが、以下のURLです。 http://www2j.biglobe.ne.jp/~apollo/server/apacuse.html #!/usr/local/bin/perl $countfile= "count.dat"; open(IN, "< $countfile"); $count = <IN>; close(IN); $count++; open(OUT,"> $countfile"); print OUT $count; close(OUT); print "Content-type: text/plain\n\n"; print $count;

    • ベストアンサー
    • CGI
  • cgiでメタタグを使用するにはどうすればいいですか

    htmlでメタタグ <meta http-equiv="refresh" content="4;URL=#.html"> と、4秒でURLにジャンプしています(URLは略)。 cgiサイトもあり、cgiでも、4秒でURLにジャンプしたいです。 print "Content-type: text/html\n\n"; print "<html>\n"; print "<head>\n"; print "<meta http-equiv="refresh" content="4;URL=#.html">\n"; print "</head>\n"; print "</html>\n"; print "と\n";で単純に挟んでいますが、エラーになってしまいました。 メタタグには、特殊な書き方があるのでしょうか?

    • ベストアンサー
    • CGI
  • CGIで二つの仕事をしたい

    464487で質問したOtanoshikeです。 メール送信CGIは_mer_さんに教えて頂いたように直したら、無事動くようになりました。 今度は、このCGIの中で、メール送信後にファイル転送をしようとしています。 一応動いてはいるようなのですが、最後の確認ページが出ません。 どこが悪いのでしょうか?恐らくはまた基本的なことを無視しているのでしょうね。 よろしくお願いいたします。 (a.cgi) #!/usr/bin/perl require '../mimew.pl'; require '../jcode.pl'; $sendmail = "/var/qmail/bin/sendmail"; $master_id = "ho\@hoge.net"; $msg="メッセージ"; &jcode'convert(*msg,'jis'); open (ML,"| $sendmail $master_id"); print ML $msg; close(ML); $filename=$ARGV[0]; $file="/~/~/$filename"; $filetype='x-exe'; print "Content-Disposition:attachment;filename=\"$filename\"\n"; print "Content-type:application/$filetype\n\n"; open(FILE,"$file"); while(<FILE>){ print "$_"; } close FILE; print "Content-type: text/html\n\n"; print "<html><head>\n"; print "</head>\n"; print "<body>sent.\n"; print "</body></html>\n"; exit;

    • ベストアンサー
    • CGI
  • エラーになってしまいます。

    先日、ファイルの一行だけを読込める?と質問した者です。早速教えて頂いた方法でやってみました。 open(IN,"A.txt"); while ($xx = <IN>) {   if ($. == 5) {     print $xx;   } } close(IN); とやりました。 サーバーエラーになるのでまず open(IN, "A.txt"); while ($xx = <IN>) { print $xx; } close(IN); とファイルの読み込みでやってみたのですがそれでもサーバーエラーになってしまいました。 エラーの原因がどこにあるのか、わからなく困っています。考えられるような原因は何でしょうか? ちなみにcgiのパーミッションは755です。 あとtxtファイルをどこに置けばいいのか、よくわからないいのですがそれが原因なのでしょうか?

    • ベストアンサー
    • CGI
  • 「 <!--#exec cgi="***.cgi" --> 」が表示されません

    「main.cgi」というファイルを作り、単純にHTMLを表示するだけのCGIファイルを作成しました。 こんな感じ ------------main.cgi------------ #!/usr/local/bin/perl print "Content-type:text/html\n\n"; print <<EOM; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <title></title> </head> <body> <略> </body> </html> EOM __END__ -------------------------------- それで、ほかのHTMLファイルに <!--#exec cgi="main.cgi" --> と入力してそのページを見てみると、 [an error occurred while processing this directive] 上の文章が表示されていました。 どうすれば「main.cgi」の内容を表示することができるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • 一番大きいファイルを探し出すCGI…が動かない!

    ホームページ作成中です。 以前ここで「あるフォルダ内に連番のhtmlファイルが自動作成され(1.html,2.html~~)、その中で一番数が大きいファイルを表示するCGI」というのを質問させていただきました。 その後すぐ回答が来て、なんとCGIを作っていただいたんです。で、試しに使ってみると(5~6枚くらい)、無事新しい方(数が多い方)を読み込んでくれていたので、感謝の気持ちと共に質問を解決させていただきました。 しかし、後になって問題が発生しました。 桁が上がると、新しい物を表示してくれないのです。 9.html,10.htmlがあると、9htmlの方を表示してしまうんです。 ソースは以下の通りですが、どこを変えることで2桁、3桁と対応可能でしょうか?自動生成するCGIに0001.htmlというように吐き出させればいいのかもしれませんが、そうする技術も無いので… よろしくお願いします。 ------------------------------------- #!/usr/bin/perl $DIR = "./se3_diary/"; $new = 0; opendir(DIR,$DIR); while ( $file = readdir(DIR) ) { if ( $file =~ /^(\d)+\.html$/ ) { $new = $1 if ( $new < $1 ); } } closedir(DIR); open(IN,"$DIR$new.html"); $src = join("",<IN>); close(IN); print "Content-Type: text/html\n\n"; print $src; exit();

    • ベストアンサー
    • CGI
  • 画像とtxtファイルの表示

    現在CGIでtxtファイルが表示されるように print "Content-type: text/html; charset=euc-jp\n\n"; $count = 0; $viewline = 1; open(IN, "A.txt"); while(<IN>){ if($count == ( $viewline - 1)){ $line = $_; last; } $count++; } close(IN); print "$line\n"; としています。 ここでさらに画像も一緒にCGIで表示させたいのですが、そうゆうことはできるのでしょうか? できるのであれば教えて頂きたいです。調べてみたのですがなかなか見つからなくて・・・。 よろしくお願いします。

    • 締切済み
    • CGI
このQ&Aのポイント
  • 彼女と付き合って2年が経ち、最近マンネリ化が進んできています。お金もなく、デートや新鮮な出来事がないことに悩んでいます。彼女はキュンキュンさせたいタイプですが、ずっとキュンキュンさせるのは無理だと思い、将来に不安を抱いています。
  • お互いの将来のためにお金を貯金してきた一方で、最近別れてしまうのではないかという不安が心の中に増えています。自分自身は別れたくはないので、どうすればいいかアドバイスを求めています。
  • 彼女との2年間の関係について、最近の悩みと将来への不安について相談です。マンネリ化が進み、お金もないためにデートや新鮮な出来事が少なくなってしまっています。彼女はキュンキュンさせたいタイプですが、ずっとキュンキュンさせるのは無理だと感じ、将来に対して不安を感じています。自分自身は別れたくはないので、どうすればいいかアドバイスが欲しいです。
回答を見る