birchholt 직접 해보고 남기는 기록

Hugo 0.146 이후 _default 와 partials 를 옮기다가 태그 페이지가 전부 비었습니다

Hugo v0.146.0 에서 템플릿 시스템이 새로 짜이면서 layouts/ 폴더 규칙이 바뀌었습니다. _default 폴더는 없어지고 partials 는 _partials 가 됐습니다. 그럼 뭘 어디로 옮겨야 하는지, 안 옮기면 뭐가 깨지는지를 직접 재봤습니다.

낡은 서랍장에서 새 선반으로 물건을 옮기다가 이름표가 떨어진 빈 상자 하나를 들고 있는 사람

이 블로그 템플릿은 이미 새 구조입니다. 그래서 같은 파일을 옛 위치로 되돌린 사본을 만들고 v0.145.0(바뀌기 직전)과 v0.165.0(지금) 바이너리로 각각 빌드했습니다. 2026-10-04 작업이고 결과물은 파일 단위로 diff 했습니다.

옛 구조 그대로 올려도 대부분은 똑같이 나옵니다

헌 지도와 새 지도를 겹쳐 창가에 대 보니 길이 거의 그대로 겹쳐 보이는 장면

되돌린 구조는 이렇습니다. 파일 내용은 하나도 안 바꾸고 이름과 위치만 옮겼습니다.

