mirror of
https://github.com/tiennm99/tsuki.git
synced 2026-09-03 00:18:28 +00:00
feat: docs, changelog, expanded examples for v0.1.0 (Phase 8)
- docs/config.md: full params reference (required + optional + per-post frontmatter); explains why theme defaults don't deep-merge into consumer sites - docs/data-schemas.md: profile.yaml + projects.yaml field tables - docs/customization.md: layout overrides, design token override via custom CSS, font self-hosting, per-page color overrides, kill switches - docs/migrating-from-stack.md: submodule swap, drop list, Stack-to-tsuki param mapping, frontmatter compat, gotchas (heading id changes break inbound anchor links) - CHANGELOG.md: complete 0.1.0 entry covering all phases - README.md: drop "under construction"; add full params snippet, search + comments + browser support sections, links to all docs - exampleSite/data/projects.yaml: +tsuki, +penny-pincher (6 total) Screenshots, miti99 migration, and v0.1.0 tag are user-driven actions recorded in phase-08 plan.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to tsuki will be documented here. Format follows [Keep a Changelog](https://keepachangelog.com/), versioning follows [SemVer](https://semver.org/).
|
||||
|
||||
## [0.1.0] — 2026-05-07
|
||||
|
||||
Initial public release.
|
||||
|
||||
### Added
|
||||
|
||||
- **Layouts** — `baseof`, `home` (hero + projects + recent), `single`, `list`, `archives`, `taxonomy/term`, `_default/taxonomy`, `post/list`, `search/list`, `404`
|
||||
- **Partials** — `head`, `header`, `footer`, `nav`, `meta`, `post-card`, `pagination`, `archive-group`, `toc`, `comments`, `search-button`, `icon`, `home/{hero,projects,recent-posts}`
|
||||
- **Render hooks** — `_markup/render-heading.html` for cosmetic anchor links
|
||||
- **Asset pipeline** — `resources.Concat | minify | fingerprint`. No SCSS, no PostCSS, no Node bundler. CSS bundle ≤ 4 KB gz, JS ≤ 1 KB gz
|
||||
- **Vietnamese-first** — `time.Format ":date_long"` localized dates, `autoHeadingIDType: github-ascii` for clean URL fragments, line-height tuned for diacritic clearance
|
||||
- **Dark mode** — CSS custom properties, `prefers-color-scheme` default, persistent toggle via `data-theme` + `localStorage`, no flash on first paint
|
||||
- **View Transitions API** — `@view-transition: navigation auto` on supported browsers, motion-safe `@keyframes`, falls back to instant nav
|
||||
- **Table of contents** — sticky on wide viewports, framed block on narrow, IntersectionObserver-driven active heading; gated by `WordCount > 400` and `Params.toc != false`
|
||||
- **Search** — Pagefind, indexed at build time in CI, UI mounted at `/search/` with full Vi i18n
|
||||
- **Comments** — Giscus, opt-in via `params.comments.giscus.enable`, theme-sync via `MutationObserver` on `data-theme`
|
||||
- **i18n** — `i18n/vi.yml` with all UI strings (search, pagination, archive, comments, theme toggle)
|
||||
- **CI** — `.github/workflows/pages.yml` runs Hugo + Pagefind + uploads to GitHub Pages; `npm ci` resolves Pagefind from `package.json` lockfile (Dependabot-friendly)
|
||||
- **ExampleSite** — 5 vi-language demo posts, 4 featured projects, profile data, archive, search, all routes verified
|
||||
|
||||
### Configuration notes
|
||||
|
||||
- Hugo 0.146+ required (uses `_partials`, `_markup`, `_shortcodes` convention).
|
||||
- Theme defaults are documentation only — Hugo does not deep-merge nested config (`pagination`, `permalinks`, `taxonomies`, `markup`) from themes. Consumer sites must set these in their own `hugo.yaml`. See [`docs/config.md`](docs/config.md).
|
||||
- Permalink token `:contentbasename` recommended for clean ASCII URLs from leaf bundles.
|
||||
|
||||
### Deferred to post-0.1.0
|
||||
|
||||
- Self-hosted Be Vietnam Pro / Inter woff2 files (system fonts work fine; user adds woff2 via `static/fonts/` if desired)
|
||||
- KaTeX math support
|
||||
- Tag cloud widget
|
||||
- Image gallery shortcode
|
||||
|
||||
[0.1.0]: https://github.com/tiennm99/tsuki/releases/tag/v0.1.0
|
||||
@@ -8,23 +8,24 @@ A Hugo blog + personal portfolio theme. The homepage *is* the portfolio — bio,
|
||||
|
||||
> 月 (*tsuki*): the moon. Quiet, observed, returned to. Companion to [`bonsai`](https://github.com/tiennm99/bonsai) in the same naming family.
|
||||
|
||||
**→ [Live demo](https://tiennm99.github.io/tsuki/)** (after first deploy)
|
||||
**→ [Live demo](https://tiennm99.github.io/tsuki/)**
|
||||
|
||||
## Status
|
||||
|
||||
🚧 **Under construction** — initial scaffold. See [the implementation plan](https://github.com/tiennm99/miti99/tree/main/plans) for what's coming.
|
||||
`v0.1.0` — initial release. See [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
## Features
|
||||
|
||||
- **Blog** — posts, tags, categories, year-grouped archive
|
||||
- **Blog** — posts, tags, categories, year-grouped archive, paginated post list
|
||||
- **Personal portfolio on the homepage** — driven by `data/profile.yaml` + `data/projects.yaml`, no separate `/portfolio` section
|
||||
- **Search** — [Pagefind](https://pagefind.app), zero-runtime, indexed at build time
|
||||
- **Comments** — [Giscus](https://giscus.app) (GitHub Discussions)
|
||||
- **Vietnamese-first** — diacritic-safe typography, native vi date formats, Be Vietnam Pro fallback
|
||||
- **Vietnamese-first** — diacritic-safe typography, native vi date formats, ASCII heading IDs
|
||||
- **Dark mode** — `prefers-color-scheme` + persistent toggle, no flash of wrong theme
|
||||
- **View Transitions API** — smooth same-document navigation in supporting browsers
|
||||
- **No build step** — pure Hugo + browser ES modules. No SCSS, no TypeScript, no bundler in the theme.
|
||||
- **Light** — target ≤ 15 KB CSS gzipped, ≤ 8 KB JS gzipped (excluding Pagefind UI)
|
||||
- **Table of contents** — auto-mounted on long posts, sticky on wide viewports, IntersectionObserver active highlight
|
||||
- **No build step** — pure Hugo + browser ES modules. No SCSS, no TypeScript, no bundler in the theme
|
||||
- **Light** — CSS ≤ 4 KB gz, JS ≤ 1 KB gz (excluding Pagefind UI)
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -57,7 +58,55 @@ module:
|
||||
|
||||
## Configuration
|
||||
|
||||
Documented in [`docs/config.md`](docs/config.md) (coming soon). For now, see `exampleSite/hugo.yaml` and `exampleSite/data/`.
|
||||
Add the required keys to your site's `hugo.yaml`:
|
||||
|
||||
```yaml
|
||||
theme: tsuki
|
||||
languageCode: vi
|
||||
defaultContentLanguage: vi
|
||||
|
||||
pagination:
|
||||
pagerSize: 10
|
||||
path: page
|
||||
|
||||
taxonomies:
|
||||
category: categories
|
||||
tag: tags
|
||||
|
||||
permalinks:
|
||||
post: /:year/:month/:day/:contentbasename/
|
||||
|
||||
markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
parser:
|
||||
autoHeadingIDType: github-ascii
|
||||
tableOfContents:
|
||||
startLevel: 2
|
||||
endLevel: 4
|
||||
```
|
||||
|
||||
Then drop `data/profile.yaml` and `data/projects.yaml` into your site (see [`docs/data-schemas.md`](docs/data-schemas.md)).
|
||||
|
||||
Hugo doesn't deep-merge nested config from themes — settings above belong in your *site* `hugo.yaml`. The `exampleSite/hugo.yaml` is a complete working example.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [`docs/config.md`](docs/config.md) — full params reference
|
||||
- [`docs/data-schemas.md`](docs/data-schemas.md) — `profile.yaml` + `projects.yaml`
|
||||
- [`docs/customization.md`](docs/customization.md) — override layouts, tokens, fonts
|
||||
- [`docs/migrating-from-stack.md`](docs/migrating-from-stack.md) — for users coming from `hugo-theme-stack`
|
||||
|
||||
## Search and comments
|
||||
|
||||
Search uses Pagefind, built in CI via `npx pagefind --site public` after Hugo. Pinned in `package.json`; bumps via Dependabot. No runtime dependency.
|
||||
|
||||
Comments use Giscus. Generate config at [giscus.app](https://giscus.app) and add to `params.comments.giscus.*` to enable. Defaults to off.
|
||||
|
||||
## Browser support
|
||||
|
||||
Modern evergreen browsers. View Transitions and `:has()` are progressive enhancements; the theme remains functional without them.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
# Configuration
|
||||
|
||||
Reference for `hugo.yaml` keys that tsuki reads. **All settings below are set in your *site's* `hugo.yaml`, not in the theme.** The theme ships defaults for documentation only — Hugo does not deep-merge nested config from themes.
|
||||
|
||||
## Required
|
||||
|
||||
```yaml
|
||||
languageCode: vi
|
||||
defaultContentLanguage: vi
|
||||
theme: tsuki
|
||||
|
||||
pagination:
|
||||
pagerSize: 10
|
||||
path: page
|
||||
|
||||
taxonomies:
|
||||
category: categories
|
||||
tag: tags
|
||||
|
||||
permalinks:
|
||||
post: /:year/:month/:day/:contentbasename/
|
||||
|
||||
markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
parser:
|
||||
autoHeadingIDType: github-ascii # ASCII slugs for vi diacritics
|
||||
tableOfContents:
|
||||
startLevel: 2
|
||||
endLevel: 4
|
||||
```
|
||||
|
||||
## Theme params
|
||||
|
||||
```yaml
|
||||
params:
|
||||
description: "Site description used in <meta>, falls back to site.Title."
|
||||
|
||||
search:
|
||||
enable: true # mounts /search/ + header search button
|
||||
|
||||
home:
|
||||
recentPostsCount: 5 # how many post-cards on the homepage
|
||||
|
||||
toc:
|
||||
enable: true # gate at template level (currently informational)
|
||||
minWordCount: 400 # post must exceed this to render TOC
|
||||
|
||||
comments:
|
||||
giscus:
|
||||
enable: false # opt-in
|
||||
repo: "<owner>/<repo>"
|
||||
repoId: "R_kgDO..."
|
||||
category: "Announcements"
|
||||
categoryId: "DIC_kwDO..."
|
||||
mapping: "pathname" # pathname | url | title | og:title
|
||||
strict: "0"
|
||||
reactionsEnabled: "1"
|
||||
inputPosition: "bottom" # top | bottom
|
||||
theme: "preferred_color_scheme"
|
||||
lang: "vi"
|
||||
```
|
||||
|
||||
Generate Giscus values at [giscus.app](https://giscus.app). Only `enable: true` activates the partial; missing IDs are ignored.
|
||||
|
||||
## Profile and projects
|
||||
|
||||
The homepage portfolio reads from data files, **not** `params`:
|
||||
|
||||
- `data/profile.yaml` — bio, avatar, links. See [data-schemas.md](data-schemas.md).
|
||||
- `data/projects.yaml` — featured projects grid. See [data-schemas.md](data-schemas.md).
|
||||
|
||||
## Per-post frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Tiêu đề bài viết"
|
||||
date: 2026-05-07T19:00:00+07:00
|
||||
draft: false
|
||||
description: "Tóm tắt 1-2 câu (dùng cho meta + post-card)."
|
||||
tags: ["hugo", "viet"]
|
||||
categories: ["ghi-chu"]
|
||||
toc: false # opt out of TOC for this post (default: render if WordCount > 400)
|
||||
comments: false # opt out of comments for this post (default: enabled if giscus.enable)
|
||||
image: "img/cover.jpg" # OG image override
|
||||
---
|
||||
```
|
||||
|
||||
## Optional
|
||||
|
||||
```yaml
|
||||
menus:
|
||||
main:
|
||||
- name: "Bài viết"
|
||||
url: /post/
|
||||
weight: 10
|
||||
- name: "Lưu trữ"
|
||||
url: /archives/
|
||||
weight: 20
|
||||
- name: "Thẻ"
|
||||
url: /tags/
|
||||
weight: 30
|
||||
```
|
||||
|
||||
## Why theme defaults don't merge
|
||||
|
||||
Hugo's config-merging strategy for nested keys (markup, permalinks, pagination) is "none" by default. The theme ships a complete `hugo.yaml` for reference, but consumer sites must duplicate the keys above. See `exampleSite/hugo.yaml` for a working example.
|
||||
@@ -0,0 +1,122 @@
|
||||
# Customization
|
||||
|
||||
Hugo's lookup order means **anything in your site overrides the theme**. No fork required.
|
||||
|
||||
## Override layouts and partials
|
||||
|
||||
Drop a file with the same path under your site's `layouts/` to replace the theme version.
|
||||
|
||||
```
|
||||
your-site/
|
||||
└── layouts/
|
||||
├── _partials/
|
||||
│ └── footer.html # overrides themes/tsuki/layouts/_partials/footer.html
|
||||
└── single.html # overrides themes/tsuki/layouts/single.html
|
||||
```
|
||||
|
||||
To extend rather than replace, copy the theme partial into your site, then modify. Common overrides:
|
||||
|
||||
- `_partials/footer.html` — add license, build info, web ring links
|
||||
- `_partials/home/hero.html` — restructure the homepage hero
|
||||
- `_partials/comments.html` — swap Giscus for a different provider
|
||||
|
||||
## Override design tokens
|
||||
|
||||
Tokens are CSS custom properties on `:root` and `:where([data-theme="dark"])`. Override them in a custom stylesheet without editing the theme.
|
||||
|
||||
```css
|
||||
/* your-site/assets/css/custom.css */
|
||||
:root {
|
||||
--tsuki-accent: #cc7a3b; /* warmer accent */
|
||||
--tsuki-font-sans: "Public Sans", system-ui, sans-serif;
|
||||
--tsuki-content-width: 48rem; /* wider posts */
|
||||
}
|
||||
:where([data-theme="dark"]) {
|
||||
--tsuki-accent: #f0a070;
|
||||
}
|
||||
```
|
||||
|
||||
Append it to the bundle by overriding `_partials/head.html`. Copy the theme version, add your file:
|
||||
|
||||
```go-html-template
|
||||
{{- $cssFiles := slice
|
||||
(resources.Get "css/tokens.css")
|
||||
(resources.Get "css/reset.css")
|
||||
...
|
||||
(resources.Get "css/view-transitions.css")
|
||||
(resources.Get "css/custom.css") {{/* your override, last in cascade */}}
|
||||
-}}
|
||||
```
|
||||
|
||||
## Add custom icons
|
||||
|
||||
Drop SVGs into `assets/icons/<name>.svg`, then reference by name:
|
||||
|
||||
```yaml
|
||||
# data/profile.yaml
|
||||
links:
|
||||
- icon: bluesky
|
||||
label: Bluesky
|
||||
url: https://bsky.app/profile/...
|
||||
```
|
||||
|
||||
Use `currentColor` for fill/stroke so icons inherit text color in light and dark modes:
|
||||
|
||||
```svg
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="..."/>
|
||||
</svg>
|
||||
```
|
||||
|
||||
## Self-host fonts
|
||||
|
||||
The theme stack is `"Inter", "Be Vietnam Pro", system-ui, ...`. The first two fall back to system fonts when missing. To self-host:
|
||||
|
||||
1. Subset Be Vietnam Pro + Inter to `vietnamese,latin` ranges.
|
||||
2. Drop the woff2 files into `static/fonts/`.
|
||||
3. Add `@font-face` declarations in `assets/css/custom.css` (see "Override design tokens" above).
|
||||
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url("/fonts/Inter-VariableFont_slnt,wght.woff2") format("woff2-variations");
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Be Vietnam Pro";
|
||||
src: url("/fonts/BeVietnamPro-Regular.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
}
|
||||
```
|
||||
|
||||
## Override colors per-page
|
||||
|
||||
Set CSS variables inline via a frontmatter `style` you wire up yourself, or use the `body_class` block from `baseof.html`:
|
||||
|
||||
```html
|
||||
<!-- layouts/section/work.html -->
|
||||
{{ define "body_class" }}list section-work{{ end }}
|
||||
```
|
||||
|
||||
Then style `body.section-work { --tsuki-accent: #...; }` in your custom CSS.
|
||||
|
||||
## Disable features
|
||||
|
||||
Every interactive feature has a kill switch:
|
||||
|
||||
```yaml
|
||||
params:
|
||||
search:
|
||||
enable: false # removes search button + /search/ route
|
||||
comments:
|
||||
giscus:
|
||||
enable: false # comments partial becomes a no-op
|
||||
```
|
||||
|
||||
Per-post:
|
||||
```yaml
|
||||
toc: false
|
||||
comments: false
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
# Data schemas
|
||||
|
||||
The homepage portfolio is data-driven. Two YAML files in `data/`.
|
||||
|
||||
## `data/profile.yaml`
|
||||
|
||||
Powers the homepage hero and the OG image fallback.
|
||||
|
||||
```yaml
|
||||
name: "Tien Nguyen" # required: display name
|
||||
handle: "tiennm99" # optional: short handle (currently unused; reserved)
|
||||
tagline: "Building tools, breaking things, writing it down." # optional: under name
|
||||
avatar: "img/avatar.svg" # optional: site-relative path under static/
|
||||
bio: | # optional: markdown, rendered with markdownify
|
||||
Software engineer based in Ho Chi Minh City. I build for the web,
|
||||
experiment with AI tooling, and write down what I learn.
|
||||
links: # optional: array of {icon, label, url}
|
||||
- icon: github # icon name resolves to assets/icons/<name>.svg
|
||||
label: GitHub
|
||||
url: https://github.com/tiennm99
|
||||
- icon: mail
|
||||
label: Email
|
||||
url: mailto:hi@example.com
|
||||
- icon: rss
|
||||
label: RSS
|
||||
url: /index.xml
|
||||
```
|
||||
|
||||
Field reference:
|
||||
|
||||
| field | type | required | notes |
|
||||
|---------|--------|----------|-------------------------------------------|
|
||||
| name | string | yes | falls back to `site.Title` if absent |
|
||||
| handle | string | no | reserved |
|
||||
| tagline | string | no | rendered as `<p>` under name |
|
||||
| avatar | string | no | resolved with `relURL`; show `<img>` if set |
|
||||
| bio | string | no | markdown; `markdownify` filter applied |
|
||||
| links | array | no | empty list = no links section |
|
||||
|
||||
Built-in icons under `assets/icons/`: `github`, `mail`, `rss`, `search`. Add your own SVGs there with `currentColor` fill.
|
||||
|
||||
## `data/projects.yaml`
|
||||
|
||||
Powers the featured projects grid on the homepage.
|
||||
|
||||
```yaml
|
||||
featured:
|
||||
- title: "bonsai"
|
||||
tagline: "Minimalist Hugo theme for link-in-bio."
|
||||
repo: https://github.com/tiennm99/bonsai
|
||||
demo: https://tiennm99.github.io/bonsai/
|
||||
image: "img/projects/bonsai.svg"
|
||||
tags: [hugo, theme, minimal]
|
||||
|
||||
- title: "vngeoguessr"
|
||||
tagline: "GeoGuessr clone for Vietnamese locations."
|
||||
repo: https://github.com/tiennm99/vngeoguessr
|
||||
image: "img/projects/vngeoguessr.svg"
|
||||
tags: [geo, mapillary, redis]
|
||||
```
|
||||
|
||||
Field reference (per project):
|
||||
|
||||
| field | type | required | notes |
|
||||
|---------|----------|----------|--------------------------------------------------|
|
||||
| title | string | yes | card heading |
|
||||
| tagline | string | no | one-line description under title |
|
||||
| image | string | no | site-relative; rendered 16:9 with `object-fit: cover` |
|
||||
| repo | URL | no | "repo →" link if present |
|
||||
| demo | URL | no | "demo →" link if present |
|
||||
| tags | string[] | no | small chips below tagline |
|
||||
|
||||
The grid uses `auto-fit, minmax(16rem, 1fr)`; cards reflow on narrow viewports automatically.
|
||||
@@ -0,0 +1,111 @@
|
||||
# Migrating from hugo-theme-stack
|
||||
|
||||
tsuki extracts Stack's information architecture (posts, tags, categories, archive, search, comments) and rewrites the visual layer + asset pipeline. Most posts will render unchanged. This guide covers what to delete, what to add, and where Stack-isms hide.
|
||||
|
||||
## What carries over
|
||||
|
||||
- Post frontmatter: `title`, `date`, `description`, `tags`, `categories`, `image`, `draft`
|
||||
- Content path convention `content/post/YYYY/MM/DD/slug/index.md`
|
||||
- Permalink shape `/:year/:month/:day/:slug/` (set `:contentbasename` on tsuki for clean ASCII)
|
||||
- Tags and categories taxonomies
|
||||
- Archive page (`content/archives/_index.md`)
|
||||
- Giscus comment provider
|
||||
|
||||
## What changes
|
||||
|
||||
### Replace theme submodule
|
||||
|
||||
```bash
|
||||
git submodule deinit themes/hugo-theme-stack
|
||||
git rm themes/hugo-theme-stack
|
||||
git submodule add https://github.com/tiennm99/tsuki themes/tsuki
|
||||
```
|
||||
|
||||
### Update `theme:`
|
||||
|
||||
```yaml
|
||||
theme: tsuki # was: hugo-theme-stack
|
||||
```
|
||||
|
||||
### Drop these (Stack-only)
|
||||
|
||||
- `params.sidebar.*` — tsuki has no sidebar
|
||||
- `params.widgets.*` — no widget system; portfolio is in homepage hero/projects
|
||||
- `params.article.headingAnchor` — anchors render-hooked into headings unconditionally (cosmetic, opt-out is via removing the partial)
|
||||
- `params.colorScheme.toggleIcon` — fixed icon
|
||||
- `params.imageProcessing.*` — tsuki uses Hugo's default image processing
|
||||
- `params.comments.provider` — only Giscus is supported; no Disqus / Utterances / Waline
|
||||
- TypeScript build pipeline (`assets/ts/`, `tsconfig.json`) — tsuki ships ES modules directly
|
||||
- SCSS pipeline (`assets/scss/`) — tsuki uses plain CSS with custom properties
|
||||
|
||||
### Param mapping
|
||||
|
||||
| Stack | tsuki | Notes |
|
||||
|---|---|---|
|
||||
| `params.description` | `params.description` | unchanged |
|
||||
| `params.sidebar.avatar.src` | `data/profile.yaml: avatar` | now data-driven |
|
||||
| `params.sidebar.subtitle` | `data/profile.yaml: tagline` | |
|
||||
| `params.sidebar.emoji` | — | dropped |
|
||||
| `params.menu.social[].icon` | `data/profile.yaml: links[].icon` | same icon names |
|
||||
| `params.article.toc` | `params.toc.enable` + per-post `toc:` | |
|
||||
| `params.search.fuse` | — | replaced by Pagefind (different config; see [config.md](config.md)) |
|
||||
| `params.colorScheme.default` | system: respects `prefers-color-scheme` | toggle persists in localStorage |
|
||||
| `params.dateFormat.published` | — | uses `time.Format ":date_long"` with site language |
|
||||
| `params.imageProcessing.cover.enabled` | — | dropped; cover image renders as-is |
|
||||
|
||||
### Content frontmatter
|
||||
|
||||
Stack-specific fields ignored without error:
|
||||
|
||||
- `image` — Stack used this for sidebar cover; tsuki uses it for OG image only
|
||||
- `categories[0]` weight quirks — tsuki uses Hugo defaults
|
||||
- `menu`, `weight` — still respected
|
||||
- `slug` — still respected
|
||||
|
||||
No content rewrite required for typical posts.
|
||||
|
||||
## Required additions
|
||||
|
||||
Add these to your `hugo.yaml` (tsuki defaults don't deep-merge from theme):
|
||||
|
||||
```yaml
|
||||
pagination:
|
||||
pagerSize: 10
|
||||
path: page
|
||||
|
||||
permalinks:
|
||||
post: /:year/:month/:day/:contentbasename/
|
||||
|
||||
markup:
|
||||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
parser:
|
||||
autoHeadingIDType: github-ascii
|
||||
tableOfContents:
|
||||
startLevel: 2
|
||||
endLevel: 4
|
||||
```
|
||||
|
||||
If your existing permalink scheme differs, **keep it** — the theme works with any permalink shape.
|
||||
|
||||
## Build and verify
|
||||
|
||||
```bash
|
||||
hugo --gc --minify
|
||||
```
|
||||
|
||||
Spot-check 5–10 posts in the rendered output. Common surprises:
|
||||
|
||||
- **TOC appears unexpectedly**: gated by `WordCount > 400` and `Params.toc != false`. Add `toc: false` to opt out.
|
||||
- **Heading IDs changed**: switching to `autoHeadingIDType: github-ascii` produces different anchor slugs. Old `#lập-trình` becomes `#lap-trinh`. Inbound links from external sites break. Mitigate with redirects, or skip the `autoHeadingIDType` change and accept Vi diacritics in fragment URLs.
|
||||
- **Search results paths**: rebuild Pagefind index (`npx pagefind --site public`); the old Fuse.js JSON index becomes dead weight.
|
||||
|
||||
## Dropped features (consider before migrating)
|
||||
|
||||
- KaTeX math (Phase 9 follow-up; available in Stack)
|
||||
- Tag cloud widget (deferred)
|
||||
- Image gallery shortcode (deferred)
|
||||
- Any Stack-specific shortcode (`gallery`, `keyword`, `bilibili`, etc.)
|
||||
|
||||
If you rely on these heavily, defer the migration or wait for the follow-up release.
|
||||
@@ -23,3 +23,14 @@ featured:
|
||||
repo: https://github.com/tiennm99/vngeoguessr
|
||||
image: "img/projects/vngeoguessr.svg"
|
||||
tags: [geo, mapillary, redis]
|
||||
|
||||
- title: "tsuki"
|
||||
tagline: "Hugo blog + personal portfolio theme. Vietnamese-first, no build step, View Transitions API."
|
||||
repo: https://github.com/tiennm99/tsuki
|
||||
demo: https://tiennm99.github.io/tsuki/
|
||||
tags: [hugo, theme, vi]
|
||||
|
||||
- title: "penny-pincher"
|
||||
tagline: "Personal expense tracker on Cloudflare D1 + Workers. Telegram-bot-first input, web read-only view."
|
||||
repo: https://github.com/tiennm99/penny-pincher-provider
|
||||
tags: [cloudflare, d1, telegram]
|
||||
|
||||
Reference in New Issue
Block a user