이 문서는 다음 유지보수자를 위한 인수인계 기록이다.
이번 패스의 핵심은 문자열, 메뉴, 언어 URL 정책을 모두 중앙화해서, 나중에 언어가 더 늘어나도 같은 규칙으로 확장할 수 있게 만든 것이다.
이번 패스의 핵심 수정
1) 메뉴의 단일 원본을 config/_default/hugo.toml 로 이동
파일:
config/_default/hugo.toml
변경 내용:
[[menus.main]]을 한 곳에만 두어 전체 언어가 같은 메뉴 정의를 공유하도록 정리했다.identifier는 번역 키와 동일하게 유지했다.pageRef기반으로 현재 언어의 대응 페이지를 자동 연결하도록 정리했다.
중요한 이유:
- 메뉴 문구를 언어 파일마다 복제하지 않아도 된다.
- 새 언어를 추가해도 메뉴 구조는 한 번만 수정하면 된다.
2) 언어 메타 파일은 최소 정보만 유지
파일:
config/_default/languages/languages.ko.tomlconfig/_default/languages/languages.en.tomlconfig/_default/languages/languages.jp.tomlconfig/_default/languages/languages.cn.toml
변경 내용:
- 언어별 메타, 로케일, 콘텐츠 경로, 정렬 순서만 남겼다.
- 메뉴 블록은 제거하고
hugo.toml의 중앙 메뉴 정의만 사용한다. - 기본 언어가
/ko/같은 서브디렉터리로 노출되는지는 언어 파일이 아니라hugo.toml이 제어한다.
중요한 이유:
- 언어 설정과 메뉴 설정의 책임이 분리된다.
- 언어 파일은 콘텐츠 경로와 표시 메타만 책임지게 된다.
3) 기본 언어도 하위 경로를 쓰도록 URL 정책을 고정
파일:
config/_default/hugo.toml
변경 내용:
defaultContentLanguageInSubdir = true로 바꿔서 기본 언어도/ko/같은 언어 접두사를 갖도록 정리했다.disableDefaultLanguageRedirect = false를 명시해 루트(/) 접근 시 기본 언어 서브디렉터리로 안내하는 동작을 유지했다.content/ko,content/en,content/jp,content/cn구조는 그대로 두고, URL 접두사만 전역 설정으로 통제하게 했다.
중요한 이유:
content/ko로 분리해 두었더라도, 기본 언어는 설정값이false면 루트(/)로 노출되는 것이 Hugo 기본 동작이다.- 폴더 구조가 잘못된 것이 아니라 URL 정책이 루트 우선으로 되어 있었던 것이다.
- 이후 사이트가 커져도 언어별 URL 규칙이 흔들리지 않는다.
4) 로케일별 퍼머링크는 front matter 의 slug / url 로 조절
파일:
- 각 언어의 콘텐츠 파일들
변경 내용:
- 번역된 페이지는 동일한 translationKey 로 묶고, 필요할 때만
slug나url로 언어별 경로를 분리할 수 있다. - 섹션 페이지는
url중심으로 관리하는 편이 안전하다. - 일반 페이지는
slug로 로케일별 URL 을 개별화할 수 있다.
중요한 이유:
- 언어별 문서 제목이 같아도 URL 은 독립적으로 제어할 수 있다.
- 나중에 콘텐츠가 늘어도 하드코딩 없이 경로 정책을 유지할 수 있다.
5) 번역 문자열의 실제 원본을 theme i18n 으로 통합
파일:
themes/(0000-0000-0000-0001)/i18n/en.yamlthemes/(0000-0000-0000-0001)/i18n/ko.yamlthemes/(0000-0000-0000-0001)/i18n/jp.yamlthemes/(0000-0000-0000-0001)/i18n/cn.yaml
변경 내용:
- 프로젝트 루트
i18n/은 비워 둔 상태로 정리했다. - 텍스트와 메뉴 라벨은 테마 i18n 이 1순위가 되도록 맞췄다.
home,blog,categories,tags,about,contact같은 기본 내비게이션 문자열은 언어별로 교체 가능하게 유지한다.
중요한 이유:
- 페이지 본문과 UI 문구의 책임이 분리된다.
- 번역은 콘텐츠, 공통 라벨은 테마로 모여서 유지보수가 쉬워진다.
이번 패스에서 확인한 트리 구조
content/
└─ ko/
├─ _index.md
├─ about/_index.md
├─ blog/
│ ├─ _index.md
│ └─ theme-upgrade-lab/
│ ├─ _index.md
│ ├─ 00-full-coverage.md
│ ├─ 01-foundation/
│ │ ├─ _index.md
│ │ ├─ design-tokens.md
│ │ ├─ color-surface.md
│ │ ├─ layout-spacing.md
│ │ └─ typography-language.md
│ ├─ 02-components/
│ │ ├─ _index.md
│ │ ├─ controls-cards.md
│ │ ├─ cta-shortcode.md
│ │ └─ media-figure.md
│ ├─ 03-rendering/
│ │ ├─ _index.md
│ │ ├─ markdown-rendering.md
│ │ ├─ shortcode-composition.md
│ │ └─ edge-cases.md
│ ├─ 04-architecture/
│ │ ├─ _index.md
│ │ ├─ taxonomy-navigation.md
│ │ └─ bundles-resources/
│ │ ├─ index.md
│ │ ├─ cover.svg
│ │ └─ diagram.svg
│ ├─ 05-operations/
│ │ ├─ _index.md
│ │ ├─ update-log.md
│ │ ├─ upgrade-summary.md
│ │ └─ verification-log.md
│ └─ 06-public-posts/
│ ├─ _index.md
│ ├─ 01-productivity-routine.md
│ ├─ 02-budget-guide.md
│ ├─ 03-weekend-cleanup.md
│ └─ 04-travel-checklist.md
├─ categories/_index.md
├─ contact/_index.md
└─ tags/_index.md
주의사항
- 디자인은 페이지 내부에서 고정 수치를 늘리지 말고,
design-tokens.css계층을 먼저 바꿔야 한다. config/_default/params.toml은 중앙 정책의 원본이지, 개별 페이지 전용 색상표가 아니다.- 언어별 콘텐츠는 같은 트리 구조를 유지해야 번역/비교/검증이 쉬워진다.
배포 전 마지막 확인
- 홈, 소개, 연락, 블로그 목록이 모두 열리는가
- 토큰 페이지의 색상/간격/폰트/반경이 실제 화면에서 보이는가
- CTA, figure, collapse, raw HTML, ltr/rtl 이 모두 정상 동작하는가
- page bundle 리소스가 상대 경로로 깨지지 않는가
추가 반영: 공지/안내/배너 중앙 제어 체계
이번 패스에서는 중요 공지, 안내 배너, 모달형 공지를 한 번에 제어할 수 있도록 구조를 추가했다.
핵심 원칙
- 문구와 노출 정책은
config/_default/params.toml에서만 수정한다. - 렌더링은
themes/(0000-0000-0000-0001)/layouts/partials/theme/announcement.html이 담당한다. - 디자인과 간격, 색상, 레이어는
theme-vars계층만 수정해서 바뀌도록 만들었다. - 언어별 문구는
themes/(0000-0000-0000-0001)/i18n/*.yaml의 공통 키를 사용한다. - 특정 섹션, taxonomy, term, page kind, layout, path, front matter params 를 조건으로 걸 수 있다.
- 닫기 상태는 localStorage 기반으로 저장되어, 사용자가 이미 닫은 공지는 다시 노출하지 않을 수 있다.
추가된 파일 트리
themes/(0000-0000-0000-0001)/
├─ assets/css/
│ ├─ common/
│ │ └─ announcement.css
│ └─ core/theme-vars/
│ └─ 80-announcement.css
└─ layouts/partials/theme/
├─ announcement.html
└─ settings.html
config/_default/params.toml 에서 통제되는 항목
enabled: 공지 체계 전체 on/offstrategy: 여러 공지가 동시에 맞을 때stack또는firstdefaultMode:banner,sticky,modal,inlinedefaultVariant:info,success,warning,danger,neutralplacement:after-header,before-main,inline,floatingitems: 공지 항목 목록- 각 항목의
scope: 언어 / kinds / sections / taxonomies / terms / paths / pathPrefixes / params
운영 시 주의사항
- 전체 공지를 끄고 싶으면
enabled = false만 바꾸면 된다. - 개별 공지는 항목별
enabled = false로 제어한다. - section 이나 taxonomy 기반으로 타게팅할 때는
scope만 바꿔도 된다. - modal 모드는 접근성상 문구를 짧고 명확하게 유지하는 편이 좋다.
- CTA 링크가 외부로 나갈 경우
target과rel을 함께 검토하는 편이 안전하다.
이번 패스에서의 설계 의미
- 공지 기능이 헤더/푸터/특정 페이지에 흩어지지 않고 한 곳에 모였다.
- 디자인 수정은 theme-vars 만 바꾸면 되고, 로직 수정은 partial 만 바꾸면 된다.
- 언어가 추가되어도
items.<id>.content+ 언어별 오버라이드 패턴을 그대로 확장할 수 있다. - 하드코딩이 아닌 중앙 정책 방식으로, 이후 유지보수와 배포가 쉬워졌다.
公告结构补充说明
这次升级不再把公告当成一个 items.<id>.content 的单块对象来管理。
现在把基础文件和语言覆盖文件拆开,结构和文案可以分别维护。
当前目录树
themes/
└── (0000-0000-0000-0001)/
└── data/
└── _index.toml
└── announcement/
├── ko.toml
├── en.toml
├── jp.toml
└── cn.toml
关闭方式
session:当前会话内不再显示persistent:写入 localStorage,直到清除才恢复hours:在指定小时数内不再显示
需要检查的页面
展示页使用 front matter 的
announcementProfile = "showcase"。 这样就能在不硬编码具体路径的前提下复用模态框和内嵌卡片示例。
追加阶段:全局启用与 scope 规范化
这次修改的目标是让公告系统更容易检查,因此先把 所有横幅都改为全局启用,并统一每个 item 的结构。
变更内容
- 在
themes/(0000-0000-0000-0001)/data/40-communication/announcement/_index.toml中加入scopeDefaults,让每个 item 采用相同结构。 languages / kinds / sections / pathPrefixes / taxonomies / terms统一把["*"]当作通配符。storageKey改为可选,留空时自动回退为生成键。priority作为排序提示使用,数值越大越先显示。dismissMode表示 close 按钮的保存策略,默认值为session。snoozeHours只用于按时间隐藏的动作。
关闭按钮检查结果
- 点击事件改为在 capture 阶段监听,减少被上层事件拦截的机会。
- close 的保存策略拆成 session / persistent / hours 三种。
- 即使存储失败,界面上的隐藏动作仍然会继续执行。
布局检查结果
- CTA 和关闭按钮在桌面端保持内容宽度,在移动端才扩展为 100%。
- footer 与 dismiss 区域的宽度、对齐和间距都交给 theme-vars token 管理。
- 按钮位置不再靠页面硬编码,而是由
theme-vars/80-announcement.css统一控制。
需要确认的文件树
config/_default/params/_index.toml
themes/(0000-0000-0000-0001)/
├─ data/
│ ├─ _index.toml
│ └─ announcement/
│ ├─ ko.toml
│ ├─ en.toml
│ ├─ jp.toml
│ └─ cn.toml
├─ layouts/partials/theme/
│ ├─ announcement-config.html
│ └─ announcement.html
├─ assets/css/common/
│ └─ announcement.css
├─ assets/css/core/theme-vars/
│ └─ 80-announcement.css
└─ assets/js/04-composition-layer/cross-cutting-composition/
└─ announcement.js
运行备注
- 要让所有 banner 全局显示,请保留
enabled = true,并让每个 item 的 scope 保持宽松。 - 只有在确实需要限定到特定 section / page 时,才缩小 scope。
storageKey只有在需要长期保持隐藏状态时才建议显式指定。