diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..988e29b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,21 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + labels: + - dependencies + - npm + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + labels: + - dependencies + - github-actions diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..6876e8b --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,63 @@ +name: Build and deploy exampleSite + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + env: + HUGO_VERSION: 0.154.0 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Setup Hugo (extended) + uses: peaceiris/actions-hugo@v3 + with: + hugo-version: ${{ env.HUGO_VERSION }} + extended: true + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build site + working-directory: exampleSite + run: hugo --gc --minify --baseURL "https://tiennm99.github.io/tsuki/" + + - name: Build Pagefind index + run: npx pagefind --site exampleSite/public + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: exampleSite/public + + deploy: + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32e1d11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Hugo build artifacts +/public/ +/resources/ +.hugo_build.lock + +# exampleSite build artifacts +exampleSite/public/ +exampleSite/resources/ +exampleSite/.hugo_build.lock +exampleSite/static/pagefind/ + +# Pagefind generated index +static/pagefind/ + +# Node +node_modules/ +npm-debug.log* + +# OS +.DS_Store +Thumbs.db + +# Editors +.vscode/ +.idea/ +*.swp diff --git a/README.md b/README.md new file mode 100644 index 0000000..87a2e94 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# tsuki (月) + +[![build](https://github.com/tiennm99/tsuki/actions/workflows/pages.yml/badge.svg)](https://github.com/tiennm99/tsuki/actions/workflows/pages.yml) +[![license](https://img.shields.io/github/license/tiennm99/tsuki)](LICENSE) +[![Hugo](https://img.shields.io/badge/hugo-%E2%89%A50.146-ff4088?logo=hugo)](https://gohugo.io) + +A Hugo blog + personal portfolio theme. The homepage *is* the portfolio — bio, featured projects, recent posts. Posts live at `/post/`. Vietnamese-first typography, View Transitions on navigation, Pagefind search, Giscus comments. + +> 月 (*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) + +## Status + +🚧 **Under construction** — initial scaffold. See [the implementation plan](https://github.com/tiennm99/miti99/tree/main/plans) for what's coming. + +## Features + +- **Blog** — posts, tags, categories, year-grouped archive +- **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 +- **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) + +## Quick start + +### As a git submodule + +```bash +git submodule add https://github.com/tiennm99/tsuki.git themes/tsuki +``` + +Add to your site's `hugo.yaml`: + +```yaml +theme: tsuki +``` + +### As a Hugo Module + +```bash +hugo mod init github.com// +hugo mod get github.com/tiennm99/tsuki +``` + +Then add to `hugo.yaml`: + +```yaml +module: + imports: + - path: github.com/tiennm99/tsuki +``` + +## Configuration + +Documented in [`docs/config.md`](docs/config.md) (coming soon). For now, see `exampleSite/hugo.yaml` and `exampleSite/data/`. + +## License + +[Apache-2.0](LICENSE) diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..7f4aced --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,7 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +tags: [] +categories: [] +--- diff --git a/assets/css/.gitkeep b/assets/css/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/assets/icons/.gitkeep b/assets/icons/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/assets/js/.gitkeep b/assets/js/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/exampleSite/content/_index.md b/exampleSite/content/_index.md new file mode 100644 index 0000000..face2ec --- /dev/null +++ b/exampleSite/content/_index.md @@ -0,0 +1,3 @@ +--- +title: tsuki +--- diff --git a/exampleSite/data/.gitkeep b/exampleSite/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/exampleSite/hugo.yaml b/exampleSite/hugo.yaml new file mode 100644 index 0000000..1dbdee2 --- /dev/null +++ b/exampleSite/hugo.yaml @@ -0,0 +1,9 @@ +baseURL: https://tiennm99.github.io/tsuki/ +languageCode: vi +defaultContentLanguage: vi +title: tsuki — example +themesDir: ../.. +theme: tsuki + +params: + description: Example site for the tsuki Hugo theme. diff --git a/exampleSite/static/img/projects/.gitkeep b/exampleSite/static/img/projects/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hugo.yaml b/hugo.yaml new file mode 100644 index 0000000..3750019 --- /dev/null +++ b/hugo.yaml @@ -0,0 +1,33 @@ +languageCode: vi +defaultContentLanguage: vi + +paginate: 10 +paginatePath: page + +taxonomies: + category: categories + tag: tags + +permalinks: + post: /:year/:month/:day/:slug/ + +markup: + goldmark: + renderer: + unsafe: true + highlight: + noClasses: false + lineNos: false + tableOfContents: + startLevel: 2 + endLevel: 4 + +params: + search: + enable: true + comments: + giscus: + enable: false + toc: + enable: true + minWordCount: 400 diff --git a/i18n/vi.yml b/i18n/vi.yml new file mode 100644 index 0000000..4f38c3e --- /dev/null +++ b/i18n/vi.yml @@ -0,0 +1,47 @@ +- id: readingTime + translation: "{{ .Count }} phút đọc" + +- id: postedOn + translation: "Đăng vào" + +- id: updatedOn + translation: "Cập nhật" + +- id: tags + translation: "Thẻ" + +- id: categories + translation: "Chuyên mục" + +- id: archive + translation: "Lưu trữ" + +- id: search + translation: "Tìm kiếm" + +- id: searchPlaceholder + translation: "Tìm bài viết..." + +- id: recentPosts + translation: "Bài viết gần đây" + +- id: featuredProjects + translation: "Dự án nổi bật" + +- id: viewAll + translation: "Xem tất cả" + +- id: tableOfContents + translation: "Mục lục" + +- id: previousPage + translation: "Trang trước" + +- id: nextPage + translation: "Trang tiếp" + +- id: noResults + translation: "Không có kết quả." + +- id: copyright + translation: "© {{ .Year }} {{ .Author }}" diff --git a/images/.gitkeep b/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/_default/.gitkeep b/layouts/_default/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/_markup/.gitkeep b/layouts/_markup/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/_partials/.gitkeep b/layouts/_partials/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/_partials/home/.gitkeep b/layouts/_partials/home/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/_shortcodes/.gitkeep b/layouts/_shortcodes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/archives/.gitkeep b/layouts/archives/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/post/.gitkeep b/layouts/post/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/layouts/search/.gitkeep b/layouts/search/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json new file mode 100644 index 0000000..ba533cc --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "tsuki", + "version": "0.1.0", + "description": "tsuki — Hugo blog + personal portfolio theme", + "license": "Apache-2.0", + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/tiennm99/tsuki.git" + }, + "devDependencies": { + "pagefind": "^1.4.0" + } +} diff --git a/static/.gitkeep b/static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/theme.toml b/theme.toml new file mode 100644 index 0000000..a9bfc37 --- /dev/null +++ b/theme.toml @@ -0,0 +1,18 @@ +name = "tsuki" +license = "Apache-2.0" +licenselink = "https://github.com/tiennm99/tsuki/blob/main/LICENSE" +description = "月 — Hugo blog + personal portfolio theme. Vietnamese-first typography, View Transitions API, Pagefind search, Giscus comments. Companion to bonsai." +homepage = "https://github.com/tiennm99/tsuki" +demosite = "https://tiennm99.github.io/tsuki/" +tags = ["blog", "portfolio", "personal", "minimal", "dark", "vietnamese", "pagefind", "view-transitions"] +features = ["blog", "portfolio", "search", "comments", "dark-mode", "responsive", "i18n", "rss"] +min_version = "0.146.0" + +[author] + name = "Tien Nguyen" + homepage = "https://miti99.com" + +[original] + author = "" + homepage = "" + repo = ""