あたらしものずきっ!

試してみたものとか、遊んでみたものを色々記してみます。

Yacafiをつかって掲示板をこしらえてみた

Yacafiを使って掲示板をこしらえてみました。そこらへんにあるレンタル掲示板より正直低性能ですが、あくまで学習用途なので。

do_*から処理を行い、&_template_param_buildにてそれぞれのテンプレート差し込み用変数をまとめてハッシュとして、templateに流してます。

perl自体の高度な機能について見識がないので、ある程度の基礎的な知識を身につけていれば多分読むのに苦労しない程度の代物です。以下をもちあわせていれば、初学者でも普通に弄れる、と思います。

  • import
  • サブルーチン
  • FileのIO操作
  • ハッシュ
  • MENTA::Template…というかMojo::Templateの使い方
  • Yacafi.pmのソースをかじる勇気
#!/usr/local/bin/perl

use strict;
use warnings;
use Yacafi extends => {
    template => {
        params   => {
            prefix   => 'html/',
            ext      => 'html',
        },
    },
};

use Fcntl qw( :DEFAULT :flock :seek );
$Yacafi::DEBUG = 1;
dispatch;

sub do_index{
    my $query = "index";
    my $args  = &_template_param_build($query);
    view_template 'index',$args;
}

sub do_post{
    my $data = {
        name => query('name'),
        mail => query('mail'),
        text => query('text'),
    };
    my $query = "post";
    my $opt   = &_template_param_build($query,$data);
    view_template 'post',$opt;
}

sub do_finish{
    my $opt;
    my $query = "finish";
    if(query('submit') eq "agree"){
        my $data = {
            name => query('name'),
            mail => query('mail'),
            text => query('text'),
        };
        &_data_save($data);
        $opt = &_template_param_build($query);
        view_template 'finish',$opt;
    }
    else{
        my $opt = &_template_param_build($query);
        view_template 'index',$opt;
    }
}

sub _template_param_build{
    my $query = shift;
    my $post_data;
    if($query eq "post"){
        $post_data = shift;
    }
    my @data  = &_data_load();
    my $res_message = '';
    if(@data ne ()){
        for my $data(@data){
            my @param = split(/<>/,$data);
            $res_message .= "<p><a href=\"mail:$param[1]\">$param[0]</a>";
            $res_message .= ":$param[2]</p>\n";
        }
    }
    my $description  = "My BBS";
    my $res = {
        res  => $res_message,
        desc => $description,
        post => $post_data,
    };
    return $res;
}

### LogFile IO

sub _data_load{
    my $logname = "log.txt";
    &_log_gen();
    open(my $fh, "<", "$logname") || die "Cannot open $logname: $!";
    flock($fh, LOCK_EX);
    my @data = <$fh>;
    close($fh);
    return @data;
}

sub _log_gen{
    my $logname = "log.txt";
    if( -e $logname){
        return;
    }
    open(my $fh, ">", $logname) || die "Cannot make $logname: $!";
    close($fh);
    chmod(0666, $logname); 
}

sub _data_save{
    my $arg     = shift;
    my $logname = "log.txt";
    &_log_gen();
    open(my $fh, ">>", $logname) || die "Cannot open $logname: $!"; 
    flock($fh, LOCK_EX);
    print $fh $arg->{name}."<>".$arg->{mail}."<>".$arg->{text}."\n";
    close($fh);
}

html/index.html

