POMOTODO : ejs템플릿 include 하기

2022. 1. 5. 00:47프로그래밍/개인프로젝트

POMOTODO를 만들면서 작성한 코드를 복습하기 위해 작성하는 글입니다.

 

 

POMOTODO.kr

 

 

What is 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') %>