Project/축구모임 홈페이지개발

[축구모임 홈페이지개발] 12/04 개발일지 Nodejs / 변수 렌더링 유무 확인, 메뉴바 구현, app.use 사용, 네비 기능 구현

한33 2023. 12. 4. 19:22

어제 message 변수가 없을 시에 login 페이지를 띄우기 위한 if 문을 마저 못끝냈었다.

 

<% if (typeof message !== 'undefined' && message) { %>
        <script>
            alert('<%= message %>');
        </script>
    <% } %>

 

위와 같은 코드를 입력했다.

 

 if (typeof message !== 'undefined' && message) {

 

typeof 연산자를 사용해서 message 가 정의되어있는지 확인하는 코드이다.

undefined 가 아닌 경우에만 다음 조건을 체크한다.

 

// &&message 는 message 변수가 존재하면서 값이 있는지를 확인한다.

 

즉 위와 같은 코드는 그냥 message 변수 안에 값이 있으면 아래를 실행하겠다는 거고 없으면 넘어가는거다.

이렇게하면 login-need.ejs 를 따로 만들지 않아도 상황에 맞게 message 변수를 사용하거나 안 할 수 있다.

앞으로 많이 이용할 거 같으니 기억해두자.


위와 비슷한 방법으로 로그인이 되었을 시에 홈 화면에 "ㅇㅇㅇ님 환영합니다" 라는 문구를 넣고자했는데,

조금 달랐다. 왜냐하면 애초에 렌더링을 할 때 변수를 담아서 넘어가야하기 때문에 서버측에서 변수에 데이터가 있는지,

즉 req.user 값이 들어있는지 확인을 해야했다.

 

app.get('/', async (req, res) => {    

  let result = await db.collection('mvp').find().sort({ _id: -1 }).limit(1).toArray();
  let Weeklymvp = result.length > 0 ? result[0].mvp : null;
  let renderingContext = { MVPname: Weeklymvp };
  if (req.user) {
    renderingContext.유저 = req.user.username;
  }

  res.render('home.ejs', renderingContext);
})

 

그래서 위와 같이 코드를 작성했고, 알게된 사실은 두가지이다.

 

{ MVPname: Weeklymvp }

 

이 자체를 변수로 지정을해서 renderingContext.유저 를 하면 유저라는 이름으로 renderingContext 안에 추가되고 그 값이

뒤에 따라오는 req.user.username 으로 지정할 수 있다. 

새롭게 추가가 되는 것이다.

 

그리고 이 자체를 if(req.user) if 문으로 덮어줌으로서 req.user 가 있을 때에만 코드가 진행되도록 해줬다.

이렇게 전달받은 코드를

<% if (typeof 유저 !== 'undefined' && 유저) { %>
        <div style="color: white;"><%=유저%> 님 환영합니다.</div>
    <% } %>

 

다음과 같이 home 화면에서 띄워주면

 

 

이렇게 기능이 완성된다.

 


 

이 if 문을 배움으로써 드디어 구현해낼 수 있는 기능들이 몇 가지 더 있었다.

 

우선 nav.ejs 는 메뉴바와 상단바를 구성해놓은 파일이고

매 파일마다

<%- include('nav.ejs') %>

 

위 코드를 사용함으로서 모든 페이지에 기능이 구현되게끔 해놨는데

로그인이 되어있다면 로그인하기 a태그를 ㅇㅇㅇ 님 으로 변경하고.

로그아웃 a태그는 로그인이 되어있을시에만 나오게끔 구현하고 싶었다.

 

  <ul>
    <% if (typeof 유저 !=='undefined' ) { %>
      <li><a style="font-size: 25px;" href="#">
          <%=유저%> 님
        </a></li>
      <% } else { %>
        <li><a style="font-size: 25px;" href="/login">로그인하기</a></li>
        <%}%>
          <li><a href="/">팀소개</a></li>
          <li><a href="/">사진&영상</a></li>
          <li><a href="/">경기결과</a></li>
          <li><a href="/notice">공지사항</a></li>
          <li><a href="/management">관리</a></li>
          <% if (typeof 유저 !=='undefined' ) { %>
              <li><a href="/logout">로그아웃</a></li>
            <% } %>
         
  </ul>

 

if문을 사용해서 위와 같이 구현해냈다.

 


 

이전에 공지사항탭의 글 상세페이지에서 수정버튼을 눌러 수정해내면 notice 로 돌아갔었는데, 수정된 상세페이지로 돌아가게 하고싶었다. 하지만 redirect('back') 을 사용하면 그냥 현재 페이지에 머물러져 있었기 때문에 나는

 

res.redirect('/notice-detail/'+req.body.id)

 

이렇게 코드를 짰다.

수정할 때 글의 id 값을 display:none; 으로 숨겨놨었기 때문에 그 숨겨놨던 id 값을 가져와서 url 로 접근시켰다.

 


 

위에서 nav.ejs 에 로그인된 회원 이름을 적용하기 위해 짠 코드가 있었다.

그런데 문제가 생겼다.

 

  if (req.user) {
    res.locals.유저 = req.user;
  }

 

이 코드를 그러면 모든 엔드포인트 마다 넣어줘서 렌더링시켜야지 그 값이 nav 에 들어갔다.

안그러면 nav.ejs 에서 유저가 없다고 판단해 다시 로그인하기 버튼을 띄우는 현상이 일어났다.

그래서 검색을 해보니, 이 과정을 한 번에 해줄 수 있는 코드가 있었다.

 

app.use((req, res, next) => {
  if (req.user) {
    res.locals.유저 = req.user;
  }
  next();
})

 

위와 같이 코드를 짜주니까 모든 코드에 알아서 if 문이 들어갔고

또 locals 를 사용해서 데이터를 렌더링 해준다는 것을 알았다.

모든 페이지에 고정적인 데이터값을 출력시켜야하는 상황에 유용하게 쓰일 코드이다. 굿 !

 


  <ul>
    <% if (typeof 유저 !=='undefined' ) { %>
      <li><a style="font-size: 25px;" href="#">
          <%=유저%> 님
        </a></li>
      <% } else { %>
        <li><a style="font-size: 25px;" href="/login">로그인하기</a></li>
        <%}%>
          <li><a href="/">팀소개</a></li>
          <li><a href="/">사진&영상</a></li>
          <li><a href="/">경기결과</a></li>
          <li><a href="/notice">공지사항</a></li>
          <% if (typeof 유저 !=='undefined' ) { %>
            <% if (유저 == 'test') {%>
              <li><a href="/management">관리</a></li>
              <%}%>
              <li><a href="/logout">로그아웃</a></li>
            <% } %>
         
  </ul>

 

관리 페이지에 대한 회원 권한을 추가하기 위해서 다음과 같이 코드를 짰다.

유저가 test 라는 이름의 유저일 때에만 관리라는 탭이 보이게 해놨다.

또 이를 유저가 없으면 아예 보이지도 않게 

<% if (typeof 유저 !=='undefined' ) { %>

위의 조건문 안에다가 넣어놨다.

 


 

홈페이지 홈 화면에 버튼을 누르면 네이버지도로 자동으로 연결시켜서 이번 주 목적지를 자동으로 검색해주는 기능이 있다.

버튼을 누르면 모바일 주소로 네이버지도로 연결시키는 건데, 아직 그 주소값을 변경시킬 수 있는 기능을 구현하지는 않았다.

그래서 관리탭에서 주소를 입력하면 그 주소가 home.ejs 로 전달되어 버튼 입력시 그 주소가 찍힌 모바일 네이버지도로 전달되는 코드를 짜볼 것이다.

 

      <div>
        <h4>네비게이션</h4>
        <div style="height: 100px;">
          <input id="navi_address" style="width: 250px;" type="text" placeholder="주소">
          <button onclick="navi_input()">입력</button>
          <div>현재 저장된 주소 : <%=목적지.address%></div>
        </div>
      </div>

 

우선 관리탭에서 다음과 같이 주소를 입력하는 input 태그와 버튼을 만들어주었다.

 

    function navi_input() {
      var navi_address = document.getElementById('navi_address').value;
      location.href = '/navi?val=' + navi_address
      alert('저장되었습니다.')
    }

 

그리고 script 태그 안에 버튼을 눌렀을 때 기능할 함수를 만들어줬다.

navi_address id 값을 가지고 있는 곳의 value 값을 지정해서 쿼리방식으로 서버로 전송한다.

app.get('/navi', async (req, res) => {
  let result = db.collection('navi').insertOne({
    address: req.query.val
  })
})

 

서버에서 /navi 로 접근해 전송받은 쿼리데이터를 address 이름으로 mongoDB 에 저장한다.

app.get('/', async (req, res) => {

  let result = await db.collection('mvp').find().sort({ _id: -1 }).limit(1).toArray();
  let Weeklymvp = result.length > 0 ? result[0].mvp : null;

  let navi = await db.collection('navi').find().sort({ _id: -1 }).limit(1).toArray();

  res.render('home.ejs', { MVP: Weeklymvp, 목적지: navi[0] });
})

 

홈화면에서 mongoDB 로 부터 address 값을 가져온다.

    function redirectTo() {
      var levelUrl = 'https://map.naver.com/p/search/<%=목적지.address%>';
      window.open(levelUrl, '_blank');
    }

 

홈 화면에서 함수값에 url 에 다가 내가 가져온 목적지 address 값을 넣어주면 완성된다.

 


 

집중력이 흐려간다. 너무 오래하고있다.

 

다음은 페이지네이션 기능을 구현했다.

 

          <div class="list-box" style="text-align: center; font-size: 18px;">
            <% for (let i=1; i<((글목록.length +1) / 10 ) + 1 ; i++ ) {%>
              <a href="/notice/<%=i%>" style="padding: 0px 3px 0px 3px;">
                <%=i%>
              </a>
              <%}%>
          </div>

 

비슷한 디자인으로 list-box 틀을 더 만들었고,

a태그를 이용해서 각 페이지로 이동할 수 있는 버튼을 만들었고.

내가 직접 이동버튼을 만드는 것이 아니라 작성되는 글의 개수를 활용해서 자동으로 페이지 인덱스 개수가 나오게 코드를 짰다.

우선 예를 들어서 게시물이 21개면 10개씩 보여질 거기 때문에 3개의 페이지 인덱스가 필요하다.

그래서 i 가 1부터

글목록.length 는 21로 나올 것이고

21개를 카운트하기 위해 글목록.length +1 을 해줬다.

몫을 구하기 위해 10을 나눠서 나온 값인 2에 +1을 해준 값인 3 ..................음 잘못됐다 이거 뭔가 잘못됐다 시간이 늦어 내일 출근을 해야하니 여기까지하고 수정해서 와야겠다.