% my $args = shift;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="Content-Style-Type" content="text/css" />
        <meta http-equiv="Content-Script-Type" content="text/javascript" />
        <title>Litchey - BBS</title>
        <style type="text/css">
            <!--
             .post_element{
                 width: 250px;
             }
             #postform dl{
                 margin-left: 50px;
             }
             #post_area{
                 width: 400px;
             }
             #submit{
                 text-align: right;
             }
            -->
        </style>
        <script type="text/javascript">
           <!--
               var chk = {};
               chk.trim = function(str){
                   return str.replace(/^\s+|\s+$/g, "");
               };
               chk.inputcheck = function(){
                   var self = this;
                   var errstring = "";
                   document.getElementById("alert_message").innerHTML = "<div id=\"alert_message\">" + errstring + "</div>\n";
                   if(self.trim(document.postform.name.value) == ""){
                       errstring += "<li>Require to input name.</li>\n";
                   }
                   if(self.trim(document.postform.mail.value) == ""){
                       errstring += "<li>Require to input mail.</li>\n";
                   }
                   if(self.trim(document.postform.text.value) == ""){
                       errstring += "<li>Require to input text.</li>\n";
                   }
                   if(errstring != ""){
                       errstring = "<ul>" + errstring + "</ul>\n";
                       document.getElementById("alert_message").innerHTML = errstring;
                       return false;
                   }
                   return true;
               };
           -->
        </script>
    </head>
    <body>
        <h1>Litchey - BBS</h1>
        <p><%= $args->{desc} %></p>
        <div id="post_area">
            <div id="alert_message"></div>
            <form action="./Litchey.cgi/post" onSubmit="return chk.inputcheck()" method="POST" id="postform" name="postform">
                <input type="hidden" name="action" value="post" />
                <dl>
                     <dt>Name:</dt> 
                         <dd><input type="text" class="post_element" name="name" /></dd>
                     <dt>Mail:</dt>
                         <dd><input type="text" class="post_element" name="mail" /></dd>
                     <dt>Text:</dt>
                         <dd><input type="text" class="post_element" name="text" /></dd>
                </dl>
                <div id="submit"><input type="submit" value="Send" /></div>
            </form>
        </div>
    <%=r $args->{res} %>
    </body>
</html>

html/post.html

% my $args = shift;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="Content-Style-Type" content="text/css" />
        <title>Litchey - BBS</title>
        <style type="text/css">
            <!--
             .post_element{
                 width: 250px;
             }
             #postform dl{
                 margin-left: 50px;
             }
             #post_area{
                 width: 400px;
             }
             #submit input,#submit_dis input{
                 text-align: center;
                 width: 70px;
             }
            -->
        </style>
    </head>
    <body>
        <h1>Litchey - BBS</h1>
        <p><%= $args->{desc} %></p>
        <div id="post_area">
            <p>次の内容で投稿してよろしいですか?</p>
            <form action="./finish" method="POST" id="postform">
                <input type="hidden" name="name" value="<%= $args->{post}->{name} %>" />
                <input type="hidden" name="mail" value="<%= $args->{post}->{mail} %>" />
                <input type="hidden" name="text" value="<%= $args->{post}->{text} %>" />
                <input type="hidden" name="action" value="finish" />
                <dl>
                     <dt>Name:</dt> 
                         <dd><%= $args->{post}->{name} %></dd>
                     <dt>Mail:</dt>
                         <dd><%= $args->{post}->{mail} %></dd>
                     <dt>Text:</dt>
                         <dd><%= $args->{post}->{text} %></dd>
                </dl>
                <div id="submit">
                    <input type="submit" name="submit" value="agree" />
                </div>
            </form>
            <form action="../Litchey.cgi" method="POST" id="postform_submitonly">
                <div id="submit_dis">
                    <input type="submit" name="submit" value="disagree" />
                </div>
            </form>
        </div>
    </body>
</html>

html/finish.html

% my $arg = shift;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="Content-Style-Type" content="text/css" />
        <title>Litchey - BBS</title>
    </head>
    <body>
        <h1>Litchey - BBS</h1>
        <p>投稿完了しました。<br /><a href="../Litchey.cgi">トップページに戻る</a>
    </body>
</html>

後、YacafiのTemplateの使い方に関してはあまり細かい説明がどこにも落ちてなかったはずなので、かじった範囲でさくさくっと書いておきます。

use Yacafi extends => {
    template => {
        params   => {
            prefix   => 'html/',#フォルダ
            ext      => 'html', #拡張子
        },
    },
};

YacafiのTemplateを使用するためのパスを指定します。これらはYacafi内では$TEMPLATE_PARAMSに渡された後、

$TEMPLATE_PARAMS->{prefix}.$file.'.'.$TEMPLATE_PARAMS->{ext}

という形でtemplateファイルへのパスになります。$fileはview_templateの第一引数が当てはまります。template内でさし変える値はview_templateの第二引数に持っていきます。

view_template 'index',$hogehoge;

Templateの書き方はMojoおよびMojo::Templateに関する説明を読むとだいたい分かると思います。

参考リンク