Heesung Yang
Hugo - 03. 템플릿 구조
서론
템플릿 구조를 이해하기 위해 이전에 설치했던 ananke 테마를 사용하지 않고 layouts 폴더에 html 템플릿 파일을 생성하며 하나하나 그 구조를 파헤쳐보자.
-
config.toml
baseURL = "http://example.org/" languageCode = "en-us" title = "My New Hugo Site" # theme = "ananke" # << 삭제 (주석처리)
그리고 hugo server를 실행해보면, 아무것도 안나온다.
~$ hugo server -D
자, 이제 템플릿 구조를 파헤쳐보자.
List 템플릿
일단 layouts/_default/list.html
파일을 생성해보자. 생성 후 폴더 구조는 아래와 같다.
.
├── archetypes
│ └── default.md
├── config.toml
├── content
│ └── posts
│ └── first-post
│ ├── index.md
│ └── sample.png
├── data
├── layouts
│ └── _default
│ └── list.html << 추가
├── resources
│ └── 생략...
├── static
└── themes
└── ananke
list.html 파일을 아래와 같이 작성하자.
<!DOCTYPE html>
<html>
<head>
<title>List Template</title>
</head>
<body>
List Template
<ul>
{{ range .Pages }}
<li><a href="{{ .URL }}">{{ .Title }}</a></li>
{{ end }}
</ul>
</body>
</html>
그리고 다시 hugo 서버를 실행해보면
우리가 좀 전에 생성한 list.html
파일을 이용하여 html 페이지가 생성된 것을 확인할 수 있다.
Posts 링크를 눌러보면 또 다시 First Post라는 링크가 있는 List 페이지가 나타난다.
이 상태에서 포스팅 2개를 추가로 작성해보자.
hugo new content/posts/second-post.md
hugo new content/posts/third-post.md
각 포스팅의 내용은 아래와 같이 간단하게 작성하자.
-
content/posts/second-post.md
--- title: "Second Post" date: 2021-09-04T18:45:55+09:00 draft: true --- This is the second post
-
content/posts/third-post.md
--- title: "Third Post" date: 2021-09-04T18:46:00+09:00 draft: true --- This is the third post
자, 이제 다시 Posts 페이지를 확인해보면 아래와 같이 각 포스팅의 제목이 보이는 것을 확인할 수 있다. (http://localhost:1313/posts/
)
즉, list.html
파일은 작성된 포스팅 리스트를 표현하기 위해 사용하는 html 템플릿이다.
지금은 각 포스팅 제목을 클릭해보면 아무것도 나타나지 않는데 각 포스팅 내용이 나타나도록 single 템플릿을 추가해보자.
Single 템플릿
Single 템플릿은 바로 우리가 작성한 markdown 문서가 html로 변환될 때 사용하는 템플릿이다.
아래와 같이 layouts/_default/single.html
파일을 추가하자.
.
├── archetypes
│ └── default.md
├── config.toml
├── content
│ └── posts
│ ├── first-post
│ │ ├── index.md
│ │ └── sample.png
│ ├── second-post.md
│ └── third-post.md
├── data
├── layouts
│ └── _default
│ ├── list.html
│ └── single.html << 추가
├── resources
│ └── 생략...
├── static
└── themes
└── ananke
<!DOCTYPE html>
<html>
<head>
<title>Single Template</title>
</head>
<body>
Single Template
<h1>{{ .Title }}</h1>
<h6>{{ .Date }}</h6>
<p>{{ .Content }}</p>
</body>
</html>
그리고 각 포스트 링크를 클릭해보면 아래와 같이 우리가 markdown으로 작성했던 내용이 잘 보인다.
이게 전부다. 중요하니까 3번 적는다.
Hugo에서 각 페이지는 List 타입 또는 Single 타입 이다.
Hugo에서 각 페이지는 List 타입 또는 Single 타입 이다.
Hugo에서 각 페이지는 List 타입 또는 Single 타입 이다.
List 타입의 페이지는
- 블로그 접속 시 처음 보여주는 홈페이지
- 포스팅 리스트 페이지
- 포스팅마다 tag를 단 경우, 어떤 tag들이 있는지 보여주는 페이지
- 포스팅마다 category를 지정한 경우, 어떤 category들이 있는지 보여주는 페이지
등이 있고 Single 타입의 페이지는
- 우리가 작성한 markdown 파일들
- about 페이지 (자기소개 페이지)
등이 있다.
템플릿 문법
위에서 작성한 list.html
파일과 single.html
파일의 내용을 보면 일반적인 html과 다른, {{ }}
로 둘러쌓인 형식을 볼 수 있는데 이는 Go 언어에서 지원하는 템플릿 엔진에서 사용하는 문법이다.
미리 작성한 html 문서(템플릿)에서 필요한 부분만 변경하기 위해 템플릿 엔진을 사용한다.
아래 그림을 보면 좀 더 이해가 쉽다.
위 그림에 표현되어 있듯 우리가 작성한 markdown 문서가 템플릿을 거쳐 HTML 문서로 생성된다. 템플릿 엔진은 템플릿 파일로 넘어온 markdown 문서 내용을 참조할 수 있는 방법을 제공한다.(그래야 템플릿에 내용을 표현하니까) Hugo의 템플릿에서 참조할 수 있는 변수 종류는 공식문서에 자세히 나와 있다. 여기서는 주로 사용하는 변수만 먼저 살펴보겠다.
- markdown 문서의 meta data(front matter) 참조
- title :
{{ .Title }}
- date :
{{ .Date }}
- draft :
{{ .Draft }}
- title :
- 우리가 작성한 포스팅 내용
{{ .Content }}
- 그 외 Hugo가 자동으로 생성하는 변수들 (Hugo 공식 문서)
템플릿 문법은 단순히 변수를 참조하는 것 외에 Logic을 표현할 수도 있다. list.html
에서 사용했던 아래 문법을 보자.
-
반복문
{{ range .Pages }} {{ .Title }} {{ end }}
Pages
라는 리스트의 개별 object를 하나씩 참조한다.Pages
는Page
라는 object를 1개 이상 가진, 리스트 형태다.- 각
Page
object는 여러가지 속성을 갖고 있는데 대표적으로Title
,URL
,Content
,Date
등이 있다.- 위 single 템플릿에서 참조했던 변수가 바로
Page
object.
- 위 single 템플릿에서 참조했던 변수가 바로
- 각 속성은
Page.Title
과 같이.
을 이용하여 접근할 수 있다.
-
현재 변수
{{ . }}
-
현재
context
를 의미한다. -
예를 들어 위 반복문의 경우
{{ range .Pages }}
라고 했을 때Pages
가 갖고 있는 개별Page
object를 참고해야 하는데 이를.
로 참조 가능하다. -
Python의 반복문 표현식을 예로 들어 설명하면 아래와 같은 문법을
for page in pages: print(page.title)
-
다음과 같이 축약해서 사용한다고 이해하면 된다.
page
라는 변수가 반복문 안에서만 쓰이므로 굳이 변수를 선언하지 않고 default 변수로써.
을 사용하는 방식이다.# 아래 문법은 틀린 문법이다. 개념만 보자. for pages: print(.title)
혹시 Perl 언어를 사용해 본 적이 있다면
$_
변수와 같은 개념이라고 이해하면 된다. -
-
마치며
Hugo에서 템플릿을 어떤식으로 활용하는지 아주 기본적인 내용을 살펴보았다. 다음 글에서는 템플릿을 좀 더 구조적으로 작성하는 방법에 대해 알아볼 예정이다.
Previous post
Hugo - 02. 이미지 파일 첨부하기