EJS활용 블로그

김주언·2022년 5월 28일
0

WEB - Basic

목록 보기
5/10
post-thumbnail

ejs... 요즘 쓰는지 모르겠음 🧐 ㄱㅊ 모르는것보다 아는게 낫다~~~

초기 설정

EJS?

EJS는 Embedded Javascript를 뜻한다. HTML 내부에 자바스크립트를 사용할 수 있게 해주는 템플릿 언어/엔진이다.

템플릿 엔진?

템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어
런타임에 템플릿 엔진이 템플릿 파일 내부의 변수들을 실제 데이터로 변환해서 클라이언트쪽으로 전송한다. 즉, HTML에 동적인 데이터를 삽입해준다

EJS 기본 문법

문법설명
<%'Scriptlet' 태그, 제어 흐름용, 출력 없음
<%_'Whitespace Slurping' Scriptlet 태그는 그 앞에 있는 모든 공백을 제거
<%=템플릿에 값을 출력(HTML 이스케이프 처리)
<%-이스케이프 처리되지 않은 값을 템플릿에 출력
<%#주석 태그, 실행 없음, 출력 없음
<%%리터럴 '<%' 출력
%>일반 종료 태그
-%>트림 모드('newline slurp') 태그, 줄 바꿈 다음에 오는 트림
_%>'공백 슬러핑' 종료 태그, 그 뒤의 모든 공백 제거

디렉터리 구조

.
├── app.js
├── node_modules
├── package-lock.json
├── package.json
├── public
│   └── css
└── views
    ├── about.ejs
    ├── compose.ejs
    ├── contact.ejs
    ├── home.ejs
    ├── partials

HTML

<%- include("partials/header") -%>

<h1>HOME</h1>
<%= homeStartingContent %>
<%- include("partials/footer") -%>

위와 같은 형태로 다른 페이지에도 동일하게 적용

Express

라우팅 설정

const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');

const app = express();

// homeStartingContent, aboutContent, contactContent 생략

app.set('view engine', 'ejs');	// 엔진 설정

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));

app.get('/', (req, res) => {
  res.render('home', { homeStartingContent});
});

app.get('/about', (req, res) => {
  res.render('about', { aboutContent });
});

app.get('/contact', (req, res) => {
  res.render('contact', { contactContent });
});

app.get('/compose', (req, res) => {
  res.render('compose');
});

app.listen(3000,  () => {
  console.log('Server started on port 3000');
});

body-parser 모듈의 역할
데이터(client에서 post로 보내준 데이터)들을 자동으로 파싱해주어서, 실제로 필요한 부분인 body부분을 추출한다.

라우트 파라미터 사용하기

app.get("/exampleUrl/:<paramName>", (req, res)=>{
  // Access req.params.paramName
});

데이터 전달하기

객체 형태로 전달하면 된다. {key:value}

const homeStartingContent = 'hello!';
app.get('/', (req, res) => {
  res.render('home', { homeStartingContent });
});

home.ejs

<h1>HOME</h1>
<!-- key 이름 동일하게 !-->
<%= homeStartingContent %>

about, contact 페이지 반복


게시글 작성

compose.ejs

<%- include("partials/header") -%>

<h1>Compose</h1>
<form action="/compose" method="post">
  <div class="form-group">
    <label>Title</label>
    <input type="text" name="postTitle" class="form-control" /><br />
    <label>Post</label>
    <textarea
      name="postBody"
      cols="30"
      rows="10"
      class="form-control"
    ></textarea>
  </div>
  <div class="text-center">
    <button class="btn btn-outline-success " type="submit" name="button">등록</button>
  </div>
</form>
<%- include("partials/footer") -%>

app.js

const posts = [];

app.get('/', (req, res) => {
  res.render('home', { homeStartingContent, posts });
});

app.post('/compose', (req, res) => {
  const post = {
    title: req.body.postTitle,
    content: req.body.postBody,
  };
  posts.push(post);
  res.redirect('/');
});
  1. compose.ejs에서 보낸 요청을 처리하는 함수 작성
  2. posts 배열에 요청 내용 삽입 후 HOME으로 리다이렉트
  3. HOME으로 돌아갈 때, 게시글 데이터를 함께 전송

게시글 내용 일부 출력

내용의 일부만 출력하도록 substring 사용한다.
home.ejs

<% posts.forEach(post => { %>
  <h1><%=post.title%></h1>
  <p>
  <%=post.content.substring(0, 100) + " ..."%>
  </p>
<% }) %>
  1. express 서버로부터 받은 posts 화면에 출력

클릭한 글내용 전체 보기

post.ejs 파일 생성

<%- include("partials/header"); -%>
<%- include("partials/footer"); -%>

home.ejs 파일 내용 수정
간략하게 나타난 글 내용 옆에 <a> 태그 추가하여 전체 내용 페이지로 이동할 수 있도록 한다. 게시글의 제목을 이용하여 라우팅

<a href="/posts/<%=post.title%>">Read More</a>

app.js 파일에 내용 추가
lodash 모듈 사용
url 파라미터를 이용 (:postName, req.params.postName)

req.params에 접근하기 위해서 url에 콜론(:)을 이용하여 변수이름(?)을 설정해준다.

const _ = require('lodash');

app.get('/posts/:postName', function (req, res) {
  const requestedTitle = _.lowerCase(req.params.postName);

  posts.forEach(function (post) {
    const storedTitle = _.lowerCase(post.title);

    if (storedTitle === requestedTitle) {
      res.render('post', {
        title: post.title,
        content: post.content,
      });
    }
  });
});

최종 화면

profile
학생 점심을 좀 차리시길 바랍니다

0개의 댓글