ユーザープロフィール画面
Twitterにユーザープロフィール画面を追加します。
HTML
Viewsフォルダ内に「profile.php」ファイルを作成します。
![VSCode](https://tech-popeye.com/wp-content/uploads/2021/11/vscode_1_compressed-4-1024x432.png)
profile.phpに以下の内容を書きます。
htdocs/Twitter/Views/profile.php
<!DOCTYPE html>
<html>
<lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="../Views/css/style.css">
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="../Views/js/like.js"></script>
<title>プロフィール</title>
</head>
<body class="home profile">
<div class="container">
<div class="side">
<div class="side-inner">
<ul class="nav flex-column">
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt="" class="icon"></a></li>
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
<li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
<li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
<li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
<li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt="" class="icon"></a></li>
<li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt="" class="my-icon"></li>
</ul>
</div>
</div>
<div class="main">
<div class="main-header">
<h1>鈴木一郎</h1>
</div>
<!-- プロフィールエリア -->
<div class="profile-area">
<div class="top">
<div class="user"><img src="../Views/img_uploaded/user/sample.jpg" alt=""></div>
<button class="btn btn-reverse btn-sm">プロフィール編集</button>
</div>
<div class="name">鈴木一郎</div>
<div class="text-muted">@ichiro.suzuki</div>
<div class="follow-follower">
<div class="follow-count">1</div>
<div class="follow-text">フォロー中</div>
<div class="follow-count">1</div>
<div class="follow-text">フォロワー</div>
</div>
</div>
<!-- 仕切りエリア -->
<div class="ditch"></div>
<!-- ツイート一覧エリア -->
</div>
</div>
</body>
</html>
サイド領域(「side」クラスをもつdiv要素内)は、home.phpと同じです。
メイン領域について、「btn-reverse」「btn-sm」「text-muted」はBootstrap用のクラスです。装飾のために使われます。
CSS
style.cssを以下のように修正します。
htdocs/Twitter/Views/css/style.css
/* 全体 */
.container {
display: flex;
}
.side {
width: 90px;
}
.main {
width: calc(100% - 90px);
border-left: 1px solid #eef;
border-right: 1px solid #eef;
max-width: 600px;
}
.btn {
background-color: #1af;
color: #fff;
font-size: 15px;
font-weight: bold;
}
/* サイド領域 */
.side .side-inner {
position: sticky;
height: 100vh;
text-align: center;
}
.side .side-inner img {
width: 35%;
margin-bottom: 15px;
}
.side .side-inner img.icon {
width: 70%;
}
.side .side-inner img.my-icon {
width: 70%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
/* メイン領域 */
.main .main-header {
padding: 20px;
border-bottom: 1px solid #eef;
}
.main .main-header h1 {
font-size: 20px;
font-weight: bold;
}
.home .tweet-post {
display: flex;
padding: 10px;
}
.home .tweet-post .my-icon {
width: 80px;
padding: 5px 15px 10px 10px;
}
.home .tweet-post .my-icon img {
width: 100%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
.home .tweet-post .input-area {
width: calc(100% - 80px);
}
.home .tweet-post .input-area textarea {
border: 0;
width: 100%;
height: 100px;
resize: none;
}
.home .tweet-post .input-area textarea:focus {
outline: none;
}
.home .tweet-post .input-area .bottom-area {
display: flex;
justify-content: space-between;
border-top: 1px solid #eef;
padding-top: 8px;
}
.home .ditch {
height: 15px;
background-color: #f7f8f8;
border-top: 1px solid #eef;
border-bottom: 1px solid #eef;
}
.home .tweet-list .tweet {
padding: 10px;
display: flex;
border-bottom: 1px solid #eef;
}
.home .tweet-list .tweet .user {
width: 80px;
padding: 5px 15px 10px 10px;
}
.home .tweet-list .tweet .user img {
width: 100%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
.home .tweet-list .tweet .name {
padding-top: 5px;
}
.home .tweet-list .tweet .name a {
color: #122;
}
.home .tweet-list .tweet .name a .nickname {
color: #122;
font-size: 17px;
font-weight: bold;
}
.home .tweet-list .tweet .name a .user-name {
color: #444;
font-size: 14px;
}
.home .tweet-list .tweet .content {
width: calc(100% - 60px);
}
.home .tweet-list .tweet .content p {
font-size: 16px;
padding: 8px 0 0 0;
margin-bottom: 8px;
}
.home .tweet-list .tweet .content img.post-image {
width: 100%;
border-radius: 15px;
margin-bottom: 10px;
margin-right: 5px;
border: 1px solid #eef;
}
.home .tweet-list .tweet .content .icon-list {
display: flex;
}
.home .tweet-list .tweet .content .icon-list .like img {
width: 25px;
margin-right: 10px;
cursor: pointer;
}
.home .tweet-list .tweet .content .icon-list .like-count {
width: 25px;
padding-top: 2px;
color: #444;
}
/* ユーザー登録 */
.signup .form-signup {
max-width: 330px;
padding: 15px;
margin-left: auto;
margin-right: auto;
}
.signup .logo {
margin-bottom: 30px;
width: 50px;
}
.signup h1 {
font-size: 20px;
margin-bottom: 20px;
}
.signup input {
margin-bottom: 10px;
}
/* ★変更箇所(ここから)*/
/* ユーザープロフィール */
.profile .profile-area {
padding: 25px;
}
.profile .profile-area .top {
display: flex;
justify-content: space-between;
}
.profile .profile-area .top .user {
width: 30%;
padding: 5px 15px 10px 0;
}
.profile .profile-area .top .user img {
width: 100%;
border-radius: 50%;
border: 3px solid rgb(235, 238, 240);
}
.profile .profile-area .top button {
height: 32px;
}
.profile .profile-area .name {
font-size: 18px;
font-weight: bold;
}
.profile .profile-area .follow-follower {
display: flex;
padding: 15px 0 10px 0;
}
.profile .profile-area .follow-follower .follow-count {
width: 30px;
font-size: 16px;
font-weight: bold;
}
.profile .profile-area .follow-follower .follow-text {
width: 100px;
font-size: 16px;
margin-right: 30px;
color: #778;
}
/* ★変更箇所(ここまで)*/
![ブラウザ](https://tech-popeye.com/wp-content/uploads/2021/11/browser_1_compressed-5-1024x662.png)
ユーザープロフィール編集モーダル
ユーザープロフィールを編集するモーダル(=ポップアップ)を追加します。
HTML
profile.phpを以下のように修正します。
htdocs/Twitter/Views/profile.php
<!DOCTYPE html>
<html>
<lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="../Views/css/style.css">
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<!-- ★変更箇所1(ここから)-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous" defer></script>
<!-- ★変更箇所1(ここまで)-->
<script src="../Views/js/like.js"></script>
<titleプロフィール</title>
</head>
<body class="home profile">
<div class="container">
<div class="side">
<div class="side-inner">
<ul class="nav flex-column">
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt="" class="icon"></a></li>
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
<li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
<li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
<li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
<li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt="" class="icon"></a></li>
<li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt="" class="my-icon"></li>
</ul>
</div>
</div>
<div class="main">
<div class="main-header">
<h1>鈴木一郎</h1>
</div>
<!-- プロフィールエリア -->
<div class="profile-area">
<div class="top">
<div class="user"><img src="../Views/img_uploaded/user/sample.jpg" alt=""></div>
<!-- ★変更箇所2(ここから)-->
<button class="btn btn-reverse btn-sm" data-bs-toggle="modal" data-bs-target="#js-modal">プロフィール編集</button>
<!-- ★変更箇所2(ここまで)-->
</div>
<div class="name">鈴木一郎</div>
<div class="text-muted">@ichiro.suzuki</div>
<div class="follow-follower">
<div class="follow-count">1</div>
<div class="follow-text">フォロー中</div>
<div class="follow-count">1</div>
<div class="follow-text">フォロワー</div>
</div>
</div>
<!-- 仕切りエリア -->
<div class="ditch"></div>
<!-- ツイート一覧エリア -->
</div>
</div>
<!-- ★変更箇所3(ここから)-->
<!-- モーダル -->
<div class="modal" id="js-modal">
<div class="modal-dialog">
<div class="modal-content">
<form action="profile.php" method="post" enctype="multipart/form-data">
<div class="modal-header">
<h5 class="modal-title">プロフィール編集</h5>
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="user">
<img src="../Views/img_uploaded/user/sample.jpg" alt="">
</div>
<div class="mb-3">
<label for="" class="mb-1">プロフィール写真</label>
<input type="file" class="form-control form-control-sm" name="image">
</div>
<input type="text" class="form-control mb-4" name="nickname" value="鈴木一郎" placeholder="ニックネーム" maxlength="50" required>
<input type="text" class="form-control mb-4" name="name" value="ichiro.suzuki" placeholder="ユーザー名" maxlength="50" required>
<input type="email" class="form-control mb-4" name="email" value="ichiro.suzuki@hoge.com" placeholder="メールアドレス" maxlength="254" required>
<input type="password" class="form-control mb-4" name="password" value="" placeholder="" minlength="4" maxlength="128">
</div>
<div class="modal-footer">
<button class="btn btn-reverse" data-bs-dismiss="modal">キャンセル</button>
<button class="btn" type="submit">保存する</button>
</div>
</form>
</div>
</div>
</div>
<!-- ★変更箇所3(ここまで)-->
</body>
</html>
変更箇所1では、モーダル用のフレームワーク(以後、モーダルフレームワークと言います)を読み込んでいます。このフレームワークを使うことで、簡単にモーダル表示をすることができます。
変更箇所2について解説します。
「data-bs-toggle」属性は、モーダルフレームワーク用の属性です。値として「modal」を指定することで、当該ボタン要素を押すとモーダルが表示されるようになります。
「data-bs-target」属性は、モーダルフレームワーク用の属性です。どの要素をモーダルとして使うかを指定します。ここでは、「js-modal」というidをもつ要素(変更箇所3のdiv要素内です)を指定しています。その要素の内容が、モーダルの表示内容になります。
変更箇所3について解説します。
上記の通り、このdiv要素内の内容が、モーダルの表示内容になります。
「modal」「modal-dialog」「modal-content」「modal-header」「modal-title」「modal-footer」はモーダルフレームワーク用のクラスです。モーダル表示のために使われます。
同じく、「data-bs-dismiss=”modal”」「aria-label=”Close”」はモーダルフレームワーク用の属性です。モーダル表示のために使われます。
「btn-close」はBootstrap用のクラスです。装飾のために使われます。
CSS
style.cssを以下のように修正します。
htdocs/Twitter/Views/css/style.css
/* 全体 */
.container {
display: flex;
}
.side {
width: 90px;
}
.main {
width: calc(100% - 90px);
border-left: 1px solid #eef;
border-right: 1px solid #eef;
max-width: 600px;
}
.btn {
background-color: #1af;
color: #fff;
font-size: 15px;
font-weight: bold;
}
/* サイド領域 */
.side .side-inner {
position: sticky;
height: 100vh;
text-align: center;
}
.side .side-inner img {
width: 35%;
margin-bottom: 15px;
}
.side .side-inner img.icon {
width: 70%;
}
.side .side-inner img.my-icon {
width: 70%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
/* メイン領域 */
.main .main-header {
padding: 20px;
border-bottom: 1px solid #eef;
}
.main .main-header h1 {
font-size: 20px;
font-weight: bold;
}
.home .tweet-post {
display: flex;
padding: 10px;
}
.home .tweet-post .my-icon {
width: 80px;
padding: 5px 15px 10px 10px;
}
.home .tweet-post .my-icon img {
width: 100%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
.home .tweet-post .input-area {
width: calc(100% - 80px);
}
.home .tweet-post .input-area textarea {
border: 0;
width: 100%;
height: 100px;
resize: none;
}
.home .tweet-post .input-area textarea:focus {
outline: none;
}
.home .tweet-post .input-area .bottom-area {
display: flex;
justify-content: space-between;
border-top: 1px solid #eef;
padding-top: 8px;
}
.home .ditch {
height: 15px;
background-color: #f7f8f8;
border-top: 1px solid #eef;
border-bottom: 1px solid #eef;
}
.home .tweet-list .tweet {
padding: 10px;
display: flex;
border-bottom: 1px solid #eef;
}
.home .tweet-list .tweet .user {
width: 80px;
padding: 5px 15px 10px 10px;
}
.home .tweet-list .tweet .user img {
width: 100%;
border-radius: 50%;
border: 0.2px solid #aaa;
}
.home .tweet-list .tweet .name {
padding-top: 5px;
}
.home .tweet-list .tweet .name a {
color: #122;
}
.home .tweet-list .tweet .name a .nickname {
color: #122;
font-size: 17px;
font-weight: bold;
}
.home .tweet-list .tweet .name a .user-name {
color: #444;
font-size: 14px;
}
.home .tweet-list .tweet .content {
width: calc(100% - 60px);
}
.home .tweet-list .tweet .content p {
font-size: 16px;
padding: 8px 0 0 0;
margin-bottom: 8px;
}
.home .tweet-list .tweet .content img.post-image {
width: 100%;
border-radius: 15px;
margin-bottom: 10px;
margin-right: 5px;
border: 1px solid #eef;
}
.home .tweet-list .tweet .content .icon-list {
display: flex;
}
.home .tweet-list .tweet .content .icon-list .like img {
width: 25px;
margin-right: 10px;
cursor: pointer;
}
.home .tweet-list .tweet .content .icon-list .like-count {
width: 25px;
padding-top: 2px;
color: #444;
}
/* ユーザー登録 */
.signup .form-signup {
max-width: 330px;
padding: 15px;
margin-left: auto;
margin-right: auto;
}
.signup .logo {
margin-bottom: 30px;
width: 50px;
}
.signup h1 {
font-size: 20px;
margin-bottom: 20px;
}
.signup input {
margin-bottom: 10px;
}
/* ユーザープロフィール */
.profile .profile-area {
padding: 25px;
}
.profile .profile-area .top {
display: flex;
justify-content: space-between;
}
.profile .profile-area .top .user {
width: 30%;
padding: 5px 15px 10px 0;
}
.profile .profile-area .top .user img {
width: 100%;
border-radius: 50%;
border: 3px solid rgb(235, 238, 240);
}
.profile .profile-area .top button {
height: 32px;
}
.profile .profile-area .name {
font-size: 18px;
font-weight: bold;
}
.profile .profile-area .follow-follower {
display: flex;
padding: 15px 0 10px 0;
}
.profile .profile-area .follow-follower .follow-count {
width: 30px;
font-size: 16px;
font-weight: bold;
}
.profile .profile-area .follow-follower .follow-text {
width: 100px;
font-size: 16px;
margin-right: 30px;
color: #778;
}
/* ★変更箇所(ここから)*/
.profile .modal img {
width: 30%;
margin-bottom: 20px;
border-radius: 50%;
border: 3px solid rgb(235, 238, 240);
}
/* ★変更箇所(ここまで)*/
ここまでで、以下のようにモーダル表示されればOKです。
![](https://tech-popeye.com/wp-content/uploads/2021/11/modal_summary_1_compressed-1024x452.png)
他のユーザーのプロフィール画面
他のユーザーのプロフィール画面を追加します。
フォローをできるようにします。
HTML
profile.phpを以下のように修正します。
htdocs/Twitter/Views/profile.php
<!DOCTYPE html>
<html>
<lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="../Views/css/style.css">
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous" defer></script>
<script src="../Views/js/like.js"></script>
<title>プロフィール</title>
</head>
<body class="home profile">
<div class="container">
<div class="side">
<div class="side-inner">
<ul class="nav flex-column">
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/1.svg" alt="" class="icon"></a></li>
<li class="nav-item"><a href="home.php" class="nav-link"><img src="../Views/img/2.svg" alt=""></a></li>
<li class="nav-item"><a href="search.php" class="nav-link"><img src="../Views/img/3.svg" alt=""></a></li>
<li class="nav-item"><a href="notification.php" class="nav-link"><img src="../Views/img/4.svg" alt=""></a></li>
<li class="nav-item"><a href="profile.php" class="nav-link"><img src="../Views/img/5.svg" alt=""></a></li>
<li class="nav-item"><a href="post.php" class="nav-link"><img src="../Views/img/6.svg" alt="" class="icon"></a></li>
<li class="nav-item"><img src="../Views/img_uploaded/user/sample.jpg" alt="" class="my-icon"></li>
</ul>
</div>
</div>
<div class="main">
<div class="main-header">
<h1>鈴木一郎</h1>
</div>
<!-- プロフィールエリア -->
<div class="profile-area">
<div class="top">
<div class="user"><img src="../Views/img_uploaded/user/sample.jpg" alt=""></div>
<!-- ★変更箇所(ここから)-->
<?php if (isset($_GET['user_id'])) : ?>
<!-- 他のユーザーのWebページ -->
<?php if (isset($_GET['case'])) : ?>
<button class="btn btn-sm">フォローをやめる</button>
<?php else : ?>
<button class="btn btn-sm btn-reverse">フォローする</button>
<?php endif; ?>
<?php else : ?>
<!-- 自分のWebページ -->
<button class="btn btn-reverse btn-sm" data-bs-toggle="modal" data-bs-target="#js-modal">プロフィール編集</button>
<?php endif; ?>
<!-- ★変更箇所(ここまで)-->
</div>
<div class="name">鈴木一郎</div>
<div class="text-muted">@ichiro.suzuki</div>
<div class="follow-follower">
<div class="follow-count">1</div>
<div class="follow-text">フォロー中</div>
<div class="follow-count">1</div>
<div class="follow-text">フォロワー</div>
</div>
</div>
<!-- 仕切りエリア -->
<div class="ditch"></div>
<!-- ツイート一覧エリア -->
</div>
</div>
<!-- モーダル -->
<div class="modal" id="js-modal">
<div class="modal-dialog">
<div class="modal-content">
<form action="profile.php" method="post" enctype="multipart/form-data">
<div class="modal-header">
<h5 class="modal-title">プロフィール編集</h5>
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="user">
<img src="../Views/img_uploaded/user/sample.jpg" alt="">
</div>
<div class="mb-3">
<label for="" class="mb-1">プロフィール写真</label>
<input type="file" class="form-control form-control-sm" name="image">
</div>
<input type="text" class="form-control mb-4" name="nickname" value="鈴木一郎" placeholder="ニックネーム" maxlength="50" required>
<input type="text" class="form-control mb-4" name="name" value="ichiro.suzuki" placeholder="ユーザー名" maxlength="50" required>
<input type="email" class="form-control mb-4" name="email" value="ichiro.suzuki@hoge.com" placeholder="メールアドレス" maxlength="254" required>
<input type="password" class="form-control mb-4" name="password" value="" placeholder="" minlength="4" maxlength="128">
</div>
<div class="modal-footer">
<button class="btn btn-reverse" data-bs-dismiss="modal">キャンセル</button>
<button class="btn" type="submit">保存する</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
profile.phpにアクセスする際、クエリストリングで「user_id=値」の指定があれば他のユーザーのWebページの内容を表示し、指定がなければ自分のWebページの内容を表示するようにしています(細かいWebページ内容の切り替えは、後ほどコーディングしていきます)。
さらに、クエリストリング「case=値」の指定の有無で、ボタンの表記を切り替えるようにしています。
![ブラウザ](https://tech-popeye.com/wp-content/uploads/2021/11/browser_3_compressed-3-1024x688.png)
![ブラウザ](https://tech-popeye.com/wp-content/uploads/2021/11/browser_4_compressed-2-1024x696.png)
![ブラウザ](https://tech-popeye.com/wp-content/uploads/2021/11/browser_5_compressed-2-1024x693.png)
CSS
前節のCSSから変更はありません。
ここまで出来たら、変更内容をコミットし、GitHubにプッシュして下さい。
本節の説明は以上になります。