CMSを自作してオリジナル動的ホームページをフルスクラッチ開発⑨公開用投稿記事ページのテンプレート作成
2021-07-22
今回は、公開用投稿記事ページのテンプレートを作成します。
星マークが作成済みのファイルです。雲マークのファイルを今回は作成します。
投稿記事のテンプテートですので、これを作成すれば、トップページの記事一覧から任意の記事をクリックすると、記事詳細の画面に遷移できるようになります。
仕組みとしては、トップページの記事一覧表示の際に、個々の記事リンクを示すため「single.php」に「記事ID」をパラメータとしてのっけているので、投稿記事のテンプレsingle.phpでは、それをGETすればデータベースから紐づいている情報を反映させる事が出来る感じです。
あと投稿記事には記事本文の他、下部の方に「前後記事へのリンク」と、「記事へのコメント欄」を設けました。
投稿記事テンプレート
single.php
<?php require_once("header.php");?> <warapper> <main> <?php require_once("pankuzu.php");?> <?php try { require_once("common/common.php"); $get = sanitize($_GET); $code = $get["n"]; $dsn = "mysql:host=localhost;dbname=test;charset=utf8"; $user = "root"; $password = ""; $dbh = new PDO($dsn, $user, $password); $dbh -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT title, img, category, time, honbun FROM blog WHERE code=$code"; $stmt = $dbh -> prepare($sql); $stmt -> execute(); //$dbh = null; $rec = $stmt -> fetch(PDO::FETCH_ASSOC); $tit = $rec["title"]; print $rec["title"]; print "<br>"; print "<div class='catetime'>"; print $rec["category"]; print "<br>"; print $rec["time"]; print "</div>"; print "<br>"; print "<img class='bunimg' src='setting/img/".$rec['img']."'>"; print "<br>"; print $rec["honbun"]; if(empty($get["cate"]) === true) { $sql = "SELECT code, title FROM blog WHERE1"; $stmt = $dbh -> prepare($sql); $stmt -> execute(); } else { $sql = "SELECT code, title FROM blog WHERE category=?"; $stmt = $dbh -> prepare($sql); $data[] = $get["cate"]; $stmt -> execute($data); } $data = array(); //$dbh = null; while(true) { $rec = $stmt -> fetch(PDO::FETCH_ASSOC); if(empty($rec["code"]) === true) { break; } $box[] = $rec["code"]; $title[] = $rec["title"]; } $maxim = count($box); $max = $maxim -1; $point = array_search($code, $box); $mae = $point -1; $ato = $point +1; print "<div class='pag2'>"; if($mae < 0) { print "<div class='posi2'></div>";; } else { print "<div class='posi2'>前の記事:"; if(empty($get["cate"]) === true) { print "<a href='single.php?n=".$box[$mae]."'>".strip_tags($title[$mae])."</a></div>"; } else { print "<a href='single.php?n=".$box[$mae]."&cate=".$get['cate']."'>".strip_tags($title[$mae])."</a></div>"; } } if($ato > $max) { print "<div class='posi2'></div>"; } else { print "<div class='posi2'>次の記事:"; if(empty($get["cate"]) === true) { print "<a href='single.php?n=".$box[$ato]."'>".strip_tags($title[$ato])."</a></div>"; } else { print "<a href='single.php?n=".$box[$ato]."&cate=".$get['cate']."'>".strip_tags($title[$ato])."</a></div>"; } } print "</div>"; print "<h3>コメントを残す</h3>"; print "<div class='comment'>"; print "<form action='comment.php' method='post'>"; print "お名前<br>"; print "<input type='text' name='name'><br>"; print "コメント<br>"; print "<textarea name='com'></textarea><br>"; print "<input type='hidden' name='code' value='".$code."'>"; print "<input type='hidden' name='tit' value='".$tit."'>"; print "<input type='submit' value='送信'>"; print "</form>"; print "</div>"; print "<br><br>"; print "<h3>コメント一覧</h3>"; $sql = "SELECT name, honbun, time FROM honcm WHERE id=? ORDER BY code DESC"; $stmt = $dbh -> prepare($sql); $data[] = $code; $stmt -> execute($data); $data = array(); $dbh = null; $rec = $stmt -> fetch(PDO::FETCH_ASSOC); if(empty($rec["name"]) === true) { print "コメントはまだありません"; } else { print "<div class='comment2'>"; print $rec["name"]."<br>"; print $rec["time"]."<br>"; print $rec["honbun"]."<br>"; print "</div>"; while(true) { $rec = $stmt -> fetch(PDO::FETCH_ASSOC); if(empty($rec["name"]) === true) { break; } print "<div class='comment2'>"; print $rec["name"]."<br>"; print $rec["time"]."<br>"; print $rec["honbun"]."<br>"; print "</div>"; } } } catch(Exception $e) { print "異常"; exit(); } ?> <?php require_once("nav.php");?> </main> <?php require_once("side.php");?> <?php require_once("footer.php");?>
cmsディレクトリにsingle.phpを作成します。
このページは、投稿記事を表示させるためのファイルになります。
初めに、記事idを示す$nのパラメータをGETし、データベースに接続して情報を反映させます。
これが動的ページの仕組み、1つのテンプレで全ての投稿記事を表示させる事が出来たりするんですよね。
続いて、前後記事へのリンクのプログラムに入ります。
前後記事リンク
$cateのパラメータの有無でif文がありますが、これは「全記事に対する前後リンク」にするのか、「カテゴリ別の前後リンク」にするかの分岐です。
index.phpはトップページなので前者になりますが、後ほど作成する「categpory.php」のカテゴリ別一覧表示のテンプレから記事にアクセスした際には、後者になります。
というかそういう仕組みにしています。
前者であれば、全ての投稿記事のtitleとcode(記事id)を、後者であれば、指定したカテゴリで全ての投稿記事のtitleとcode(記事id)を変数に配列として$boxと$titleに代入しています。
$maxim = count($box); は記事数をカウントしています。
$max = $maxim -1; は記事数-1しています。
$point = array_search($code, $box); は、配列の中から指定した値が格納されているkeyを取得してます。第1引数にkeyを知りたい値、第2引数に対象の配列を指定すれば、この場合だと$boxの配列にある$codeのkeyが取得できます。つまり、今回の場合はこれで全ての記事の中で今どこの位置にいるのか?を知る事ができます。
$mae = $point -1; 先ほど取得したkeyをー1しています。 前の記事で使います。
$ato = $point +1; 先ほど取得したkeyを+1しています。次の記事で使います。
これだけ情報が準備できれば、あとはif文で前後リンクが出来ます。
$mae < 0 なら、前に記事は存在しないので、なにも表示はさせません。
elseなら、記事は存在するので、タイトルとリンクを貼っています。
ここでまたif文がありますが、条件にempty($get["cate"]) === true としています。
つまり、「全記事に対する前後リンク」か、「カテゴリ別の前後リンク」の分岐ですね。
前者ならリンクには記事idのパラメータのみ、後者なら記事id+カテゴリidのパラメータをのっけてます。
前途した「全記事に対する前後リンク」にするのか、「カテゴリ別の前後リンク」にするのかを、リンク先で判別させるためですね。
次の記事についても要領は同じです。
コメント入力欄
続いて、記事の対するコメント入力欄になります。
ここは単に、formタグで名前とコメントを入力できるようにしているだけです。submitで入力した情報がコメントチェックのページにpostされます。
今回、コメントは「認証されれば反映」としているので、cmsよりコメント認証を行えば、その記事に対してコメントを反映させるようにしています。
honcmテーブルに認証コメントが保存されるので、そこに情報があれば反映される仕組みになっています。
それでは、ここまで完成すれば一旦トップページから一覧されている記事にアクセスしてみて下さい。
記事の内容と前後記事、コメント欄が表示されていればOKです。
※カテゴリについてはまだページを作成していないので確認はできません。
次回は、コメントチェックページを作成したいと思います。