Pug, Template (Recap)

Iteration과 mixin을 복습해본다.

왜냐하면 두가지를 프론트 엔드에서 꽤 자주 사용 하게 된다.

거의 Iteration을 자주 쓰고 mixin은 가끔 쓰게 될것이다.

Iteration은 array의 모든 element에 대해 특정 행동을 취할때 사용한다.



videoController.js에서

video라는 array를 보내주고 있다.


const videos = [

{

title: "First Video",

rating: 5,

comments: 10,

createdAt: "2 hours ago ",

views: 100,

id: 1,

},

{

title: "Second Video",

rating: 3,

comments: 5,

createdAt: "25 minutes ago ",

views: 20,

id: 1,

},

{

title: "Third Video",

rating: 4,

comments: 8,

createdAt: "2 minutes ago ",

views: 80,

id: 1,

},

];

return res.render("home", { pageTitle: "Home", videos });

videos들을 이렇게 보내주고 있다.

이제 "home" (variable)은 home.pug로 보내진다.

home.pug

each view in videos

+video(view)

videos 배열을 이렇게 쓸수 있다.

그래서 each X in Y 형태로 Y 안의 각각의 X에 대해서 동일한 작업을 할수 있다.

여기서 Y는 현재 가지고 있는 array를 가리킨다.

그리고 videos 이 부분은 video 객체의 array 이어야 할 필요는 없다.

예를 들어 숫자의 array 여도 좋다.

아니면 그냥 이렇게 array를 바로 만들어 써도 괜찮다.

each x in [1, 2, 3, 4, 5]

li=x

새로고침을 해보면 리스트로 1~5까지 나오는걸 확인할수 있다.

앞으로 이런걸 많이 해볼거다.

비디오 array를 가져와서 꽤 많은 비디오를 보여줄것이다.

또는 댓글 array도 가져오고 이런 모든게 iteration이다.

each X in Y 에서 variable의 이름은 중요하지 않다.

중요한건 Y 가 무조건 list여야 한다는 거다.



실제로 res.render로 보내는 variable의 이름을 쓰면 된다.

매우 중요한 사실은 each X in Y 에서 Y는 반드시 존재해야 한다는 거다.

Y가 없으면 문제가 생긴다.

each view in [ ]

+video(view)

else

div Sorry nothing found.

만일 array 안에 어떤 element도 존재 하지 않을 경우 else 의 조건이 있는 이유이다.

이건 JavaScript에서는 볼수 없는 구조이다.

pug에 있는 문법이다.

pug는 똑똑하기 때문에 Y가 빈 array이거나 length가 0이면 바로 알아차려서 보여준다.

mixin

each x in videos

li=x

videos가 render로 보내지는 variable이란걸 알고 있다.

새로고침을 해보면 object Object라고 나온다.

이건 왜냐하면 videos에서 각각의 X는 JavaScript객체이기 때문이다.

each X in videos에서 X는 객체이다.

그래서 X를 좀더 나은 방법으로 보여줘야 한다.

x.title을 써볼수 있다.

li=x.title

그러면 title이 나오는걸 알수 있다.

유투브를 가보면 온통 video block이다.

뭔가를 검색할 때도 video block, 트렌딩 페이지에서도 video block,

사이드바에 있는 관련 동영상들도 video block이다.

이럴 때 UI component를 재사용 해야 한다.

video block을 만들어 줘야 한다.

제목, 평점, 댓글수 ,게시 날짜 이런 것들을 보여주고 싶다.

그런 것들을 홈페이지 , 검색 페이지 , 프로필 페이지에서

똑같은 형태의 html 블록을 여러 페이지에서 보여줘야 한다.

이 때 필요 한게 mixin이다.



mixin은 이미 만들어진 html 조각과 같은거다.

바깥 세계로부터 정보를 가져오는 역할을 한다.

이미 만들어진 html 조각을 본적이 있다.

footer에서 보았다.

허나 footer는 그냥 html 블록으로서 매번 새 페이지를 만들때마다 import를 해야 했다.


footer을 수정 하고 싶을때는 footer.pug로 가서 수정해 주면

모든 페이지에 적용이 되기 때문에 좋은 방법이긴 하다.

하지만 footer는 정보를 가져오거나 하지 않는다.

footer는 그저 똑같은 것만 계속 보여줄 뿐이다.

mixin video(info)

div

h4=info.title

ul

li #{info.rating}/5.

li #{info.comments} comments.

li Posted #{info.createdAt}.

li #{info.views} views.

반면 video는 일종의 partial인데 이건 다른 세계로부터 정보를 가져오는 역할도 수행한다.

마치 html 내용물을 return 하는 JavaScript의 function과도 같은거다.

그리고 html 내용물은 계속 변할수 있다.

그래서 video를 사용하는 방법은 첫째로 include mixins/video를 해줘야 한다.

그 다음에 +video()를 해줘야 한다.

home.pug

include mixins/video

block content

h2 Welcome here you will see the trending videos.

each view in videos

+video(view)

video는 argument가 필요하다.

(이 경우에는 argument는 info이지만)

argument가 없게 되면

TypeError: /Users/j.mercury/Documents/wetube/src/views/mixins/video.pug:3

1| mixin video(info)

2| div

> 3| h4=info.title

4| ul

5| li #{info.rating}/5.

6| li #{info.comments} comments.

Cannot read properties of undefined (reading 'title')

이런 에러가 뜨게 된다.

에러를 자세히 보면 info.title이라는 코드를 실행하려 하는데

video mixin에 어떤 데이터도 보내주지 않고 있다.

그래서 info에는 undefined가 된거다.

undefinde는 title을 가지고 있지 않다.

video mixin에 데이터를 보내줘야 한다.

그래서 view라는 variable을 통해 각각의 item에 접근할수 있다.

이제 view를 video mixin으로 보내주고 있다.

video mixin은 view를 받으면서 모든 정보들에 접근하는 중이다.

그래서 새로고침 해보면 잘 작동하는걸 알수 있다.

mixin video(info)

div

h4=info.title

ul

li #{info.rating}/5.

li #{info.comments} comments.

li Posted #{info.createdAt}.

li #{info.views} views.

보다시피 똑같은 html의 형태지만

그러나 안에 포함하고 있는 내용은 각기 다르다.

바로 mixin의 힘이다.

html을 return하는 일종의 function인 셈이다.

그리고 그 function을 template에 쓸수 있다.

약간의 다른 점은 +를 해줘야 한다는 거다.

반면에 footer에는 +를 안 붙였다.

footer는 단순한 html이기 때문이다.

mixin을 사용하고 싶다면 +를 붙여준다.

그리고 mixin을 template에 include 해줘야 한다.

좋은 웹페이지 즐겨찾기