POMOTODO : ejs템플릿 include 하기
2022. 1. 5. 00:47ㆍ프로그래밍/개인프로젝트
POMOTODO를 만들면서 작성한 코드를 복습하기 위해 작성하는 글입니다.
여러 페이지에서 공통으로 사용하는 상단 네비게이션바의 코드를 여러 파일에서 동일하게 사용하고 있는 걸 인지했고,
수정하기 위해 공부했다
간편하게 공통되는 중복코드들을 하나의 외부 파일로 만들고 ejs템플릿으로 include 하기로 했다
header.ejs
<header>
<nav class="top-bar">
<div class="search-bar">
<input type="text" class="query" value="" style="display: inline;" placeholder="google search" autofocus="true" onkeydown="if(window.event.keyCode==13){search()}" spellcheck="false">
</div>
<button class="copyright"><i class="far fa-copyright"></i></button>
<div class="copyright-modal" style="display: none;">
<div>Icons made by <a href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>
<div>Icons made by <a href="" title="th studio">th studio</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>
</div>
<div class="login-check-modal" style="display: block;" >
<div class="loginplz-content">
<p class="warning"> Please login, <br> if you want to save your data.</p>
데이터를 저장하려면 로그인 해주세요.
</div>
<div class="close-loginplz-icon" ><i class='fas fa-times'></i></div>
</div>
<div class="POMOTODO__logo" title="Home">
<a href="/">
<img src="/POMOTODO icon/tomato(0).png" alt="logo Image">
POMOTODO
</a>
</div>
<div id="id-check">
<!-- 아이디출력 -->
<span id="modal-button-id-check"><%= posts %></span>
<!-- 모달창 출력 -->
<span class="modal-close"></span>
<span id="modal-window-id-check">
<!-- 로그인/로그아웃 버튼 -->
<span id="hello">Hello!</span>
<span id="hello-user">Hello ! <%= posts %></span>
<button id="loginButton">Log in </button>
<button id="logoutButton">Log out</button>
<button id="signup-login-modal">Sign up</button>
<button id="unregister">Delete ID</button>
<div id="unregister-check">
do you want delete ID?<br>
<button id="unregister-ok">yes</button>
<button id="unregister-no">no</button>
</div>
<div id="contact-me-title">
contact-developer
<ul class="POMOTODO__contact-me">
<li>
<a href="https://coqoa.tistory.com/" title="tistory blog" target="blank" ><i class="fas fa-bold"></i></a>
</li>
<li>
<a href="https://github.com/coqoa" title="github" target="blank"><i class="fab fa-github"></i></a>
</li>
<li id="mail-btn">
<i class="far fa-envelope" title="E-mail"></i>
</li>
</ul>
</div>
<div id="modal" class="modal-overlay">
<div class="mail-modal-window">
<div class="content">coqoa28@gmail.com</div>
</div>
</div>
</span>
</div>
<ul class="POMOTODO__menu">
<li>
<button type="button" class="searchBarBtn" title="Google Search : Shift + Enter">
<i class="fas fa-search"></i>
</button>
</li>
<li>
<a href="/" title="Home" class="homeBtn">
<i class="fas fa-home"></i>
</a>
</li>
<li>
<a href="/record" title="Record" class="calendarBtn">
<i class="fas fa-calendar-alt"></i>
<a>
</li>
<li>
<a href="/크롬익스텐션" title="Chrome-Extension" class="puzzleBtn" >
<i class="fas fa-puzzle-piece"></i>
<a>
</li>
</ul>
<div id="POMOTODO__clock"></div>
</nav>
</header>
header.css
:root {
--backgroundColor: #f0f0f0;
--contentColor: #f5f5f5;
--blackShadow: #cfcfcf;
--whiteShadow: #ffffff8b;
--lightgrayShadow: #d9d9d9;
--bluetext: #221974;
--redtext: #ff8585;
--hoverredtext: #f75858;
--graytext: #c7c8ca;
--beigetext: #f5f5dc;
--greentext: #76c576;
}
.top-bar {
zoom: 80%;
}
button:hover {
opacity: 0.7;
cursor: pointer;
}
button:active {
opacity: 0.7;
cursor: pointer;
}
body {
font-family: "Ubuntu", "IBM Plex Sans KR";
display: flex;
justify-content: center;
height: 670px;
margin: 0px;
background-color: var(--backgroundColor);
}
header nav {
font-family: "Ubuntu", "IBM Plex Sans KR";
display: flex;
justify-content: center;
align-items: center;
padding: 8px 12px;
position: fixed;
left: 0;
width: 100%;
height: 10px;
background-color: #ffffff;
color: #5e5e5e;
z-index: 999;
}
/*네비게이션바의 a태그*/
a {
text-decoration: none;
color: #5e5e5e;
}
.POMOTODO__logo a {
position: absolute;
bottom: 4px;
left: 10px;
padding: 0px;
font-family: "Ubuntu", "IBM Plex Sans KR";
font-size: 17px;
font-weight: 500;
font-style: italic;
}
.POMOTODO__logo a:hover {
background-color: transparent;
color: black;
}
/* 로고 아이콘 */
.POMOTODO__logo i {
position: relative;
bottom: 1px;
padding-right: 5px;
color: #ff8585;
}
#id-check {
font-family: "Ubuntu", "IBM Plex Sans KR";
font-size: 17px;
font-weight: 500;
font-style: italic;
text-align: center;
color: gray;
}
#modal-button-id-check {
position: absolute;
right: 165px;
bottom: 0px;
height: 20px;
width: 120px;
padding-bottom: 3px;
border-radius: 7px;
color: gray;
}
#modal-button-id-check:hover {
cursor: pointer;
color: black;
}
#modal-button-id-check:active {
cursor: pointer;
box-shadow: inset 0px 0px 0px #949da6, -0px -0px 0px #ffffff;
}
/* 생성된 모달창 */
.modal-close {
position: absolute;
top: 25px;
left: 0;
display: none;
width: 3000px;
height: 3000px;
background-color: #ffffff20;
z-index: 90;
}
#modal-window-id-check {
display: none;
flex-direction: column;
position: absolute;
top: 45px;
right: 130px;
height: 220px;
width: 150px;
font-family: "Ubuntu", "IBM Plex Sans KR";
background: rgba(255, 255, 255, 0.6);
box-shadow: 6px 6px 9px #c8ced7;
backdrop-filter: blur(1.5px);
-webkit-backdrop-filter: blur(1.5px);
border-radius: 10px;
padding: 5px 5px 10px 5px;
z-index: 99;
}
/* 로그인버튼, 로그아웃버튼, 회원탈퇴버튼 */
#hello,
#hello-user,
#loginButton,
#logoutButton,
#unregister,
#signup-login-modal {
font-size: 18px;
font-weight: 600;
font-style: italic;
color: gray;
display: none;
justify-content: center;
margin: 13px 0px;
border: 0;
background-color: transparent;
}
#hello,
#hello-user {
color: #221974;
}
#loginButton:hover {
opacity: 1;
color: #8ab36f;
}
#logoutButton:hover {
opacity: 1;
color: #e24747;
}
#signup-login-modal:hover {
opacity: 1;
color: #5140eb;
}
#loginButton:active,
#logoutButton:active,
#signup-login-modal {
box-shadow: inset 0px 0px 0px #949da6, -0px -0px 0px #ffffff;
}
#unregister:hover {
opacity: 1;
color: #f0942c;
}
#unregister:active {
cursor: pointer;
box-shadow: inset 0px 0px 0px #949da6, -0px -0px 0px #ffffff;
}
#unregister-check {
position: relative;
top: 100px;
left: -25px;
display: none;
padding-top: 15px;
border: 1px solid white;
border-radius: 10px;
width: 200px;
height: 150px;
background: rgba(255, 255, 255, 0.6);
box-shadow: 6px 6px 9px #c8ced7;
backdrop-filter: blur(1.5px);
-webkit-backdrop-filter: blur(1.5px);
}
#unregister-ok,
#unregister-no {
font-size: 18px;
font-weight: 500;
color: gray;
font-style: italic;
margin: 10px;
padding: 10px;
border: 0px;
border-radius: 10px;
background-color: transparent;
}
#unregister-ok:hover,
#unregister-no:hover {
color: black;
}
#unregister-ok:active,
#unregister-no:active {
box-shadow: inset 0px 0px 0px #949da6, -0px -0px 0px #ffffff;
}
#contact-me-title {
position: absolute;
top: 150px;
left: 12px;
font-weight: 400;
margin-top: 10px;
padding-top: 10px;
}
.POMOTODO__contact-me {
position: absolute;
top: 40px;
left: 10px;
display: flex;
justify-content: center;
list-style: none;
margin: 0px;
padding: 0px;
}
.POMOTODO__contact-me li {
margin-top: 2px;
padding: 2px 12px;
}
.POMOTODO__contact-me li:hover {
color: black;
}
#mail-btn {
cursor: pointer;
}
#modal.modal-overlay {
position: relative;
top: 100px;
left: -30px;
width: 210px;
height: 65px;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.6);
box-shadow: 6px 6px 9px #c8ced7;
backdrop-filter: blur(1.5px);
-webkit-backdrop-filter: blur(1.5px);
border-radius: 10px;
}
#modal .content {
position: relative;
}
/* 네비게이션아이콘 */
.POMOTODO__menu {
position: relative;
right: 0.8%;
display: flex;
list-style: none;
padding: 0px;
margin: 0px;
font-size: 18px;
}
.POMOTODO__menu li {
padding: 2px 12px;
margin: 0px;
}
.POMOTODO__menu li:hover {
opacity: 0.6;
}
/* 네비게이션 시계 */
#POMOTODO__clock {
display: inline;
font-family: "Ubuntu", "IBM Plex Sans KR";
position: absolute;
right: 30px;
top: 5px;
margin-right: 10px;
font-size: 14px;
color: #5e5e5e;
}
.searchBarBtn:hover {
opacity: 1;
color: rgb(59, 59, 214);
}
.homeBtn:hover {
color: rgb(246, 94, 39);
}
.calendarBtn:hover {
color: rgb(18, 147, 18);
}
.puzzleBtn:hover {
color: rgb(210, 93, 210);
}
/* 검색창 구현 */
.search-bar {
position: absolute;
top: 30px;
z-index: 999;
align-items: center;
}
.query {
font-family: "Ubuntu", "IBM Plex Sans KR";
font-weight: 500;
font-style: italic;
font-size: 18px;
height: 30px;
width: 560px;
border: 0;
border-radius: 10px;
background-color: white;
text-align: center;
color: black;
box-shadow: 5px 8px 10px #7e7e7e;
}
.searchBarBtn {
position: relative;
top: -1px;
left: 10px;
font-size: 17px;
border: 0;
color: #5e5e5e;
background-color: transparent;
}
/* 네비게이션 크기변경 바 */
.desktop-mode {
position: relative;
top: -1px;
border: 0;
background-color: transparent;
color: #5e5e5e;
}
.copyright {
position: absolute;
font-size: 20px;
right: 30px;
top: 30px;
border: 0;
color: lightgray;
background-color: transparent;
}
.copyright-modal {
display: none;
position: absolute;
right: 40px;
top: 60px;
width: 400px;
height: 40px;
padding: 10px;
border-radius: 15px;
background-color: rgba(255, 255, 255, 0.574);
box-shadow: 5px 8px 10px var(--blackShadow);
z-index: 999;
}
.login-check-modal {
position: absolute;
top: 40px;
right: 80px;
width: 260px;
height: 100px;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 10px;
box-shadow: 3px 3px 5px #7e7e7e;
text-align: center;
font-family: "Ubuntu", "IBM Plex Sans KR";
font-weight: 500;
font-size: 15px;
color: #5e5e5e;
z-index: 999;
}
.warning {
color: var(--redtext);
}
.close-loginplz-icon {
position: absolute;
top: 8px;
right: 10px;
cursor: pointer;
}
.close-loginplz-icon:hover {
color: lightgrey;
}
@media screen and (max-width: 1023px) {
.login-check-modal {
top: 80px;
}
}
@media screen and (max-width: 520px) {
.POMOTODO__menu {
right: 10%;
}
.query {
width: 430px;
}
}
@media screen and (max-width: 490px) {
.top-bar {
zoom: 60%;
}
.POMOTODO__menu {
right: 3%;
}
#modal-button-id-check {
right: 5%;
}
#POMOTODO__clock {
display: none;
}
}
header.js
//네비 날짜
function setClock(){
let dateObject = new Date();
let year = dateObject.getFullYear();
let month = dateObject.getMonth()+1;
let date = dateObject.getDate();
let hour = addStringZero(dateObject.getHours());
let min = addStringZero(dateObject.getMinutes());
document.getElementById("POMOTODO__clock").innerHTML = year + ". " + month + ". " + date + " . " + hour+ " : " + min ;
}
function addStringZero(time){
if(parseInt(time)<10)
return "0"+time;
else
return time;
}
window.onload = function(){
setClock();
setInterval(setClock,1000);
}
let modalButton = document.getElementById('modal-button-id-check');
let modalWindow = document.getElementById('modal-window-id-check');
let loginButton = document.getElementById('loginButton');
let logoutButton = document.getElementById('logoutButton');
let unregister = document.getElementById('unregister');
let unregisterCheck = document.getElementById('unregister-check');
let unregisterOk = document.getElementById('unregister-ok');
let unregisterNo = document.getElementById('unregister-no');
let signupLoginModal = document.getElementById('signup-login-modal');
let hello = document.getElementById('hello');
let helloUser = document.getElementById('hello-user');
let emailModal = document.querySelector('.modal-overlay');
let loginModalClose = document.querySelector('.modal-close');
modalButton.addEventListener("click", e=>{
if(modalWindow.style.display == 'flex'){
modalWindow.style.display = "none"
loginModalClose.style.display = "none"
}else{
loginModalClose.style.display = "inline"
modalWindow.style.display = "flex"
if(modalButton.innerText == "log in"){
loginButton.style.display = "flex"
signupLoginModal.style.display = "flex"
hello.style.display="inline-block"
}
else{
logoutButton.style.display = "flex"
unregister.style.display = "flex"
helloUser.style.display="inline-block"
}
}
loginPlzModal.style.display = 'none';
})
//개발자 이메일 확인 모달창 구현
let modal = document.getElementById("modal");
let btnModal = document.getElementById("mail-btn");
btnModal.addEventListener("click", e => { // 누르면 모달창 생성, 한번 더 누르면 모달창 종료
if (modal.style.display == "flex"){
modal.style.display = "none";
unregisterCheck.style.display = "none"
}
else{
modal.style.display = "flex";
unregisterCheck.style.display = "none"
}
})
window.addEventListener("keyup", e => { //esc키 눌렀을 때 모달창 종료
if(modal.style.display === "flex" && e.key === "Escape")
modal.style.display = "none";
modalWindow.style.display = "none"
loginModalClose.style.display = "none"
emailModal.style.display = "none"
unregisterCheck.style.display = "none"
})
//모달창 밖을 클릭하면 모달창종료
loginModalClose.addEventListener("click", e=>{
modalWindow.style.display = "none"
loginModalClose.style.display = "none"
emailModal.style.display = "none"
unregisterCheck.style.display = "none"
copyrightModal.style.display = 'none'
})
loginButton.addEventListener("click", e=>{
location.href='/login';
})
logoutButton.addEventListener("click", e=>{
location.href='/logout';
})
unregister.addEventListener("click", e=>{
unregisterCheck.style.display = "inline-block"
emailModal.style.display = "none"
})
unregisterOk.addEventListener("click", e=>{
location.href='/deleteUser';
})
unregisterNo.addEventListener("click", e=>{
unregisterCheck.style.display = "none"
})
signupLoginModal.addEventListener("click", e=>{
location.href='/signup';
})
// 검색창 관련
let query = document.querySelector('.query')
let searchBtn = document.querySelector('.searchBtn')
let searchBarBtn = document.querySelector('.searchBarBtn')
let bodyClass = document.querySelector('.body')
let isShift, isEnter;
document.onkeyup = function(e){
if(e.which == 16) isShift = false;
if(e.which == 13) isEnter = false;
}
document.onkeydown = function(e){
if(e.which == 16) isShift = true;
if(e.which == 13) isEnter = true;
console.log(isShift, isEnter)
if(isShift==true && isEnter == true){
query.style.display = "inline";
query.value = "";
query.focus();
// searchBarBtn.style.display = "none";
return false;
}
}
function search(){
if(query.value.length>0){
let url = 'http://www.google.com/search?q='+query.value;
window.open(url)
}
query.value = "";
isEnter = false;
isShift = false;
}
searchBarBtn.onclick = function(){
query.style.display = "inline";
query.value = "";
query.focus();
// searchBarBtn.style.display = "none";
isEnter = false;
isShift = false;
}
query.onblur = function(){
query.style.display = "none";
// searchBarBtn.style.display = "inline";
isEnter = false;
isShift = false;
}
let copyrightBtn = document.querySelector(".copyright");
let copyrightModal = document.querySelector(".copyright-modal");
copyrightBtn.onclick = function(){
// copyrightModal.style.display = none;
console.log(copyrightModal.style.display == 'none');
if(copyrightModal.style.display == 'none'){
copyrightModal.style.display = 'inline'
loginModalClose.style.display = "inline"
}else{
copyrightModal.style.display = 'none'
}
loginPlzModal.style.display = 'none';
}
let loginPlzModal = document.querySelector('.login-check-modal');
let closeLoginPlzIcon = document.querySelector('.close-loginplz-icon');
if(modalButton.innerText !== 'log in'){
loginPlzModal.style.display = 'none';
}
closeLoginPlzIcon.onclick = function(){
loginPlzModal.style.display = 'none';
}
그리고 첨부를 원하는 파일(ejs)내부의 적절한 위치에 다음과 같이 작성해줬다
나는 POMOTODO.ejs와 record.ejs 두 개의 파일에 작성했음
<%- include ('header.ejs') %>
'프로그래밍 > 개인프로젝트' 카테고리의 다른 글
POMOTODO : 암호화 (0) | 2022.01.05 |
---|---|
POMOTODO : session, passport, serialize, deserialize (0) | 2022.01.05 |
POMOTODO : 회원가입 유효성검사 및 예외처리 (0) | 2022.01.05 |
POMOTODO(12) - 이슈발생 및 해결, 새롭게 구현한것 등등 (0) | 2022.01.04 |
POMOTODO - 개발순서 중간정리 ~ 21. 12.28 (0) | 2021.12.28 |