지난 스토리에서는 Node.js 에서 동적웹페이지를 만드는 기초 부분에 대해 알아보았는데요.
사실 이 방법은 Node.js의 편의성을 충분히 발휘한 방법은 아닙니다.
Node.js 에는 템플릿이라는 멋진 기능이 있거든요 :)
https://itadventure.tistory.com/436
템플릿이란?
템플릿은 특정 모양을 만들기 위해 사전에 준비된 틀을 의미합니다.
그런 의미에서 붕어빵을 구워내는 빵틀도 일종의 템플릿이라 생각이 들지 않으신가요? :)
Node.js 에서는 템플릿이란 어떤 의미일까요?
그건 바로 HTML 태그로 이루어진 기초 문서를 의미합니다.
어느정도 완성된 HTML 문서의 형틀을 미리 만들어 놓고
그 중 일부를 필요한 정보로 채워넣는 것이지요.
이를테면 아래와 같은 모양의 화면을 미리 준비했다고 칩시다.
이중에서 용량칸과 가운데 들어갈 이미지는 아직 준비되지 않은 상황입니다.
하지만 용량부분과 이미지를 채워 넣으면 아래와 같은 문서가 됩니다.
귀여운 강아지가 등장했군요 :)
이 중에서 전자에 해당하는 문서가 바로 템플릿 문서 입니다. 바로 어느정도 완성된 문서이기 때문이지요.
그래서 템플릿 문서중 필요한 일부 정보를 채워넣어 완성하는 것이 템플릿의 주요 목적입니다.
npm 세팅
내친 김에 방금 그 화면을 만들어 보도록 하겠습니다.
참고로 랜덤으로 강아지 이미지를 제공하는 것은 오픈 API로서
그 전에 먼저 템플릿 관련 라이브러리인 ejs 모듈과 외부 api 를 호출할 수 있는 request 모듈을 설치해야 합니다.
자 이제 새로운 폴더를 만들어서 시작해 보도록 합시다.
새로운 폴더는 /home/nodejs4 로 정하기로 하고
리눅스 터미널에서 폴더 생성, 권한 변경, cd 명령으로 해당 폴더로 이동까지 진행합니다.
sudo mkdir /home/nodejs4
sudo chown ec2-user:ec2-user /home/nodejs4
cd /home/nodejs4
그리고 npm 초기화 후 express, ejs, request 를 설치해 줍니다.
npm init -y
npm install express
npm install ejs
npm install request
ejs 는 템플릿 기능사용을 위한 확장 모듈입니다.
템플릿 사용을 위해 필수적으로 설치해주어야 하구요.
request 의 경우 외부 API를 호출할 목적으로 설치해준 것인데 차차 등장합니다.
결과화면은 아래와 같습니다.
※ 어떤 경우에는 ejs 와 request 가 설치되지 않는 경우가 가끔 있는데요.
이 때는 새로운 폴더에서 처음부터 다시 설치한 다음 소스만 옮기는 방법과
모듈을 전역설치 후 링크해 사용하는 방법으로 대체할 수 있습니다.
모듈을 전역 설치방법과 링크하는 방법은 아래와 같습니다.
설치가 안될 때는 대체해서 사용해 주시면 됩니다.
npm install ejs -g
npm link ejs
npm install request -g
npm link request
폴더와 소스 구성
이제 폴더를 2개 만들어 주세요.
첫번째는 정적 이미지를 보관할 public 폴더와
템플릿 문서를 보관할 views 폴더입니다.
sudo mkdir public
sudo mkdir views
sudo chown ec2-user:ec2-user public
sudo chown ec2-user:ec2-user views
참고로 템플릿 방식은 지난 스토리에 다루었던 정적 웹사이트와 함께 사용할 수 있습니다.
그러니까 정적 웹문서는 public 폴더에 저장하고
템플릿 문서는 views 폴더에 저장하면 구분이 수월해 집니다.
이제 main.js를 아래 소스와 같이 입력, 저장해 주세요,
저장할 폴더는 /home/nodejs4 입니다.
const express=require('express');
const request=require('request');
const ejs=require("ejs");
const app=express();
app.set('view engine', 'ejs');
app.set('views', './views');
// public 폴더하위의 파일들을 기본으로 서비스
app.use(express.static('public'));
app.get('/randomdog', function(req,res) {
request("https://random.dog/woof.json", function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
let object = JSON.parse(body);
res.render('randomdog', {
imagesize: object.fileSizeBytes,
imageurl: object.url
});
}
});
});
// 페이지를 찾을 수 없음 오류 처리
app.use(function(req, res, next) {
res.status(404);
res.send(
'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">' +
'<html><head><title>404 페이지 오류</title></head>' +
'<body><h1>찾을 수 없습니다</h1>' +
'<p>요청하신 URL ' + req.url + ' 을 이 서버에서 찾을 수 없습니다..</p><hr>' +
'</body></html>'
);
});
app.listen(8080, function() {});
그리고 아래 소스를 views 폴더 내에 randomdog.ejs 라는 이름으로 저장합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>랜덤 강아지</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>랜덤한 강아지가 화면에 표시가 되요</h1><br/>
용량 : <%=imagesize%> bytes.<br/>
<div style="border:5px solid black;padding:5px; width:550px;heght:550px;">
<img src='<%=imageurl%>' width='500' height='500' style='text-align:center'>
</div>
API 정보 : https://random.dog/woof.json
</body>
</html>
이제 노드 서버를 시작하고,
node main.js
웹브라우저에서 퍼블릭IP:8080/randomdog 이라는 URL로 접속합니다.
면을 맛있게 먹는 영상의 강아지 두마리가 등장했군요.
가끔은 이렇게 움직이는 GIF가 등장하기도 합니다.
F5 키로 화면을 새로 고침하면, 어휴 앙증맞은 강아지가 등장하지 않았습니까?
F5 키로 새로 고침할 때마다 사진이 계속 변경됩니다.
이와 같이 사전에 문서를 만들어 놓고 빈 곳을 쏙쏙 채워넣는 것이 템플릿의 핵심입니다.
이제 템플릿과 관련된 코드를 하나씩 뜯어볼까요?
우선 이 예제에서 템플릿 문서는 아래와 같은데요. views 폴더에 있는 randomdog.ejs 파일입니다.
ejs 템플릿의 경우 문서의 확장자는 ejs 를 사용해야 합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>랜덤 강아지</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>랜덤한 강아지가 화면에 표시가 되요</h1><br/>
용량 : <%=imagesize%> bytes.<br/>
<div style="border:5px solid black;padding:5px; width:550px;heght:550px;">
<img src='<%=imageurl%>' width='500' height='500' style='text-align:center'>
</div>
API 정보 : https://random.dog/woof.json
</body>
</html>
이 중에서 눈여겨 보실 부분은 <%=imagesize%> 과 <%=imageurl%> 입니다.
이 부분을 제외하고는 이 템플릿은 완성된 HTML 문서이기 때문입니다.
node.js 에다가 이 부분에 채워넣을 값을 전달해서 표시해달라고 요청하면 이 문서가 표시되는 것이지요.
node.js 가 실행하는 main.js 에서 아래코드가 추가되었는데요
const request=require('request');
const ejs=require("ejs");
:
app.set('view engine', 'ejs');
app.set('views', './views');
:
app.get('/randomdog', function(req,res) {
request("https://random.dog/woof.json", function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
let object = JSON.parse(body);
res.render('randomdog', {
imagesize: object.fileSizeBytes,
imageurl: object.url
});
}
});
});
아래 2개의 코드는 request 모듈과 ejs 모듈을 불러옵니다
const request=require('request');
const ejs=require("ejs");
그리고 나서 express 에게 템플릿 문서로 사용할 엔진이 ejs 라고 알려주는 부분과
app.set('view engine', 'ejs');
그리고 템플릿 문서가 보관된 폴더는 views 폴더다~ 라고 알려주는 부분이 추가되었습니다.
app.set('views', './views');
그리고 퍼블릭IP:8080/randomdog 이라는 URL 이 불려질때 실행하는 코드 부분이 정의가 되었는데요.
app.get('/randomdog', function(req,res) {
:
});
그 때 랜덤하게 강아지 이미지를 가져오는 오픈 API 를 호출합니다. ( API 주소 : https://random.dog/woof.json )
이 때 request 모듈이 사용됩니다.
사용법 : request("https://random.dog/woof.json", function(error, response, body) { ... });
그리고 오픈 API를 호출하여 성공하든 실패하든 그 결과를 가지고 function() 이라 명시한 부분 중괄호 안쪽부분이 실행됩니다.
app.get('/randomdog', function(req,res) {
request("https://random.dog/woof.json", function(error, response, body) {
:
});
});
그리고 오류가 없었는지 확인한 다음 오류가 없었다면,
또 다시 중괄호 안쪽을 실행할텐데요. => if (!error && response.statusCode == 200) { ... }
app.get('/randomdog', function(req,res) {
request("https://random.dog/woof.json", function(error, response, body) {
if (!error && response.statusCode == 200) {
:
}
});
});
중괄호 안쪽에서 템플릿에 문서를 채워 전달하는 기능을 수행합니다.
결과값을 서버 창에 한번 표시해준 다음
console.log(body);
json 형식으로 묶어서 온 문자열을 오브젝트 형태로 변환해 줍니다.
오브젝트로 변환해주어야 상세 내용의 확인이 가능하기 때문입니다.
JSON.parse 는 자바스크립트의 내장 함수이기 때문에 바로 사용이 가능합니다.
let object = JSON.parse(body);
이 API 의 json 문자열은 하나를 샘플로 들자면 아래와 같은데요.
{"fileSizeBytes":139246,"url":"https://random.dog/55f59ffd-5682-4c8e-a539-cdc445802ac7.jpg"}
이 경우 파일크기가 139,246 바이트이고,
이미지 파일의 URL 이 https://random.dog/55f59ffd-5682-4c8e-a539-cdc445802ac7.jpg 이라는 의미입니다.
이 내용이 오브젝트 형태로 변환되면 아래와 같이 찾기 쉽게 표 형태(또는 트리 형태)로 변환이 됩니다.
이 값이 object 에 대입되는 것이지요.
fileSizeBytes | 139246 |
url | https://random.dog/55f59ffd-5682-4c8e-a539-cdc445802ac7.jpg |
이 2개의 값을 최종적으로 템플릿에 전달해 문서를 완성하고 사용자의 웹브라우저에 출력하는 부분은 아래와 같습니다.
object 의 fileSizeBytes 속성에 들어 있는 값을 사용하려면 object.fileSizeBytes 이란 명칭을 ( 점 기호로 구분 ),
object 의 url 속성에 들어 있는 값을 사용하려면 object.url 이란 명칭을 사용하여 값을 전달하는 것입니다.
res.render('randomdog', {
imagesize: object.fileSizeBytes,
imageurl: object.url
});
주의하실 부분은 여기서 전달하는 좌측 부분의 제목은 템플릿에서의 명칭과 동일해야 한다는 것입지요.
틀리면 node.js 가 실행중 오류가 발생합니다, 다만 노드서버가 중지되지는 않습니다.
그래서 최종적으로 템플릿 문서를 완성하고 아래와 같은 랜덤한 강아지 이미지와 함께 이미지 파일의 용량이 표시가 되는 것이지요.
※ 위 API 는 오픈 API이며 관련 정보는 아래를 참조해 주세요.
https://www.programmableweb.com/api/randomdog-rest-api-v302
※ pug 템플릿? : node.js 에는 ejs 외에도 pug 라고 불리우는 템플릿이 있습니다.
ejs 와는 템플릿 문서의 구조가 상당히 다른데요.
앞에서 예로 든 문서의 형태는 아래와 같이 바꿔주시면 됩니다.
doctype html
html(lang='en')
head
meta(charset='UTF-8')
title 랜덤 강아지
link(rel='stylesheet' href='style.css')
body
h1 랜덤한 강아지가 화면에 표시가 되요
br
| #{imagesize} bytes.
br
div(style='border:5px solid black;padding:5px; width:550px;heght:550px;')
img(src=imageurl width=500 height=500 style='text-align:center')
| API 정보 : https://github.com/AdenFlorian/random.dog
그 외에도 main.js 에서 일부 변경되는 부분은 아래와 같으며
const pug=require("pug");
:
app.set('view engine', 'pug');
npm 에서도 먼저 pug 을 설치해주어야 합니다.
npm install pug
이와 같이 할 경우 템플릿 문서의 소스가 간결해지는 장점은 있지만,
HTML 코더가 디자인코드를 작성한 다음에, 다시 코드를 2차 변환해 작성해야 하는 이슈가 있습니다.
게다가 이 문서를 적절히 칼라풀하게 하이라이팅하는 에디터도 아직은 발견하지 못했습니다.
칼라링 없이 흑백 단색화면으로만 코딩하려면 좀.. 1995년대 TG에디터가 생각이 나는군요 ㅎㅎ..
이 형태가 어느정도 인기있는 문서가 되기 전까지는 글쎄요.
아직은 이 pug 템플릿 문서가 유용하게 활용도가 있다고는 생각되지 않습니다.
템플릿 문서에 대한 대략적인 이해가 수월하게 되셨는지 모르겠군요.
궁금하신 부분 문의주시고 오늘도 여기까지 읽어주신 분들께 감사드립니다 :)
구독과 좋아요는 ♥ 입니다 :)
넥스트 스토~리 / node.js express | 템플릿 쪽지함#1. 구경편
https://itadventure.tistory.com/438
'코딩과 알고리즘' 카테고리의 다른 글
node.js express | 템플릿 쪽지함#2. 배열의 템플릿 전달 (2) | 2021.08.29 |
---|---|
node.js express | 템플릿 쪽지함#1. 구경 (0) | 2021.08.25 |
node.js express | 동적 웹페이지 BASIC (0) | 2021.08.21 |
node.js with express 프레임워크 | 정적 웹사이트 만들기 (0) | 2021.08.21 |
node.js with fs 모듈 | 파일 시스템으로 첫페이지 보여주기 (0) | 2021.08.20 |