첫번째 토이프로젝트 이름은 '수진님이 보고 계셔' 입니다. 유데미에서 배운 것과 스파르타 웹개발 종합반에서 배운 것들을 종합하여 동생을 위한 팬명록을 만드려고 합니다. 기존에 언니를 위해서 만들어 준 것을 보고 동생이 원해서 더 업그레이드 버전으로 만들기로 했습니다. 반응형 웹사이트를 만들겁니다.
1. 와이어프레임 작업하기
- 프로필과 프로필 사진
- 수진이의 한마디와 사진
- 친구들의 응원 붙이기
- 보고 있어 -> 계셔
2. 디자인 수정 요청이 들어오다
- 같이 앉아서 열심히 원하는 거 다 넣어줬더니 다시 돌아와서 갤러리 기능을 넣어달라고 합니다. 사진이 슬라이더를 통해 나타나는 것을 구현해 보기로 했습니다.
- 원하는 사진 2장을 보내라고 했더니 9장을 보내왔습니다. 다 귀여우니까 넣어달랍니다.
- 아예 요소 배치를 다 바꾸고 새로 정했습니다.
Bootstrap Carousel
갤러리 기능을 위해 Bootstrap 웹사이트 가서 Carousel 메뉴에서 퍼왔습니다.
가장 난감했던 점은 사진이 한쪽으로 쏠리고 크기 조절을 못했었던 거였습니다
결국 id 값을 붙여서 묶어서 조절했습니다.
어찌 중간으로 오긴 했는데 윈도우를 줄였을 시 오른쪽 마진이 더 큰 현상이 나타났습니다.
다 center로 설정했는데 어찌 이럴수 있는걸까요...
Index.HTML
대부분 웹개발 종합반에서 만들었던 팬명록에서 가져왔고 부트스트랩을 이용해서 css 요소를 넣었습니다.
어려웠고 다시 돌아와서 고쳐야 하는 부분은 사진입니다.
사진 크기 조절이 쉽게 되지 않았습니다. 특히 고래사진 크기를 키우고 싶은데 잘 안됩니다....
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<!-- Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Yeon+Sung&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Custom CSS -->
<title>수진이 팬명록</title>
<style>a {
color: white;
text-decoration: underline
}
#dog:hover {
color: #ffc8dd
}
#mx:hover {
color: #03045e
}
#mara:hover {
color: red;
}
img {
width: 30%;
margin: calc(10% / 6);
flex-direction: row;
}
body {
background: #023e8a;
font-family: 'Yeon Sung', cursive;
}
#propic {
justify-content: center;
}
header {
margin-top: 30px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
margin-top: 40px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
}
.headingGroup > p {
color: white;
font-size: 1.2em;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
}
.headingGroup > img {
width: 50%;
height: 50%;
}
#tem {
color: white;
font-size: 1.2em;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
}
#carousel {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
margin-bottom: 20px;
margin-top: 20px;
}
.carousel-item {
max-width: 900px;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
margin: auto;
}
.quote p {
font-weight: 100;
font-size: 1.125rem;
line-height: 2.0;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 30px auto 20px auto;
box-shadow: 0px 0px 3px 0px black;
padding: 20px;
background-color: white;
}
.mypost > button {
margin-top: 15px;
}
.mycards {
width: 95%;
max-width: 500px;
margin: auto;
color: #2b2d42;
}
.mycards > .card {
margin-top: 10px;
margin-bottom: 10px;
color: black;
}
</style>
<script>
$(document).ready(function () {
set_temp()
show_comment()
});
function set_temp() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/weather/seoul",
data: {},
success: function (response) {
$('#temp').text(response['temp'])
}
})
}
function save_comment() {
let name = $('#name').val()
let comment = $('#comment').val()
$.ajax({
type: "POST",
url: "/sujin",
data: {'name_give': name, 'comment_give': comment},
success: function (response) {
alert(response["msg"])
window.location.reload()
}
});
}
function show_comment() {
$('#comment-list').empty()
$.ajax({
type: "GET",
url: "/sujin",
data: {},
success: function (response) {
let rows = response['comments']
for (let i = 0; i < rows.length; i++) {
let name = rows[i]['name']
let comment = rows[i]['comment']
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>${comment}</p>
<footer class="blockquote-footer">${name}</footer>
</blockquote>
</div>
</div>`
$('#comment-list').append(temp_html)
}
}
});
}
</script>
</head>
<body>
<section class="container-fluid px-0">
<div class="row align-items-center">
<div class="col-lg-6">
<div id="headingGroup" class="text-white text-center d-lg-block mt-5">
<img class="img-fluid"
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkH9bD%2FbtrPEo5Bc0h%2F9uUNc4il44jXabyvEBgpJk%2Fimg.jpg"
alt="">
</div>
</div>
<div class="col-lg-4">
<div class="text-white text-center d-lg-block mt-5">
<h1>"오늘도 열심히 놀아라"</h1>
<h5>수진님의 한말씀</h5>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</section>
<section class="container-fluid px-0">
<div class="row align-items-center">
<div class="row justify-content-center">
<div class="col-lg-6 m-5 ">
<hr>
</div>
</div>
</div>
</section>
<header class="title">
<h1>
수진님이 보고 계셔🐋
</h1>
</header>
<p id="tem">현재기온 : <span id="temp">36</span>도</p>
<section class="container px-0">
<div class="align-items-center">
<div class="row justify-content-flex-end">
<div id="HG" class="text-white text-center mt-5">
<img class="img-fluid"
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccbkC1%2FbtrPDsnaMYX%2FEjkbMmkALPaD6ZFY1KeWO0%2Fimg.jpg">
</div>
</div>
</div>
</section>
<section class="container-fluid px-0">
<div class="row align-items-center">
<div class="row justify-content-flex-end">
<div id="headingGroup" class="text-white text-center d-lg-block mt-5">
<p>
<h3>이름: 이수진</h3>
나이: 비밀<br>
키: 198<br>
몸무게: 비밀 <br>
사는곳: 서울 <br>
직업: 대학생 및 알바생 <br>
취미: 누워서 배그하기 <br>
좋아하는 음식: <a id="mara"
href="https://map.naver.com/v5/search/%EA%B0%95%EB%82%A8%20%EC%A4%91%EA%B2%BD%EB%A7%88%EB%9D%BC%ED%83%95/place/1761717994?placePath=%3Fentry=pll%26from=nx%26fromNxList=true&c=14139655.9420416,4509207.8155029,15,0,0,0,dh">마라샹궈</a>
<br>
좋아하는 아이돌: <a id="mx" href="http://www.monstax-e.com/">몬스타엑스</a> <br>
강아지이름: <a id="dog" href="https://www.instagram.com/modu_sooni">이멍순</a>
</p>
</div>
</div>
</div>
</section>
<section id="carousel" class="container-fluid">
<div class="row align-items-center">
<div class="row justify-content-flex-start mx-10">
<div id="carouselExampleIndicators" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active"
aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1"
aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2"
aria-label="Slide 3"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="3"
aria-label="Slide 4"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="4"
aria-label="Slide 5"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="5"
aria-label="Slide 6"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="6"
aria-label="Slide 7"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="7"
aria-label="Slide 8"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="8"
aria-label="Slide 9"></button>
</div>
<div class="carousel-inner row align-items-center">
<div class="carousel-item active">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcE9CnF%2FbtrPFdPy4Ew%2FMXvB979V09VBST3xipoWM0%2Fimg.jpg"
class="col-lg-4 justify-content-center" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg66aN%2FbtrPEoxoiOi%2Fp7yGW4w64IGymUAulE0pT0%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkX53v%2FbtrPFXS42oW%2Fv2k1ERdK0XUivZXar3kUMk%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fboxg5B%2FbtrPDruAvwn%2FoDxGsj27MgLxs7wlTHyKi0%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv2EDf%2FbtrPB1QJvZx%2FZgu9HpiWGQ3XdmAJHtqm8K%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyKAca%2FbtrPGeUKtbs%2FD06PuKCxdB53l7jOAEdPwk%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdtof8F%2FbtrPFzrlyf4%2FhYKmXd1902Af37K9oEtnCk%2Fimg.jpg"
class="col-lg-4" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOBYzr%2FbtrPDebeayR%2F2nxfHjcKU7OByYCQzqc7H0%2Fimg.jpg"
class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyaaVd%2FbtrPEjpdK4D%2Fy6lOZQxZLxHggHBG3HWjrK%2Fimg.jpg"
class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
</div>
</section>
<section class="bigpics row align-items-center content">
<div class="col-12 col-lg-12 pics mb-5 mb-md-0">
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcE9CnF%2FbtrPFdPy4Ew%2FMXvB979V09VBST3xipoWM0%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg66aN%2FbtrPEoxoiOi%2Fp7yGW4w64IGymUAulE0pT0%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkX53v%2FbtrPFXS42oW%2Fv2k1ERdK0XUivZXar3kUMk%2Fimg.jpg">
<!-- Giuseppe Milo -->
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fboxg5B%2FbtrPDruAvwn%2FoDxGsj27MgLxs7wlTHyKi0%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv2EDf%2FbtrPB1QJvZx%2FZgu9HpiWGQ3XdmAJHtqm8K%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyKAca%2FbtrPGeUKtbs%2FD06PuKCxdB53l7jOAEdPwk%2Fimg.jpg">
<!-- GörlitzPhotography -->
<img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdtof8F%2FbtrPFzrlyf4%2FhYKmXd1902Af37K9oEtnCk%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOBYzr%2FbtrPDebeayR%2F2nxfHjcKU7OByYCQzqc7H0%2Fimg.jpg"><img
src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyaaVd%2FbtrPEjpdK4D%2Fy6lOZQxZLxHggHBG3HWjrK%2Fimg.jpg">
</div>
</section>
<div class="mypost">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="name" placeholder="url">
<label for="floatingInput">닉네임</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="comment"
style="height: 100px"></textarea>
<label for="floatingTextarea2">응원댓글</label>
</div>
<button onclick="save_comment()" type="button" class="btn btn-dark">응원 남기기</button>
</div>
<div class="mycards" id="comment-list">
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
</div>
</body>
</html>
3. 서버 배포 및 도메인 연결하기
- AWS에서 새로운 인스턴스를 설정하고 새 IP 주소를 받았습니다.
- Gabia에서 동생이 원했던 도메인 이름을 넣어서 새로 구입했습니다.
- FileZilla를 통해 리눅스에 접속해 필요한 프로그램들 (pip 및 python packages (flask, dnspython, pymongo, certifi)을 설치했습니다.
- 인바운드 규칙을 수정했습니다.
- 80포트: HTTP 접속을 위한 기본포트
- 5000포트: flask 기본포트
- 27017포트: DB 접속 포트
- 22포트: SSH
- Gabia의 도메인 DNS 관리에 들어가 새로운 IP 주소를 연결합니다.
- nohup python app.py & 을 실행해서 로컬 컴퓨터가 꺼져도 리눅스는 돌아가게 설정했습니다.
4. 완성하기
아래는 완성된 웹사이트를 캡쳐하였습니다.
언제까지 서버를 열어놓을지는 모르겠지만 웹사이트 주소는 jinwoongwife.shop 입니다.
5. 느낀점
- 한 6시간 정도 걸렸습니다.
- 기존에 있던 코드를 가져와서 내 필요에 맞게 수정하는 작업이었습니다.
- 유데미 강의는 vscode를 사용하고 스파르타 웹개발종합반은 pycharm을 사용하는데 개인적으로 vscode가 더 나은 거 같습니다....아직 둘다 익숙하지 않아서 일까요;;
- 사진이나 아이템 배치랑 사이즈 조절하는 법에 대해서 좀 안일하게 생각했는데 다시 한번 강의 복습을 해봐야겠습니다.