hugo 자주쓰는 명령어 및 디렉터리 구조
2023년 6월 3일
자주 사용하는 명령어 #
버전 확인 #
1hugo version
서버 로드 #
1hugo server
2 --port=[port] # export 포트지정 (1313)
3 --bind=[bindIP] # 외부와 연결될 인터페이스 (127.0.0.1)
4 --contentDir=[dir] # 컨텐츠 디렉터리 지정 (./content)
5 --themesDir=[dir] # 테마 디렉터리 지정 (./themes)
6 --source=[dir] # hugo 소스 디렉터리 지정 (.)
7 --ignoreCache # 휴고 서버 캐시를 무시한다
8 -D # 미게시(draft) 상태의 글도 표시하기
9 --liveReloadPort=[port] # 라이브리로드 포트 변경
10# 마지막으로 수정한 페이지로 자동 리다이렉션되는 옵션
11# baseURL이 사용되기 때문에 내 환경에서는 appendPort 옵션도 꺼줘야한다
12 --navigateToChanged
13 --appendPort=[true/false] # baseURL에 포트를 붙일건지 옵션 (true)
사이트 프레임 생성 #
1hugo new site [folder]
컨텐츠 생성 #
1hugo new
2 --kind=[type] # 컨텐츠 메타데이터 type을 지정해서 생성
디렉터리 구조 #
site를 하나 생성하면 아래의 트리구조로 생성된다.
1site/
2├─ archetypes/
3│ └─ default.md
4├─ assets/
5├─ content/
6│ ├─ blog/
7│ └─ about/
8├─ data/
9├─ layouts/
10├─ public/
11├─ static/
12├─ themes/
13└─ hugo.toml
archetypes #
hugo new로 컨텐츠를 생성하면 archetypes의 스켈레톤 파일을 이용해서 파일을 생성하게 되는데,
이때 hugo에서는 스켈레톤 파일전체에서(컨텐츠 내용부분까지) go 템플릿 구문{{ here }} 내부의 변수를 자동으로 치환해준다.
각 content 섹션의 md 파일을 먼저 확인한 후 없으면 default.md를 사용하게된다.
- content의 하위폴더를 말하며 예시에서는 blog, about 섹션이 있다.
--kind옵션을 사용하면 archetype을 직접 지정할 수 있다.
archetypes 파일을 찾는 순서 #
- archetypes/section.md
- themes/[theme]/archetypes/section.md
- archetypes/default.md
- themes/[theme]/archetypes/default.md
Example #
파일의 윗부분엔 — 로 감싸진 영역이 있는데, 이것을 Frontmatter라고 부른다. content의 스켈레톤 파일이기 때문에 archetypes 파일에서도 존재한다. 당연하게도 문서 내용까지 archetypes 파일에 포함시킬 수 있다.
1---
2title: "{{ replace .Name "-" " " | title }}"
3date: {{ .Date }}
4lastmod: .Date
5draft: true
6---
7
8문서 제목:
9게시자:
10게시일:
Frontmatter는 문서가 렌더링될때 참고될 수 있는 값들을 의미한다. hugo 프로젝트 자체에서 공통적으로 사용하도록 정의해둔것도 있지만 theme 자체에서 참고하는 값도 있다.
Frontmatter로 지정한 변수는 layout 과 같은 .html 파일에서 .Params 를 통해 접근할 수 있다.
-
title: 문서의 제목이다. 보통 메뉴리스트에서 보여질 이름, permalink 주소에서 사용되는 문서제목외에도 렌더링시 사용되기도 한다.
hugo new section/aaa/bbb/file-name.md형식으로 파일을 생성하면 file-name이 .Name이 되며, archetypes에 정의된 코드대로 -를 공백으로 치환하여 “file name” 이라는 문자열이 파이프를 통해 title변수에 저장된다. -
date: .Date는 시스템의 현재 시간을 나타내는 내장변수이다. 파일 생성 시 archetypes를 참고하며 현재 시간을 집어넣기 때문에 파일을 만든 시간이 된다.
-
lastmod: 마지막 게시글 수정날자를 의미한다. 중괄호 없이 .Date만 지정하면 content화 될때도 .Date 문자열 그대로 전달되고, lastmod 값이 수정된다. .Date는 현재 시간을 의미하는데, 빌드될때 치환되기 때문에 마지막 수정시간이 기록된다. 수정되지 않으면 리빌드가 발생하지 않아서 이전 값이 유지된다.
1lastmod: .Date
-
draft: 파일을 게시할것인지 여부이며 false일때 블로그에 게시된다.
-
aliases: 기존 URL 대신 접근할 별칭 URL을 지정할 수 있다. 예시처럼 지정하면 기존 URL 외에도 http://url.com/alias/post1, http://url.com/alias/post2 로도 접근할 수 있다.
1aliases: ["alias/post1", "alias/post2"]
-
tags, categories: 게시글의 카테고리와 태그를 지정할 수 있다. config 파일의 taxonomies 설정에 따라 추가적인 분류도 지정할 수 있고 자체적으로 분류 검색 기능을 지원한다.
-
weight: 메뉴나 index 페이지에서 보여질 게시글의 순서를 지정한다. weight가 낮을수록, 최신 글일수록 위쪽에 리스팅된다.
-
type: 컨텐츠의 분류를 지정하며, 렌더링할 layout의 모습까지 변경된다.
-
layout: 레이아웃을 지정할 수 있다. (v0.88이후 삭제)
content #
모든 정적페이지 컨텐츠만 저장되는 폴더.
각 섹션(디렉토리)의 루트 경로에서 표시할 컨텐츠는 _index.md 파일이 된다.
_index.md 파일은 리스트페이지라고 부르며, post.md 같은 일반 콘텐츠들은 싱글페이지라고 부른다.
1content/
2 blog/
3 _index.md # http://url.com/blog/ => blog의 인덱스페이지
4 post1.md # http://url.com/blog/post1
5 post2.md # http://url.com/blog/post2
6 work/
7 post3.md
8 tool/
9 _index.md # http://url.com/work/tool/
10 _index.md # http://url.com/
11 about.md # http://url.com/about
blog, work, work/tool 모두 섹션이라고 부르지만, 템플릿을 지정하는 archetype과 관련된 섹션은 blog, work 같은 최상위 섹션이다.
work/post3.md 와 work/tool/_index.md 는 같은 archetypes/work.md 를 참조한다.
content의 Frontmatter #
archetypes 스켈레톤 파일을 기반으로 생성되어 스켈레톤 파일의 frontmatter를 그대로 가져온다.
스켈레톤 파일은 생성중 파싱과정에서 템플릿변수를 치환하게되지만,
content에서는 frontmatter에 템플릿 없이 변수를 사용할 수 있고 파일이 빌드될때 frontmatter를 파싱해서 변수를 치환해둔다.
archetypes를 설명할때 lastmod 에는 go 템플릿 형식으로 지정하지 않았다. .Date라는 문자를 그대로 content화 시키게 되면, content의 Frontmatter는 리빌드될때 변수가 치환되기 때문에 리빌드 시간이 lastmod로 찍히게 된다.
1---
2# 현재 시간을 의미하지만 리빌드 될때마다 치환되기 떄문에
3# liveReload 기능을 켜두면 파일이 수정된(리빌드된) 시간을 의미하게된다.
4lastmod: .Date
5---
6
7컨텐츠 내용
layouts #
content 폴더의 .md 파일은 컨텐츠에 불과하고, 컨텐츠의 데이터를 어떤 모양으로 렌더링할지 정의된 템플릿 html 코드가 layouts 폴더에 구현되어 있다.
모든 레이아웃은 _default/baseof.html 기준으로 구현되며, 내부의 block을 재정의해서 타입별 레이아웃을 구현하게 된다. (자세한건 아래에 서술)
레이아웃의 자동선택 #
레이아웃도 최상위 섹션에 해당하는 폴더가 없다면 _default 폴더에서 결정되며, _index.md 파일은 list.html, 그 외 파일은 single.html이 선택된다.
hugo의 테마 상속구조상 테마를 지정했다면 themes의 레이아웃 파일이 먼저 적용되고, 특정 레이아웃이 없다면 루트의 layouts를 지정하게된다.
1layouts/
2 _default/
3 baseof.html # 모든 템플릿의 메인과 같은 역할
4 list.html # work/_index.md, work/tool/_index.md
5 single.html # work/post3.md, ...
6 blog/
7 list.html # blog/_index.md
8 single.html # blog/post1.md
9 partials/ # 재사용 가능한 템플릿 코드들
레이아웃의 수동선택 #
같은 섹션이 아니더라도 컨텐츠의 메타데이터로 type을 직접 지정하면 템플릿을 지정할 수 있다.
work 섹션이지만, frontmatter에 type을 지정해서 blog 타입으로 템플릿을 지정해서 blog 형식으로 글을 렌더링할 수 있게된다.
1# work/post4.md
2---
3title: "test title"
4weight: 3
5date: 2023-06-03T08:24:29Z
6type: blog # work 섹션이지만, blog 형식의 layout 사용
7---
레이아웃의 구현 #
레이아웃은 html 코드와, go의 템플릿 문법을 이용해서 만들게 되는데,
메인이 되는 baseof.html 템플릿을 확장하여 block들을 define으로 재정의해서 구현하는 방식이다.
baseof.html은 모든 페이지에서 통일할 레이아웃이 구현되어 있고, 블록이 재정의 되지 않았다면 기본값으로 지정된 값이 출력되도록 만들어져 있다.
1<!-- layouts/_default/baseof.html -->
2<!DOCTYPE html>
3<html>
4 <head>
5 <meta charset="utf-8">
6 <title>
7 {{ block "title" . }} <!-- title 구현 -->
8 {{ .Site.Title }} <!-- 기본값 -->
9 {{ end }}
10 </title>
11 </head>
12 <body>
13 {{ block "main" . }} <!-- main 구현 -->
14 {{ end }}
15 {{ block "footer" . }}
16 {{ end }}
17 </body>
18</html>
19
20<!-- layouts/_default/single.html -->
21{{ define "title" }}
22 {{ .Title }} – {{ .Site.Title }}
23{{ end }}
24{{ define "main" }}
25 <h1>{{ .Title }}</h1>
26 {{ .Content }}
27{{ end }
static #
이미지, js, css 등 모든 정적 콘텐츠가 저장되는곳. 게시글 작성 시 이미지도 이곳에 저장할 계획이다.
컨텐츠에 포함될 이미지도 내 서버내부에 안전하게 저장되어야 하는데, 이미지를 저장하는 여러 방법이 있다.
- wget 으로 다운로드
이건 다른 웹서버에 이미지파일이 올라가있을때 사용가능하다. 보통 github의 이미지서버를 빌려서 issue에 업로드하고 그 경로를 wget으로 가져온다. - scp 프로그램
ssh로 서버와 연결이 가능하기 때문에 scp를 이용해서 파일을 옮길 수 있다. 나는 WinSCP프로그램을 이용할 예정이다. - 도커의 폴더에 마운트
내 환경은 시놀로지라는 NAS에 도커를 올려서 실행하기 때문에 도커의 이미지폴더에 NAS 폴더를 마운트해서 NAS폴더에 업로드하면 자동으로 서버에 올라가도록 구성할수도 있다.
경로는 /static/image/test.png 인 경우 static을 제외하고 /image/test.png 경로로 사용하면 된다.