layouts/_default/baseof.html     ← baseof.html
layouts/_default/single.html     ← page.html
layouts/_default/list.html       ← section.html
layouts/index.html               ← home.html
layouts/partials/*.html          ← _partials/*.html
layouts/_default/_markup/        ← _markup/
구조v0.145.0v0.165.0
옛 구조성공, HTML 27장성공, HTML 27장
새 구조실패(exit 1)성공, 옛 구조와 0개 파일 차이

같은 v0.165.0 에서 옛 구조와 새 구조의 결과물이 한 바이트도 다르지 않았습니다. 공식 문서도 「old to new」로 옛 이름을 새 이름에 대응시켜 호환을 최대한 유지하려 했다고 적고 있습니다. 다만 깨진 사례도 보고됐다고 같이 적혀 있습니다 (New template system overview, 2026-10-04 확인).

거꾸로가 더 위험했습니다. 새 구조를 v0.145.0 으로 빌드하면 바로 죽습니다.

WARN  found no layout file for "html" for kind "page"
ERROR ... error calling partial: partial "head.html" not found

구버전은 _partials/ 를 모릅니다. 폴더를 옮긴 뒤에는 CI·배포 환경의 Hugo 버전도 0.146.2 이상인지 먼저 보셔야 합니다(이유는 아래 0.146.0 절에 있습니다).

경고 없이 바뀐 것 하나 — list-baseof.html

현관 매트만 바뀌었는데 손님들이 모두 다른 문으로 들어가는 집

옛 구조 방식의 파일을 더 얹었습니다. 목록 전용 뼈대 _default/list-baseof.html, 태그용 terms.html·taxonomy.html, 섹션 전용 section/posts.html 입니다. 템플릿마다 숨긴 표식 문자열을 넣어 어떤 파일이 어느 페이지를 그렸는지 결과물에서 뽑았습니다. 꺼두었던 태그 페이지도 실험에서는 켰습니다.

페이지v0.145.0 뼈대v0.146.0 · v0.146.2 · v0.165.0 뼈대
홈, /posts/, /tags/, /tags/hugo/list-baseof.htmlbaseof.html
글 본문, 404baseof.htmlbaseof.html

v0.146.0 부터 list-baseof.html 은 그냥 무시됩니다. 빌드는 성공하고 경고도 없습니다. 목록 페이지만 다르게 생긴 사이트라면 그 차이가 말없이 사라집니다. v0.165.0 에서 --logLevel info 로 빌드해도 관련 메시지는 없었습니다.

나머지(_default/terms.html, _default/taxonomy.html, section/posts.html, partials/)는 옛 위치에 둔 채로는 v0.165.0 에서도 옛 뜻대로 쓰였습니다.

옮기는 도중에 태그 페이지 17장이 비었습니다

책장 칸마다 이름표는 붙어 있는데 책이 한 권도 꽂혀 있지 않은 서가

공식 문서 표의 첫 줄대로 _default/ 안의 파일을 전부 layouts/ 바로 아래로 올렸습니다. 이름은 안 바꿨습니다.

빌드는 성공, 경고 0줄이었습니다. 그런데 태그별 페이지 17장 전부에서 글 카드가 0개가 됐고 HTML 파일은 65장에서 48장으로 줄었습니다. 줄어든 17장은 태그마다 있던 page/1/ 리디렉션 파일입니다.

원인은 이름의 뜻이 바뀐 데 있었습니다. 공식 문서에 적혀 있습니다.

A template named taxonomy.html used to be a candidate for both Page kind term and taxonomy, now it’s only considered for taxonomy.

제 실험에서는 _default/ 안에 있을 때 taxonomy.html 이 예전처럼 태그 하나의 글 목록(term)을 그렸습니다. 루트로 올리자 태그 전체 목록(taxonomy)에만 쓰였습니다. 태그 하나의 페이지는 갈 곳을 잃고 list.html 로 떨어졌고 제 list.html 로는 그 페이지에서 글 카드가 하나도 나오지 않았습니다.

어떤 파일이 실제로 쓰였는지는 --templateMetrics 로 바로 보입니다.

$ hugo --templateMetrics --renderToMemory
옮기기 전횟수옮긴 직후횟수
_default/taxonomy.html17list.html17
_default/terms.html3taxonomy.html3

두 번 빌드한 출력에서 template·count 열만 옮겼습니다. 같은 실험에서 이름을 taxonomy.html → term.html, terms.html → taxonomy.html 로 바꾸자 17장이 다시 채워졌습니다. 업그레이드 뒤 태그 페이지가 안 나온다는 질문에 term.html 을 쓰라는 답이 달린 포럼 글도 있습니다 (Taxonomy not working after upgrade). 다른 글은 _default/ 안에서도 term 이 taxonomy.html 을 쓴다고 하는데, 제가 v0.146.0·v0.165.0 에서 해 본 결과로는 재현되지 않았습니다.

한 단계씩 옮기며 잰 이전표

옛 상자에서 새 서랍으로 물건을 하나씩 옮기며 체크 표시 대신 작은 돌을 하나씩 올려두는 손

v0.165.0 으로 한 단계 옮길 때마다 빌드하고, 바로 앞 단계와 결과물을 비교했습니다.

단계한 일바뀐 파일결과
1partials/ → _partials/0그대로
2_default/* → layouts/37태그 페이지 17장 빔
3list-baseof.html → baseof.list.html0아무것도 안 고쳐짐
4taxonomy.html → term.html, terms.html → taxonomy.html37태그 페이지 복구
5index.html → home.html, single.html → page.html, section/posts.html → posts/section.html0그대로
6baseof.list.html 대신 baseof.home.html·baseof.section.html·baseof.taxonomy.html·baseof.term.html23목록 뼈대 복구

2와 4는 반드시 같이 하셔야 합니다. 사이에 배포가 끼면 그동안 태그 페이지가 빈 채로 나갑니다.

3번은 문서대로 이름을 바꿨는데 바뀐 게 없었습니다. baseof.list.html 은 list.html 로 그려진 페이지에만 붙었습니다. 홈(index.html), 섹션(section/posts.html), 태그 전체 목록(taxonomy.html)처럼 다른 템플릿으로 그려지는 목록 페이지에는 붙지 않았습니다. 예전처럼 목록 계열 전부에 붙이려면 6번처럼 페이지 종류별로 나눠야 했습니다. 6번까지 마친 결과에서 페이지마다 어느 템플릿이 쓰였는지가 v0.145.0 옛 구조와 6개 대표 페이지 모두 일치했고 목록 페이지 파일 크기도 바이트 수까지 같았습니다.

반쯤 옮긴 상태도 하나 봤습니다. partials/header.html 과 _partials/header.html 을 같이 두면 v0.145.0 은 partials/ 를, v0.165.0 은 _partials/ 를 씁니다. 새 버전에서는 옛 폴더를 남겨둔 채 그 안의 파일을 고쳐도 화면이 안 바뀝니다.

0.146.0 과 0.146.1 은 건너뛰세요

같은 편지를 넣었는데 한 우체통에서만 그림 엽서로 바뀌어 나오는 두 우체통

중간 버전도 빌드해 봤다가 구조와 상관없는 문제를 하나 만났습니다. v0.146.0 과 v0.146.1 에서는 언어를 안 적은 코드블록이 SVG 그림(GoAT 다이어그램)으로 바뀌어 나왔습니다.

soft-404 글 HTML  v0.145.0: 18,512 B   v0.146.0·v0.146.1: 51,232 B   v0.146.2: 18,512 B

글 다섯 편에서 코드블록 15개가 글자 하나하나 <text> 로 쪼개진 그림이 됐습니다. 옛 구조든 새 구조든 같았습니다. v0.146.2 릴리스 노트의 「Fix codeblock hook resolve issue」(#13593)로 고쳐졌습니다. 버전을 핀으로 고정해 쓰신다면 0.146 대에서는 최소 0.146.2 로 잡으세요.

다시 옮긴다면 이 순서로 하겠습니다

새 선반 앞에서 옛 서랍장을 비우기 전에 각 칸의 사진을 먼저 찍어 두는 사람
  1. 옮기기 전에 지금 Hugo 로 한 번 빌드해서 public/ 을 따로 복사해 둡니다. 비교 기준입니다.
  2. hugo --templateMetrics --renderToMemory 로 실제로 쓰이는 템플릿 목록을 적어 둡니다.
  3. partials/ → _partials/ 로 이름을 바꾸고 옛 폴더는 지웁니다.
  4. _default/ 를 올리는 것과 taxonomy.html·terms.html 이름 정리는 한 커밋으로 합니다.
  5. *-baseof.html 이 있었다면 baseof.<종류>.html 로 나누고 그 뼈대를 받던 페이지가 지금도 받는지 확인합니다.
  6. 다시 빌드해서 1번 결과와 diff -rq 합니다. 빌드 성공과 경고 없음은 근거가 안 됩니다. 이번에 틀어진 건 전부 빌드가 성공했고 그 문제를 알리는 경고는 한 줄도 없었습니다.
  7. 배포 환경의 Hugo 버전이 0.146.2 이상인지 봅니다.

테마를 쓰는 경우는 이번에 재현하지 않아서 적지 않았습니다.