이 문서는 다음 유지보수자를 위한 인수인계 기록이다.

이번 패스의 핵심은 문자열, 메뉴, 언어 URL 정책을 모두 중앙화해서, 나중에 언어가 더 늘어나도 같은 규칙으로 확장할 수 있게 만든 것이다.

이번 패스의 핵심 수정

1) 메뉴의 단일 원본을 config/_default/hugo.toml 로 이동

파일:

  • config/_default/hugo.toml

변경 내용:

  • [[menus.main]] 을 한 곳에만 두어 전체 언어가 같은 메뉴 정의를 공유하도록 정리했다.
  • identifier 는 번역 키와 동일하게 유지했다.
  • pageRef 기반으로 현재 언어의 대응 페이지를 자동 연결하도록 정리했다.

중요한 이유:

  • 메뉴 문구를 언어 파일마다 복제하지 않아도 된다.
  • 새 언어를 추가해도 메뉴 구조는 한 번만 수정하면 된다.

2) 언어 메타 파일은 최소 정보만 유지

파일:

  • config/_default/languages/languages.ko.toml
  • config/_default/languages/languages.en.toml
  • config/_default/languages/languages.jp.toml
  • config/_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 로 묶고, 필요할 때만 slugurl 로 언어별 경로를 분리할 수 있다.
  • 섹션 페이지는 url 중심으로 관리하는 편이 안전하다.
  • 일반 페이지는 slug 로 로케일별 URL 을 개별화할 수 있다.

중요한 이유:

  • 언어별 문서 제목이 같아도 URL 은 독립적으로 제어할 수 있다.
  • 나중에 콘텐츠가 늘어도 하드코딩 없이 경로 정책을 유지할 수 있다.

5) 번역 문자열의 실제 원본을 theme i18n 으로 통합

파일:

  • themes/(0000-0000-0000-0001)/i18n/en.yaml
  • themes/(0000-0000-0000-0001)/i18n/ko.yaml
  • themes/(0000-0000-0000-0001)/i18n/jp.yaml
  • themes/(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/off
  • strategy : 여러 공지가 동시에 맞을 때 stack 또는 first
  • defaultMode : banner, sticky, modal, inline
  • defaultVariant : info, success, warning, danger, neutral
  • placement : after-header, before-main, inline, floating
  • items : 공지 항목 목록
  • 각 항목의 scope : 언어 / kinds / sections / taxonomies / terms / paths / pathPrefixes / params

운영 시 주의사항

  • 전체 공지를 끄고 싶으면 enabled = false 만 바꾸면 된다.
  • 개별 공지는 항목별 enabled = false 로 제어한다.
  • section 이나 taxonomy 기반으로 타게팅할 때는 scope 만 바꿔도 된다.
  • modal 모드는 접근성상 문구를 짧고 명확하게 유지하는 편이 좋다.
  • CTA 링크가 외부로 나갈 경우 targetrel 을 함께 검토하는 편이 안전하다.

이번 패스에서의 설계 의미

  • 공지 기능이 헤더/푸터/특정 페이지에 흩어지지 않고 한 곳에 모였다.
  • 디자인 수정은 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 只有在需要长期保持隐藏状态时才建议显式指定。