
自由研究でSNSをつくろう! メニュー構成編
1週間ぶりのごぶさたです! 自由研究によるSNS作りもいよいよ後半戦、今回はこれまでに作った各種ページをつなぐためのメニューを導入します。
サイトメニューと個人メニューをわける
メニューといっても、自由研究SNS(仮)は「ミニマム」を標榜するSNSですからたくさんの要素はありません。それでもわけて考えなければいけないのが、「サイト全体のメニュー」と「個人」のメニューの構成です。
サイト全体のメニューには、そもそもサイトのトップページへ戻る機能や、ログイン/ログアウトなどの機能が必要です。企業が運営するようなSNSなら通報窓口などもこのメニューに加えるべきでしょう。
一方、個人メニューはSNSにログインしたあと、ユーザーが行なう行為のための機能を配置します。ホーム画面(Twitterで言えばタイムライン)を表示する、プロフィールを確認する、といった感じです。また、今回は発言も個人メニューから行なえるようにしようと思います。
なお[ログアウト]は概念的には個人メニューにあった方が自然なのですが、対になる[ログイン]はサイトメニューにあるほうがわかりやすいので、[ログアウト]もサイトメニューに配置することにしました。もっとも、べつにログアウトさせやすくする必要はないので目立たない場所にひっそり置いてあってもいいと思います。
さっそく作成!
というわけでスタイル設定などを行ない、実際にメニューを作ってみました!

おおお、なんかすっかり「できた」感じになってきました。
ちなみにこの画面写真は、『Microsoft Edge』のデバッガー(F12キー)でスマホサイズの表示をテストしたものです。デバッガーは『Chrome』の方が使いやすいですけどね。
内容はパッと見でだいたいわかると思いますが、サイトメニューは画面上部(TOP)に固定し、個人メニューは画面下部(BOTTOM)に固定しています。
下部の「テストマン!!」とユーザー名が書かれた部分をクリックするとプロフィール画面へ移動、顔アイコンをクリックするとホーム画面へ移動、という具合いです。発言用のボックスはまだ仮設置のもので、次回以降できちんと実装していく予定です。
このあたりの設定については末尾にソースコードを載せておきますので、自作したい人は参考にしてみてください。
コード整理がたいへん!
さて、見た目はサクッとできあがったわけですが、たいへんなのはコード整理の方でした。
これまではホーム画面やプロフィール画面でそれぞれ独立して動作できればよかったのですが、どこからでもログイン/ログアウトできるようにしたことや、どこでもログイン中のユーザー情報を表示させる必要がでてきたため、サイト全体で処理の仕組みを共通化しなければいけなくなったのです。
そのため、情報を表示する前に行なう必要がある事前準備(例えばログイン時のユーザー存否確認やパスワード比較、ログインしたユーザー情報のロード等)は、先にひとつの共通処理(common.php)として実行するようにコードを変更しました。
一方、home.php(ホーム画面)やprofile.php(プロフィール画面)といった個別ページのコードは、結果を"表示"する機能が中心になります。
例[ホーム画面を呼び出した場合の処理]
home.php実行
├common.php呼び出し(★共通)
│ ├引数受け取り(フォームやURLから)
│ ├共通変数(pathなど)の初期化/設定
│ ├各種判定(ログイン時の判定等)
│ └ユーザーデータのロード等
├home独自の判定処理
├style.php呼び出し(★共通)
│ ├style設定
│ ├TOPメニュー表示(関数)
│ └BOTTOMメニュー表示(関数)
└home画面の内容を表示
コード自体はこれまでに作ったものをまとめなおすだけとも言えるので「作り直し」のような手間がかかるわけではありません。ただし、「制御」の仕組みが変わったのでテスト(&デバッグ)をきちんとやらないといけないのがたいへんでした。実際、バグが出るわ出るわ……(涙)。
とはいえ、苦労した甲斐もあってコードはスマートになりました。次回、いよいよ「発言」できるようにして、SNS作りの最終段階へと進んでいきますよ!
(つづく)
参考ソースコード(style.php)
<style>
/* TOPメニュー */
#TopMenu{
position:fixed;
top:0px;
left:0px;
width:100%;
height:24px;
padding-top:6px;
padding-bottom:6px;
padding-left:0px;
padding-right:0px;
border-bottom:solid 4px rgba(200,198,195,1.0);
background-color:rgba(60,58,55,1.0);
font-size:16px;
}
#TopMenu a{
color:rgba(210,210,210,1.0);
}
#TopMenu a:hover{
color:rgba(245,245,245,1.0);
}
.LabelToIndex{
float:left;
margin-left:12px;
font-weight:bolder;
}
.LabelToLogout{
float:right;
margin-right:12px;
}
#page_title_bar{
position:fixed;
top:36px;
left:0px;
height:24px;
padding-top:6px;
padding-bottom:2px;
padding-left:12px;
padding-right:18px;
background-color:rgba(200,198,195,0.5);
border-bottom-right-radius:12px;
letter-spacing:-1px;
}
a #page_title_bar{
color:rgba(60,58,55,0.8);
font-weight:bolder;
}
a:hover #page_title_bar{
color:rgba(60,58,55,1.0);
}
</style>
<?php
function utPrintTopMenu(){
//TOPメニューを出力
global $scene_now;
global $main_title;
global $sub_title;
global $url_index;
global $url_home;
global $url_return;
global $token;
global $login;
global $target_user;
echo '<div id="TopMenu">';
//INDEXへ戻る
$temp_title=$main_title;
$temp_href=$url_index;
echo '<label class="LabelToIndex"><a href="'.$temp_href.'">'.$temp_title.'</a></label>';
//ログイン/ログアウト
$temp_view=true; //表示フラグON
if($login==0){
$temp_title='ログイン';
if($scene_now=='profile'){
$temp_href=$url_home.'?return_id='.$target_user;
}else{
$temp_href=$url_home; //homeへ遷移
}
if($scene_now=='home'){
$temp_view=false; //homeでは表示しない
}
}else{
$temp_title='ログアウト';
$temp_href=$url_home.'?/'.$token.'/logout';
}
if($temp_view==true){
echo '<label class="LabelToLogout"><a href="'.$temp_href.'">'.$temp_title.'</a></label>';
}
echo '</div>';
//ページタイトルバー
$temp_href=$url_return;
echo '<a href="'.$temp_href.'">';
echo '<div id="page_title_bar">';
echo $sub_title;
echo '</div>';
echo '</a>';
}
?>
<style>
#BottomMenu{
position:fixed;
z-index:9999;
bottom:0;
left:0px;
width:500px;
height:112px;
padding-top:10px;
padding-bottom:10px;
padding-left:12px;
padding-right:0px;
border-top-right-radius:30px;
border-top:solid 4px rgba(150,150,150,1.0);
border-right:solid 4px rgba(150,150,150,1.0);
background-color:rgba(220,218,215,1.0);
font-size:16px;
}
@media (max-width: 513px) {
#BottomMenu{
border-top-right-radius:0px;
border-right:0px;
}
}
#me_icon{
float:left;
width:112px;
height:112px;
margin-right:10px;
}
#me_name{
display:block;
float:left;
min-width:112px;
height:22px;
margin-top:-32px;
margin-left:-12px;
padding-left:11px;
padding-right:11px;
border-top-right-radius:20px;
background-color:rgba(80,78,77,1.0);
font-size:15px;
font-weight:bolder;
text-align:center;
}
a #me_name{
color:rgba(255,255,255,0.8);
}
a:hover #me_name{
color:rgba(255,255,255,0.95);
}
#chat_region{
float:left;
width:368px;
height:108px;
margin-left:0px;
margin-top:2px;
background-color:white;/* transparent;*/
border-radius:8px;
}
input[type="submit"][name="chat_write"]{
float:left;
width:80px;
height:20px;
padding:0px;
border:0px;
border-top-right-radius:8px;
background-color:rgba(240,180,20,0.8);
color:rgba(250,250,250,0.9);
font-size:14px;
}
input[type="submit"][name="chat_write"]:hover{
background-color:rgba(250,250,250,1.0);
color:rgba(240,180,20,0.8);
}
input[type="text"][name="chat_theme"]{
float:left;
width:288px;
padding-top:3px;
padding-bottom:0px;
padding-left:6px;
padding-right:0px;
border:0px;
border-top-left-radius:8px;
background-color:rgba(250,200,20,0.7);
color:rgba(50,0,0,0.75);
font-size:15px;
font-weight:bolder;
letter-spacing:0px;
}
textarea[name="chat_message"]{
width:100%;
height:88px;
padding-top:6px;
padding-bottom:4px;
padding-left:6px;
padding-right:3px;
border:0px;
border-bottom-left-radius:8px;
border-bottom-right-radius:8px;
background-color:rgba(250,220,30,0.4);
color:rgba(50,20,0,0.75);
font-size:15px;
font-weight:bolder;
font-family:inherit;
letter-spacing:0px;
line-height:130%;
}
input[type="text"][name="chat_theme"]:focus{
color:rgba(50,0,0,0.9);
}
textarea[name="chat_message"]:focus{
color:rgba(50,0,0,0.9);
}
input[type="text"][name="chat_theme"]::placeholder{
color:rgba(30,0,0,0.4);
}
textarea[name="chat_message"]::placeholder{
color:rgba(30,0,0,0.4);
}
</style>
<?php
function utPrintBottomMenu(){
//BOTTOMメニューを出力
global $login;
global $me_icon_path;
global $me_icon_frame;
global $url_home;
global $url_profile;
global $url_return;
global $account_id;
global $token;
global $me_nickname;
if($login==0){
//(未ログイン)
}else{
//(ログイン中)
echo '<div id="BottomMenu">';
echo '<form action="'.$url_return.'" method="post">';
echo '<input type="hidden" name="form_command" value="chat">'; //home
echo '<input type="hidden" name="account_id" value="'.$account_id.'"'; //account_id
echo '<input type="hidden" name="token" value="'.$token.'">'; //token
//名前
$temp_href=$url_profile.'?'.$account_id;
echo '<a href="'.$temp_href.'">';
echo '<div id="me_name">'.utUserShortName($account_id,$me_nickname).'</div>';
echo '</a>';
//アイコン
$temp_href=$url_home;
echo '<div id="me_icon">';
echo '<a href="'.$temp_href.'">'.utPrintIcon($me_icon_path,$me_icon_frame).'</a>';
echo '</div>';
//チャット領域
echo '<div id="chat_region">';
echo '<input type="text" name="chat_theme" list="branch" placeholder="・テーマ記入or空白にしてリスト選択" maxlength="20" autocomplete="off">';
echo '<datalist id="branch">';
echo '<option value="近況報告">';
echo '<option value="自由研究">';
echo '<option value="その他">';
echo '</datalist>';
echo '<input type="submit" name="chat_write" value="▶">';
echo '<textarea name="chat_message" placeholder="・メッセージ記入" maxlength="200"></textarea>';
echo '</div>';
//締め
echo '</form>';
echo '</div>';
}
}
?>