Merge branch 'saicaca:main' into feat/gitlab-card
This commit is contained in:
@@ -0,0 +1,59 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Create a report to help us improve
|
||||||
|
title: "[Bug]: "
|
||||||
|
labels: ["bug"]
|
||||||
|
assignees:
|
||||||
|
- L4Ph
|
||||||
|
- saicaca
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
- type: textarea
|
||||||
|
id: bug-description
|
||||||
|
attributes:
|
||||||
|
label: Describe the bug
|
||||||
|
description: A clear and concise description of what the bug is.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: to-reproduce
|
||||||
|
attributes:
|
||||||
|
label: To Reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected-behavior
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: A clear and concise description of what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: OS
|
||||||
|
multiple: true
|
||||||
|
options:
|
||||||
|
- Windows
|
||||||
|
- macOS
|
||||||
|
- Linux
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
- type: input
|
||||||
|
id: browser
|
||||||
|
attributes:
|
||||||
|
label: Browser
|
||||||
|
placeholder: e.g. chrome, safari
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context about the problem here.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Suggest an idea for this project
|
||||||
|
title: "[Feature]: "
|
||||||
|
labels: ["enhancement"]
|
||||||
|
assignees:
|
||||||
|
- saicaca
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this feature request!
|
||||||
|
- type: textarea
|
||||||
|
id: related-problem
|
||||||
|
attributes:
|
||||||
|
label: Is your feature request related to a problem?
|
||||||
|
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Describe the solution you'd like
|
||||||
|
description: A clear and concise description of what you want to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Describe alternatives you've considered
|
||||||
|
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
description: Add any other context or screenshots about the feature request here.
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
**Disclaimer**
|
||||||
|
|
||||||
|
Please note that this feature request is at the discretion of the repository owner, @saicaca, and its implementation is not guaranteed.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
name: Custom Issue
|
||||||
|
description: Describe your issue here.
|
||||||
|
title: "[Other]: "
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: issue-description
|
||||||
|
attributes:
|
||||||
|
label: Issue Description
|
||||||
|
description: Please describe your issue.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
## Type of change
|
||||||
|
|
||||||
|
- [ ] Bug fix (a non-breaking change that fixes an issue)
|
||||||
|
- [ ] New feature (a non-breaking change that adds functionality)
|
||||||
|
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
|
- [ ] Other (please describe):
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] I have read the [**CONTRIBUTING**](https://github.com/saicaca/fuwari/blob/main/CONTRIBUTING.md) document.
|
||||||
|
- [ ] I have checked to ensure that this Pull Request is not for personal changes.
|
||||||
|
- [ ] I have performed a self-review of my own code.
|
||||||
|
- [ ] My changes generate no new warnings.
|
||||||
|
|
||||||
|
## Related Issue
|
||||||
|
|
||||||
|
<!-- Please link to the issue that this pull request addresses. e.g. #123 -->
|
||||||
|
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
<!-- Please describe the changes you made in this pull request. -->
|
||||||
|
|
||||||
|
|
||||||
|
## How To Test
|
||||||
|
|
||||||
|
<!-- Please describe how you tested your changes. -->
|
||||||
|
|
||||||
|
|
||||||
|
## Screenshots (if applicable)
|
||||||
|
|
||||||
|
<!-- If you made any UI changes, please include screenshots. -->
|
||||||
|
|
||||||
|
|
||||||
|
## Additional Notes
|
||||||
|
|
||||||
|
<!-- Any additional information that you want to share with the reviewer. -->
|
||||||
@@ -25,3 +25,7 @@ pnpm-debug.log*
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
bun.lockb
|
bun.lockb
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
|
# ide
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ A static blog template built with [Astro](https://astro.build).
|
|||||||
[**日本語**](https://github.com/saicaca/fuwari/blob/main/docs/README.ja.md) /
|
[**日本語**](https://github.com/saicaca/fuwari/blob/main/docs/README.ja.md) /
|
||||||
[**한국어**](https://github.com/saicaca/fuwari/blob/main/docs/README.ko.md) /
|
[**한국어**](https://github.com/saicaca/fuwari/blob/main/docs/README.ko.md) /
|
||||||
[**Español**](https://github.com/saicaca/fuwari/blob/main/docs/README.es.md) /
|
[**Español**](https://github.com/saicaca/fuwari/blob/main/docs/README.es.md) /
|
||||||
[**ไทย**](https://github.com/saicaca/fuwari/blob/main/docs/README.th.md) (Provided by the community and may not always be up-to-date)
|
[**ไทย**](https://github.com/saicaca/fuwari/blob/main/docs/README.th.md) /
|
||||||
|
[**Tiếng Việt**](https://github.com/saicaca/fuwari/blob/main/docs/README.vi.md) /
|
||||||
|
[**Bahasa Indonesia**](https://github.com/saicaca/fuwari/blob/main/docs/README.id.md) (Provided by the community and may not always be up-to-date)
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|
||||||
|
|||||||
+61
-61
@@ -1,63 +1,63 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.2.0/schema.json",
|
||||||
"vcs": {
|
"vcs": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"clientKind": "git",
|
"clientKind": "git",
|
||||||
"useIgnoreFile": false
|
"useIgnoreFile": false
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignoreUnknown": false,
|
"ignoreUnknown": false,
|
||||||
"includes": [
|
"includes": [
|
||||||
"**",
|
"**",
|
||||||
"!**/src/**/*.css",
|
"!**/src/**/*.css",
|
||||||
"!**/src/public/**/*",
|
"!**/src/public/**/*",
|
||||||
"!**/dist/**/*",
|
"!**/dist/**/*",
|
||||||
"!**/node_modules/**/*"
|
"!**/node_modules/**/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"indentStyle": "tab"
|
"indentStyle": "tab"
|
||||||
},
|
},
|
||||||
"assist": { "actions": { "source": { "organizeImports": "on" } } },
|
"assist": { "actions": { "source": { "organizeImports": "on" } } },
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true,
|
"recommended": true,
|
||||||
"style": {
|
"style": {
|
||||||
"noParameterAssign": "error",
|
"noParameterAssign": "error",
|
||||||
"useAsConstAssertion": "error",
|
"useAsConstAssertion": "error",
|
||||||
"useDefaultParameterLast": "error",
|
"useDefaultParameterLast": "error",
|
||||||
"useEnumInitializers": "error",
|
"useEnumInitializers": "error",
|
||||||
"useSelfClosingElements": "error",
|
"useSelfClosingElements": "error",
|
||||||
"useSingleVarDeclarator": "error",
|
"useSingleVarDeclarator": "error",
|
||||||
"noUnusedTemplateLiteral": "error",
|
"noUnusedTemplateLiteral": "error",
|
||||||
"useNumberNamespace": "error",
|
"useNumberNamespace": "error",
|
||||||
"noInferrableTypes": "error",
|
"noInferrableTypes": "error",
|
||||||
"noUselessElse": "error"
|
"noUselessElse": "error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"quoteStyle": "double"
|
"quoteStyle": "double"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"includes": ["**/*.svelte", "**/*.astro", "**/*.vue"],
|
"includes": ["**/*.svelte", "**/*.astro", "**/*.vue"],
|
||||||
"linter": {
|
"linter": {
|
||||||
"rules": {
|
"rules": {
|
||||||
"style": {
|
"style": {
|
||||||
"useConst": "off",
|
"useConst": "off",
|
||||||
"useImportType": "off"
|
"useImportType": "off"
|
||||||
},
|
},
|
||||||
"correctness": {
|
"correctness": {
|
||||||
"noUnusedVariables": "off",
|
"noUnusedVariables": "off",
|
||||||
"noUnusedImports": "off"
|
"noUnusedImports": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
# 🍥 Fuwari
|
||||||
|
|
||||||
|
Template blog statis yang dibangun dengan [Astro](https://astro.build).
|
||||||
|
|
||||||
|
[**🖥️ Demo Langsung (Vercel)**](https://fuwari.vercel.app)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
🌏 README dalam
|
||||||
|
[**中文**](https://github.com/saicaca/fuwari/blob/main/docs/README.zh-CN.md) /
|
||||||
|
[**日本語**](https://github.com/saicaca/fuwari/blob/main/docs/README.ja.md) /
|
||||||
|
[**한국어**](https://github.com/saicaca/fuwari/blob/main/docs/README.ko.md) /
|
||||||
|
[**Español**](https://github.com/saicaca/fuwari/blob/main/docs/README.es.md) /
|
||||||
|
[**ไทย**](https://github.com/saicaca/fuwari/blob/main/docs/README.th.md) /
|
||||||
|
[**Tiếng Việt**](https://github.com/saicaca/fuwari/blob/main/docs/README.vi.md) /
|
||||||
|
**Bahasa Indonesia (ini)** (Disediakan oleh komunitas, mungkin tidak selalu paling mutakhir)
|
||||||
|
|
||||||
|
## ✨ Fitur
|
||||||
|
|
||||||
|
- [x] Dibangun dengan [Astro](https://astro.build) dan [Tailwind CSS](https://tailwindcss.com)
|
||||||
|
- [x] Animasi dan transisi halaman yang halus
|
||||||
|
- [x] Mode terang / gelap
|
||||||
|
- [x] Warna tema & banner yang bisa dikustomisasi
|
||||||
|
- [x] Desain responsif
|
||||||
|
- [x] Fitur pencarian dengan [Pagefind](https://pagefind.app/)
|
||||||
|
- [x] [Fitur markdown tambahan](#-markdown-sintaks-ekstensi)
|
||||||
|
- [x] Daftar isi (Table of Contents)
|
||||||
|
- [x] RSS feed
|
||||||
|
|
||||||
|
## 🚀 Memulai
|
||||||
|
|
||||||
|
1. Buat repositori blog kamu:
|
||||||
|
- [Generate repositori baru](https://github.com/saicaca/fuwari/generate) dari template ini atau fork repositori ini.
|
||||||
|
- Atau jalankan salah satu perintah berikut:
|
||||||
|
```sh
|
||||||
|
# npm
|
||||||
|
npm create fuwari@latest.
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn create fuwari.
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm create fuwari@latest
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun create fuwari@latest
|
||||||
|
|
||||||
|
# deno
|
||||||
|
deno run -A npm:create-fuwari@latest
|
||||||
|
```
|
||||||
|
2. Untuk mengedit blog secara lokal, klon repositori kamu, jalankan `pnpm install` untuk instalasi dependensi.
|
||||||
|
- Install [pnpm](https://pnpm.io) `npm install -g pnpm` jika belum punya.
|
||||||
|
3. Edit file konfigurasi `src/config.ts` untuk menyesuaikan blog.
|
||||||
|
4. Jalankan `pnpm new-post <nama-file>` untuk membuat postingan baru dan edit di `src/content/posts/`.
|
||||||
|
5. Deploy blog ke Vercel, Netlify, GitHub Pages, dll. sesuai [panduan](https://docs.astro.build/en/guides/deploy/). Jangan lupa edit konfigurasi situs di `astro.config.mjs` sebelum deploy.
|
||||||
|
|
||||||
|
## 📝 Frontmatter Postingan
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: Judul Postingan Pertama Saya
|
||||||
|
published: 2023-09-09
|
||||||
|
description: Ini adalah postingan pertama blog Astro saya.
|
||||||
|
image: ./cover.jpg
|
||||||
|
tags: [Foo, Bar]
|
||||||
|
category: Front-end
|
||||||
|
draft: false
|
||||||
|
lang: id # Isi hanya jika bahasa postingan berbeda dari bahasa default di `config.ts`
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧩 Markdown Sintaks Ekstensi
|
||||||
|
|
||||||
|
Selain dukungan default Astro untuk [GitHub Flavored Markdown](https://github.github.com/gfm/), terdapat beberapa fitur tambahan:
|
||||||
|
|
||||||
|
- Admonisi ([Pratinjau & Cara Pakai](https://fuwari.vercel.app/posts/markdown-extended/#admonitions))
|
||||||
|
- Kartu repositori GitHub ([Pratinjau & Cara Pakai](https://fuwari.vercel.app/posts/markdown-extended/#github-repository-cards))
|
||||||
|
- Kode blok ekspresif lewat Expressive Code ([Pratinjau](https://fuwari.vercel.app/posts/expressive-code/) / [Dokumentasi](https://expressive-code.com/))
|
||||||
|
|
||||||
|
## ⚡ Perintah
|
||||||
|
|
||||||
|
Semua perintah dijalankan dari root proyek, via terminal:
|
||||||
|
|
||||||
|
| Perintah | Aksi |
|
||||||
|
|:-----------------------------|:----------------------------------------------------------|
|
||||||
|
| `pnpm install` | Instalasi dependensi |
|
||||||
|
| `pnpm dev` | Menjalankan server dev lokal di `localhost:4321` |
|
||||||
|
| `pnpm build` | Build untuk produksi ke folder `./dist/` |
|
||||||
|
| `pnpm preview` | Pratinjau hasil build sebelum deploy |
|
||||||
|
| `pnpm check` | Cek error atau masalah di kode |
|
||||||
|
| `pnpm format` | Format kode dengan Biome |
|
||||||
|
| `pnpm new-post <nama-file>` | Membuat postingan baru |
|
||||||
|
| `pnpm astro ...` | Jalankan perintah CLI seperti `astro add`, `astro check` |
|
||||||
|
| `pnpm astro --help` | Bantuan menggunakan Astro CLI |
|
||||||
|
|
||||||
|
## ✏️ Kontribusi
|
||||||
|
|
||||||
|
Lihat [Panduan Kontribusi](https://github.com/saicaca/fuwari/blob/main/CONTRIBUTING.md) untuk detail tentang cara berkontribusi ke proyek ini.
|
||||||
|
|
||||||
|
## 📄 Lisensi
|
||||||
|
|
||||||
|
Proyek ini dilisensikan di bawah MIT License.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> Dokumentasi ini tersedia dalam Bahasa Indonesia. Untuk bahasa lain, lihat README di direktori docs.
|
||||||
+41
-45
@@ -13,48 +13,27 @@
|
|||||||
- [x] 라이트 모드 / 다크 모드
|
- [x] 라이트 모드 / 다크 모드
|
||||||
- [x] 사용자 정의 가능한 테마 색상 및 배너
|
- [x] 사용자 정의 가능한 테마 색상 및 배너
|
||||||
- [x] 반응형 디자인
|
- [x] 반응형 디자인
|
||||||
- [ ] 댓글
|
- [x] [Pagefind](https://pagefind.app/)를 이용한 검색 기능
|
||||||
- [x] 검색
|
- [x] [Markdown 확장 기능](https://github.com/saicaca/fuwari?tab=readme-ov-file#-markdown-extended-syntax)
|
||||||
- [x] 목차
|
- [x] 목차
|
||||||
|
- [x] RSS 피드
|
||||||
|
|
||||||
## 요구 사항
|
## 🚀 시작하기
|
||||||
|
1. 블로그 저장소를 생성하세요:
|
||||||
- Node.js <= 22
|
- 이 템플릿에서 [새 저장소를 생성](https://github.com/saicaca/fuwari/generate)하거나 이 저장소를 포크하세요.
|
||||||
- pnpm <= 9
|
- 또는 다음 명령어 중 하나를 실행하세요:
|
||||||
|
```sh
|
||||||
## 🚀 사용하는 방법 1
|
npm create fuwari@latest
|
||||||
|
yarn create fuwari
|
||||||
[create-fuwari](https://github.com/L4Ph/create-fuwari)를 사용하여 로컬에서 프로젝트를 초기화합니다.
|
pnpm create fuwari@latest
|
||||||
|
bun create fuwari@latest
|
||||||
```sh
|
deno run -A npm:create-fuwari@latest
|
||||||
# npm
|
```
|
||||||
npm create fuwari@latest
|
2. 로컬에서 블로그를 수정하려면, 저장소를 복제하고 `pnpm install`을 실행하여 종속성을 설치하세요.
|
||||||
|
- [pnpm](https://pnpm.io)이 설치되어 있지 않다면 `npm install -g pnpm`을 실행하여 설치하세요.
|
||||||
# yarn
|
3. `src/config.ts`설정 파일을 수정하여 블로그를 커스터마이징하세요.
|
||||||
yarn create fuwari
|
4. `pnpm new-post <filename>`을 실행하여 새 게시물을 만들고 `src/content/posts/`에서 수정하세요.
|
||||||
|
5. [가이드](https://docs.astro.build/en/guides/deploy/)에 따라 블로그를 Vercel, Netlify, Github Pages 등에 배포하세요. 배포하기 전에 `astro.config.mjs`에서 사이트 구성을 수정해야 합니다.
|
||||||
# pnpm
|
|
||||||
pnpm create fuwari@latest
|
|
||||||
|
|
||||||
# bun
|
|
||||||
bun create fuwari@latest
|
|
||||||
|
|
||||||
# deno
|
|
||||||
deno run -A npm:create-fuwari@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
1. 블로그를 사용자 정의하려면 `src/config.ts` 구성 파일을 편집하세요.
|
|
||||||
2. `pnpm new-post <filename>`을 실행하여 새 게시물을 만들고 `src/content/posts/`에서 편집하세요.
|
|
||||||
3. [가이드](https://docs.astro.build/en/guides/deploy/)에 따라 블로그를 Vercel, Netlify, GitHub 페이지 등에 배포하세요. 배포하기 전에 `astro.config.mjs`에서 사이트 구성을 편집해야 합니다.
|
|
||||||
|
|
||||||
## 🚀 사용하는 방법
|
|
||||||
|
|
||||||
1. 이 템플릿에서 [새 저장소를 생성](https://github.com/saicaca/fuwari/generate)하거나 이 저장소를 포크하세요.
|
|
||||||
2. 블로그를 로컬에서 편집하려면 저장소를 복제하고 `pnpm install` 및 `pnpm add sharp`를 실행하여 종속성을 설치하세요.
|
|
||||||
- 아직 [pnpm](https://pnpm.io)을 설치하지 않았다면 `npm install -g pnpm`을 실행하여 [pnpm](https://pnpm.io)을 설치하세요.
|
|
||||||
3. 블로그를 사용자 정의하려면 `src/config.ts` 구성 파일을 편집하세요.
|
|
||||||
4. `pnpm new-post <filename>`을 실행하여 새 게시물을 만들고 `src/content/posts/`에서 편집하세요.
|
|
||||||
5. [가이드](https://docs.astro.build/en/guides/deploy/)에 따라 블로그를 Vercel, Netlify, GitHub 페이지 등에 배포하세요. 배포하기 전에 `astro.config.mjs`에서 사이트 구성을 편집해야 합니다.
|
|
||||||
|
|
||||||
## ⚙️ 게시물의 머리말 설정
|
## ⚙️ 게시물의 머리말 설정
|
||||||
|
|
||||||
@@ -63,24 +42,41 @@ deno run -A npm:create-fuwari@latest
|
|||||||
title: 내 첫 블로그 게시물
|
title: 내 첫 블로그 게시물
|
||||||
published: 2023-09-09
|
published: 2023-09-09
|
||||||
description: 내 새로운 Astro 블로그의 첫 번째 게시물입니다!
|
description: 내 새로운 Astro 블로그의 첫 번째 게시물입니다!
|
||||||
image: /images/cover.jpg
|
image: ./cover.jpg
|
||||||
tags: [푸, 바, 오]
|
tags: [Foo, Bar]
|
||||||
category: 앞-끝
|
category: Front-end
|
||||||
draft: false
|
draft: false
|
||||||
lang: jp # 게시물의 언어가 `config.ts`의 사이트 언어와 다른 경우에만 설정합니다.
|
lang: jp # 게시물의 언어가 `config.ts`의 사이트 언어와 다른 경우에만 설정합니다.
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
## 🧩 마크다운 확장 구문
|
||||||
|
Astro의 기본 [GitHub Flavored Markdown](https://github.github.com/gfm/) 지원 외에도 몇 가지 추가적인 마크다운 기능이 포함되어 있습니다.
|
||||||
|
- Admonitions ([미리보기 및 사용법](https://fuwari.vercel.app/posts/markdown-extended/#admonitions))
|
||||||
|
- GitHub 저장소 카드 ([미리보기 및 사용법](https://fuwari.vercel.app/posts/markdown-extended/#github-repository-cards))
|
||||||
|
- Expressive Code를 사용한 향상된 코드 블록 ([미리보기](https://fuwari.vercel.app/posts/expressive-code/) / [문서](https://expressive-code.com/))
|
||||||
|
|
||||||
## 🧞 명령어
|
|
||||||
|
|
||||||
|
## ⚡ 명령어
|
||||||
|
|
||||||
모든 명령어는 프로젝트 최상단, 터미널에서 실행됩니다:
|
모든 명령어는 프로젝트 최상단, 터미널에서 실행됩니다:
|
||||||
|
|
||||||
| Command | Action |
|
| Command | Action |
|
||||||
|:------------------------------------|:-------------------------------------------------|
|
|:------------------------------------|:-------------------------------------------------|
|
||||||
| `pnpm install` AND `pnpm add sharp` | 종속성을 설치합니다. |
|
| `pnpm install` | 종속성을 설치합니다. |
|
||||||
| `pnpm dev` | `localhost:4321`에서 로컬 개발 서버를 시작합니다. |
|
| `pnpm dev` | `localhost:4321`에서 로컬 개발 서버를 시작합니다. |
|
||||||
| `pnpm build` | `./dist/`에 프로덕션 사이트를 구축합니다. |
|
| `pnpm build` | `./dist/`에 프로덕션 사이트를 구축합니다. |
|
||||||
|
| `pnpm check` | 코드에서 오류를 확인합니다. |
|
||||||
|
| `pnpm format` | Biome을 사용하여 코드를 포멧합니다. |
|
||||||
| `pnpm preview` | 배포하기 전에 로컬에서 빌드 미리보기 |
|
| `pnpm preview` | 배포하기 전에 로컬에서 빌드 미리보기 |
|
||||||
| `pnpm new-post <filename>` | 새 게시물 작성 |
|
| `pnpm new-post <filename>` | 새 게시물 작성 |
|
||||||
| `pnpm astro ...` | `astro add`, `astro check`와 같은 CLI 명령어 실행 |
|
| `pnpm astro ...` | `astro add`, `astro check`와 같은 CLI 명령어 실행 |
|
||||||
| `pnpm astro --help` | Astro CLI를 사용하여 도움 받기 |
|
| `pnpm astro --help` | Astro CLI를 사용하여 도움 받기 |
|
||||||
|
|
||||||
|
## ✏️ 기여
|
||||||
|
이 프로젝트에 기여하는 방법에 대한 자세한 내용은 [기여 가이드](https://github.com/saicaca/fuwari/blob/main/CONTRIBUTING.md)를 확인하세요.
|
||||||
|
|
||||||
|
## 📄 라이선스
|
||||||
|
이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.
|
||||||
|
|
||||||
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fsaicaca%2Ffuwari?ref=badge_large&issueType=license)
|
||||||
+51
-54
@@ -10,54 +10,33 @@
|
|||||||
|
|
||||||
- [x] สร้างด้วย [Astro](https://astro.build) และ [Tailwind CSS](https://tailwindcss.com)
|
- [x] สร้างด้วย [Astro](https://astro.build) และ [Tailwind CSS](https://tailwindcss.com)
|
||||||
- [x] มีอนิเมชั่นและการเปลี่ยนหน้าอย่างลื่นไหล
|
- [x] มีอนิเมชั่นและการเปลี่ยนหน้าอย่างลื่นไหล
|
||||||
- [x] รองรับโหมดสว่าง / โหมดมืด
|
- [x] โหมดสว่าง / โหมดมืด
|
||||||
- [x] ปรับแต่งสีธีมและแบนเนอร์ได้
|
- [x] ปรับแต่งสีธีมและแบนเนอร์ได้
|
||||||
- [x] Responsive design (หน้าตาเว็บปรับเปลี่ยนตามขนาดจอ)
|
- [x] Responsive design (หน้าตาเว็บปรับเปลี่ยนตามขนาดจอ)
|
||||||
- [ ] การแสดงความคิดเห็น
|
- [x] ฟังก์ชันการค้นหา ขับเคลื่อนด้วย [Pagefind](https://pagefind.app/)
|
||||||
- [x] การค้นหา
|
- [x] [คุณสมบัติเพิ่มเติมสำหรับมาร์กดาวน์](https://github.com/saicaca/fuwari/blob/main/docs/README.th.md#-markdown-extended-syntax)
|
||||||
- [x] TOC (สารบัญ)
|
- [x] สารบัญ
|
||||||
|
- [x] RSS feed
|
||||||
|
|
||||||
|
## 🚀 เริ่มต้นใช้งาน
|
||||||
|
|
||||||
## จำเป็นต้อง
|
1. สร้าง repository ใหม่สำหรับบล็อกของคุณ:
|
||||||
|
- [Generate repository ใหม่](https://github.com/saicaca/fuwari/generate) ขึ้นมาจากแม่แบบนี้ หรือจะ fork repository นี้ก็ได้
|
||||||
- Node.js <= 22
|
- หรือจะสร้างโดยการเลือกรันคำสั่งต่อไปนี้ คำสั่งใดคำสั่งหนึ่ง:
|
||||||
- pnpm <= 9
|
```sh
|
||||||
|
npm create fuwari@latest
|
||||||
## 🚀 วิธีใช้งาน 1
|
yarn create fuwari
|
||||||
|
pnpm create fuwari@latest
|
||||||
เริ่มต้นโปรเจ็กต์ในเครื่องโดยใช้ [create-fuwari](https://github.com/L4Ph/create-fuwari)
|
bun create fuwari@latest
|
||||||
|
deno run -A npm:create-fuwari@latest
|
||||||
```sh
|
```
|
||||||
# npm
|
2. เริ่มแก้ไขบล็อกของคุณแบบ local โดยการ clone repository ของคุณ (จากข้อ 1) ไว้ในเครื่องของคุณ แล้วรันคำสั่ง `pnpm install` เพื่อติดตั้ง dependencies ที่จำเป็น
|
||||||
npm create fuwari@latest
|
- ติดตั้ง [pnpm](https://pnpm.io) ด้วยคำสั่ง `npm install -g pnpm` ก่อน ถ้ายังไม่เคยติดตั้ง
|
||||||
|
|
||||||
# yarn
|
|
||||||
yarn create fuwari
|
|
||||||
|
|
||||||
# pnpm
|
|
||||||
pnpm create fuwari@latest
|
|
||||||
|
|
||||||
# bun
|
|
||||||
bun create fuwari@latest
|
|
||||||
|
|
||||||
# deno
|
|
||||||
deno run -A npm:create-fuwari@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
1. แก้ไขไฟล์การตั้งค่า `src/config.ts` เพื่อปรับแต่งบล็อกของคุณ
|
|
||||||
2. รันคำสั่ง `pnpm new-post <filename>` เพื่อสร้างโพสต์ใหม่ใน `src/content/posts/` และแก้ไขไฟล์โพสต์นั้นๆ ให้สมบูรณ์
|
|
||||||
3. Deploy เว็บบล็อกของคุณไปยัง Vercel, Netlify, GitHub Pages หรือบริการอื่นๆ โดยอ้างอิงวิธีการจาก[คู่มือนี้](https://docs.astro.build/en/guides/deploy/) อย่าลืมแก้ไขการตั้งค่าเว็บไซต์ในไฟล์ `astro.config.mjs` ก่อนที่คุณจะ deploy เว็บ
|
|
||||||
|
|
||||||
## 🚀 วิธีใช้งาน 2
|
|
||||||
|
|
||||||
1. [Generate repository ใหม่](https://github.com/saicaca/fuwari/generate)ขึ้นมาจากแม่แบบนี้ หรือจะ fork repository นี้ก็ได้
|
|
||||||
2. เริ่มแก้ไขบล็อกของคุณแบบ local โดยการ clone repository ของคุณ (จากข้อ 1) ไว้ในเครื่องของคุณ แล้วรันคำสั่ง `pnpm install` และ `pnpm add sharp` เพื่อติดตั้ง dependencies ที่จำเป็น
|
|
||||||
- ติดตั้ง [pnpm](https://pnpm.io) ด้วยคำสั่ง `npm install -g pnpm` ถ้ายังไม่เคยติดตั้ง
|
|
||||||
3. แก้ไขไฟล์การตั้งค่า `src/config.ts` เพื่อปรับแต่งบล็อกของคุณ
|
3. แก้ไขไฟล์การตั้งค่า `src/config.ts` เพื่อปรับแต่งบล็อกของคุณ
|
||||||
4. รันคำสั่ง `pnpm new-post <filename>` เพื่อสร้างโพสต์ใหม่ใน `src/content/posts/` และแก้ไขไฟล์โพสต์นั้นๆ ให้สมบูรณ์
|
4. รันคำสั่ง `pnpm new-post <filename>` เพื่อสร้างโพสต์ใหม่ใน `src/content/posts/` และแก้ไขไฟล์โพสต์นั้น ๆ ให้สมบูรณ์
|
||||||
5. Deploy เว็บบล็อกของคุณไปยัง Vercel, Netlify, GitHub Pages หรือบริการอื่นๆ โดยอ้างอิงวิธีการจาก[คู่มือนี้](https://docs.astro.build/en/guides/deploy/) อย่าลืมแก้ไขการตั้งค่าเว็บไซต์ในไฟล์ `astro.config.mjs` ก่อนที่คุณจะ deploy เว็บ
|
5. Deploy เว็บบล็อกของคุณไปยัง Vercel, Netlify, GitHub Pages หรือบริการอื่น ๆ โดยอ้างอิงวิธีการจาก[คู่มือนี้](https://docs.astro.build/en/guides/deploy/) อย่าลืมแก้ไขการตั้งค่าเว็บไซต์ในไฟล์ `astro.config.mjs` ก่อนที่คุณจะ deploy เว็บ
|
||||||
|
|
||||||
## ⚙️ Frontmatter ของโพสต์
|
## 📝 Frontmatter (ส่วนหัวไฟล์) ของโพสต์
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -68,20 +47,38 @@ image: ./cover.jpg
|
|||||||
tags: [Foo, Bar]
|
tags: [Foo, Bar]
|
||||||
category: Front-end
|
category: Front-end
|
||||||
draft: false
|
draft: false
|
||||||
lang: jp # เขียนค่านี้เมื่อภาษาของโพสต์นั้นๆ แตกต่างจากภาษาของเว็บไซต์ที่ตั้งค่าไว้ใน `config.ts` เท่านั้น
|
lang: jp # เขียนค่านี้เมื่อภาษาของโพสต์นั้น ๆ แตกต่างจากภาษาของเว็บไซต์ที่ตั้งค่าไว้ใน `config.ts` เท่านั้น
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🧞 คำสั่ง
|
## 🧩 Markdown Extended Syntax
|
||||||
|
|
||||||
คำสั่งที่รันได้ใน terminal จาก root ของโปรเจค:
|
เดิมที Astro มีการสนับสนุน[ภาษามาร์กดาวน์แบบของ GitHub](https://github.github.com/gfm/) ไว้อยู่แล้ว แต่ Fuwari ได้เพิ่มเติมคุณสมบัติพิเศษอื่น ๆ เข้าไปอีก:
|
||||||
|
|
||||||
| คำสั่ง | ผลที่เกิด |
|
- Admonitions หรือ กล่องข้อมูลพิเศษ ([ดูตัวอย่างและการใช้งาน](https://fuwari.vercel.app/posts/markdown-extended/#admonitions))
|
||||||
|:------------------------------------|:--------------------------------------------------|
|
- การ์ด GitHub Repository ([ดูตัวอย่างและการใช้งาน](https://fuwari.vercel.app/posts/markdown-extended/#github-repository-cards))
|
||||||
| `pnpm install` และ `pnpm add sharp` | ติดตั้ง dependencies |
|
- บล็อกโค้ดขั้นสูง ด้วย Expressive Code ([ดูตัวอย่าง](https://fuwari.vercel.app/posts/expressive-code/) / [เอกสารประกอบ](https://expressive-code.com/))
|
||||||
| `pnpm dev` | เปิดเซิร์ฟเวอร์เพื่อพัฒนาเว็บแบบ local ที่ `localhost:4321` |
|
|
||||||
| `pnpm build` | Build เว็บไซต์แบบพร้อมใช้งานจริงไปยังโฟลเดอร์ `./dist/` |
|
## ⚡ คำสั่ง
|
||||||
| `pnpm preview` | ดูตัวอย่าง build ของคุณแบบ local ก่อนที่จะ deploy จริง |
|
|
||||||
| `pnpm new-post <filename>` | สร้างโพสต์ใหม่ |
|
คำสั่งที่รันได้ใน terminal จาก root ของโปรเจกต์:
|
||||||
| `pnpm astro ...` | รันคำสั่ง CLI เช่น `astro add`, `astro check` |
|
|
||||||
| `pnpm astro --help` | ดูข้อมูลเพิ่มเติมเกี่ยวกับ Astro CLI |
|
| คำสั่ง | การทำงาน |
|
||||||
|
|:---------------------------|:-------------------------------------------------------|
|
||||||
|
| `pnpm install` | ติดตั้ง dependencies |
|
||||||
|
| `pnpm dev` | เปิดเซิร์ฟเวอร์สำหรับการพัฒนาแบบ local ที่ `localhost:4321` |
|
||||||
|
| `pnpm build` | Build เว็บไซต์สำหรับใช้งานจริงไปยังโฟลเดอร์ `./dist/` |
|
||||||
|
| `pnpm preview` | ดูตัวอย่าง build ของคุณแบบ local ก่อนที่จะ deploy จริง |
|
||||||
|
| `pnpm check` | ดำเนินการตรวจสอบหาข้อผิดพลาดในโค้ดของคุณ |
|
||||||
|
| `pnpm format` | จัดรูปแบบโค้ดของคุณด้วย Biome |
|
||||||
|
| `pnpm new-post <filename>` | สร้างโพสต์ใหม่ |
|
||||||
|
| `pnpm astro ...` | รันคำสั่ง CLI เช่น `astro add`, `astro check` |
|
||||||
|
| `pnpm astro --help` | แสดงวิธีใช้งาน Astro CLI |
|
||||||
|
|
||||||
|
## ✏️ การมีส่วนร่วม
|
||||||
|
|
||||||
|
กรุณาอ่าน [แนวทางการมีส่วนร่วม](https://github.com/saicaca/fuwari/blob/main/CONTRIBUTING.md) สำหรับรายละเอียดวิธีการมีส่วนร่วมในโปรเจกต์นี้
|
||||||
|
|
||||||
|
## 📄 สัญญาอนุญาต
|
||||||
|
|
||||||
|
โปรเจกต์นี้เผยแพร่ภายใต้สัญญาอนุญาตแบบ MIT License
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# 🍥Fuwari
|
||||||
|
|
||||||
|
Một mẫu blog tĩnh được xây bằng [Astro](https://astro.build).
|
||||||
|
|
||||||
|
[**🖥️ Xem bản dùng thử (Vercel)**](https://fuwari.vercel.app)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## ✨ Tính năng
|
||||||
|
|
||||||
|
- [x] Được xây dựng bằng [Astro](https://astro.build) và [Tailwind CSS](https://tailwindcss.com)
|
||||||
|
- [x] Có hoạt ảnh đổi chuyển trang mượt mà
|
||||||
|
- [x] Chế độ sáng / tối
|
||||||
|
- [x] Màu sắc và biểu ngữ có thể tùy chỉnh được
|
||||||
|
- [x] Thiết kế nhanh nhạy
|
||||||
|
- [x] Có chức năng tìm kiếm với [Pagefind](https://pagefind.app/)
|
||||||
|
- [x] [Có các tính năng mở rộng của Markdown](https://github.com/saicaca/fuwari?tab=readme-ov-file#-markdown-extended-syntax)
|
||||||
|
- [x] Có mục lục
|
||||||
|
- [x] Nguồn cấp dữ liệu RSS
|
||||||
|
|
||||||
|
## 🚀 Bắt đầu
|
||||||
|
|
||||||
|
1. Tạo kho lưu trữ blog của bạn:
|
||||||
|
- [Tạo một kho lưu trữ mới](https://github.com/saicaca/fuwari/generate) từ mẫu này hoặc fork kho lưu trữ này.
|
||||||
|
- Hoặc chạy một trong các lệnh sau:
|
||||||
|
```sh
|
||||||
|
npm create fuwari@latest
|
||||||
|
yarn create fuwari
|
||||||
|
pnpm create fuwari@latest
|
||||||
|
bun create fuwari@latest
|
||||||
|
deno run -A npm:create-fuwari@latest
|
||||||
|
```
|
||||||
|
2. Để chỉnh sửa blog của bạn trên máy cục bộ, hãy clone kho lưu trữ của bạn, chạy lệnh `pnpm install` để cài đặt các phụ thuộc..
|
||||||
|
- Cài đặt [pnpm](https://pnpm.io) `npm install -g pnpm` nếu chưa có.
|
||||||
|
3. Chỉnh sửa tệp cấu hình `src/config.ts` để tùy chỉnh blog của bạn.
|
||||||
|
4. Chạy `pnpm new-post <filename>` để tạo một bài viết mới và chỉnh sửa nó trong `src/content/posts/`.
|
||||||
|
5. Triển khai blog của bạn lên Vercel, Netlify, GitHub Pages, etc. theo [chỉ dẫn](https://docs.astro.build/en/guides/deploy/). Bạn cần chỉnh sửa cấu hình trang web trong `astro.config.mjs` trước khi triển khai.
|
||||||
|
|
||||||
|
## 📝 Tiêu đề đầy đủ của bài viết
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: Blog đầu tiên của mình
|
||||||
|
published: 2023-09-09
|
||||||
|
description: Đây là bài viết đầu tiên vủa mình trên trang blog tạo bằng Astro này.
|
||||||
|
image: ./cover.jpg
|
||||||
|
tags: [Foo, Bar]
|
||||||
|
category: Front-end
|
||||||
|
draft: false
|
||||||
|
lang: jp # Chỉ đặt nếu ngôn ngữ của bài viết khác với ngôn ngữ của trang web trong `config.ts`
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧩 Cú pháp Markdown mở rộng
|
||||||
|
|
||||||
|
Ngoài việc Astro đã có hỗ trợ mặc định cho [Markdown vị Github](https://github.github.com/gfm/), một số tính năng Markdown khác cũng đã được bổ sung:
|
||||||
|
|
||||||
|
- Chêm xen ([Xem trước và Cách sử dụng](https://fuwari.vercel.app/posts/markdown-extended/#admonitions))
|
||||||
|
- Thẻ hiển thị kho lưu trữ GitHub ([Xem trước và Cách sử dụng](https://fuwari.vercel.app/posts/markdown-extended/#github-repository-cards))
|
||||||
|
- Các khối mã nâng cao với Expressive Code ([Xem trước](https://fuwari.vercel.app/posts/expressive-code/) / [Tài liệu](https://expressive-code.com/))
|
||||||
|
|
||||||
|
## ⚡ Lệnh
|
||||||
|
|
||||||
|
Tất cả các lệnh được chạy từ thư mục gốc của dự án, từ một bảng điều khiển:
|
||||||
|
|
||||||
|
| Lệnh | Mục đích |
|
||||||
|
|:---------------------------|:----------------------------------------------------|
|
||||||
|
| `pnpm install` | Cài đặt các phụ thuộc |
|
||||||
|
| `pnpm dev` | Khởi động máy chủ cục bộ tại `localhost:4321` |
|
||||||
|
| `pnpm build` | Xây dựng trang web của bạn vào `./dist/` |
|
||||||
|
| `pnpm preview` | Xem trước bản web cục bộ của bạn, trước khi triển khai |
|
||||||
|
| `pnpm check` | Chạy kiểm tra lỗi trong mã của bạn |
|
||||||
|
| `pnpm format` | Định dạng mã của bạn bằng Biome |
|
||||||
|
| `pnpm new-post <filename>` | Tạo một bài viết mới |
|
||||||
|
| `pnpm astro ...` | Chạy các lệnh CLI như `astro add`, `astro check` |
|
||||||
|
| `pnpm astro --help` | Nhận trợ giúp sử dụng Astro CLI |
|
||||||
|
|
||||||
|
## ✏️ Đóng góp
|
||||||
|
|
||||||
|
Xem [Hướng dẫn đóng góp](https://github.com/saicaca/fuwari/blob/main/CONTRIBUTING.md) để biết thêm chi tiết về cách đóng góp cho dự án này.
|
||||||
|
|
||||||
|
## 📄 Giấy phép
|
||||||
|
|
||||||
|
Dự án này đã được cấp Giấy phép MIT.
|
||||||
+24
-24
@@ -18,30 +18,30 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/check": "^0.9.4",
|
||||||
"@astrojs/rss": "^4.0.12",
|
"@astrojs/rss": "^4.0.12",
|
||||||
"@astrojs/sitemap": "^3.4.1",
|
"@astrojs/sitemap": "^3.6.0",
|
||||||
"@astrojs/svelte": "7.1.0",
|
"@astrojs/svelte": "7.2.0",
|
||||||
"@astrojs/tailwind": "^6.0.2",
|
"@astrojs/tailwind": "^6.0.2",
|
||||||
"@expressive-code/core": "^0.41.2",
|
"@expressive-code/core": "^0.41.3",
|
||||||
"@expressive-code/plugin-collapsible-sections": "^0.41.2",
|
"@expressive-code/plugin-collapsible-sections": "^0.41.3",
|
||||||
"@expressive-code/plugin-line-numbers": "^0.41.2",
|
"@expressive-code/plugin-line-numbers": "^0.41.3",
|
||||||
"@fontsource-variable/jetbrains-mono": "^5.2.6",
|
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
||||||
"@fontsource/roboto": "^5.2.6",
|
"@fontsource/roboto": "^5.2.8",
|
||||||
"@iconify-json/fa6-brands": "^1.2.5",
|
"@iconify-json/fa6-brands": "^1.2.6",
|
||||||
"@iconify-json/fa6-regular": "^1.2.3",
|
"@iconify-json/fa6-regular": "^1.2.4",
|
||||||
"@iconify-json/fa6-solid": "^1.2.3",
|
"@iconify-json/fa6-solid": "^1.2.4",
|
||||||
"@iconify-json/material-symbols": "^1.2.26",
|
"@iconify-json/material-symbols": "^1.2.40",
|
||||||
"@iconify/svelte": "^4.2.0",
|
"@iconify/svelte": "^4.2.0",
|
||||||
"@swup/astro": "^1.6.0",
|
"@swup/astro": "^1.7.0",
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"astro": "5.10.0",
|
"astro": "5.13.10",
|
||||||
"astro-expressive-code": "^0.41.2",
|
"astro-expressive-code": "^0.41.3",
|
||||||
"astro-icon": "^1.1.5",
|
"astro-icon": "^1.1.5",
|
||||||
"hastscript": "^9.0.1",
|
"hastscript": "^9.0.1",
|
||||||
"katex": "^0.16.22",
|
"katex": "^0.16.23",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"mdast-util-to-string": "^4.0.0",
|
"mdast-util-to-string": "^4.0.0",
|
||||||
"overlayscrollbars": "^2.11.4",
|
"overlayscrollbars": "^2.12.0",
|
||||||
"pagefind": "^1.3.0",
|
"pagefind": "^1.4.0",
|
||||||
"photoswipe": "^5.4.4",
|
"photoswipe": "^5.4.4",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
"rehype-autolink-headings": "^7.1.0",
|
"rehype-autolink-headings": "^7.1.0",
|
||||||
@@ -54,22 +54,22 @@
|
|||||||
"remark-math": "^6.0.0",
|
"remark-math": "^6.0.0",
|
||||||
"remark-sectionize": "^2.1.0",
|
"remark-sectionize": "^2.1.0",
|
||||||
"sanitize-html": "^2.17.0",
|
"sanitize-html": "^2.17.0",
|
||||||
"sharp": "^0.34.2",
|
"sharp": "^0.34.4",
|
||||||
"stylus": "^0.64.0",
|
"stylus": "^0.64.0",
|
||||||
"svelte": "^5.34.7",
|
"svelte": "^5.39.8",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.18",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.9.3",
|
||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/ts-plugin": "^1.10.4",
|
"@astrojs/ts-plugin": "^1.10.4",
|
||||||
"@biomejs/biome": "2.0.0",
|
"@biomejs/biome": "2.2.5",
|
||||||
"@rollup/plugin-yaml": "^4.1.2",
|
"@rollup/plugin-yaml": "^4.1.2",
|
||||||
"@types/hast": "^3.0.4",
|
"@types/hast": "^3.0.4",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/markdown-it": "^14.1.2",
|
||||||
"@types/mdast": "^4.0.4",
|
"@types/mdast": "^4.0.4",
|
||||||
"@types/sanitize-html": "^2.16.0",
|
"@types/sanitize-html": "^2.16.0",
|
||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.1",
|
||||||
"postcss-nesting": "^13.0.2"
|
"postcss-nesting": "^13.0.2"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@9.14.4"
|
"packageManager": "pnpm@9.14.4"
|
||||||
|
|||||||
Generated
+1825
-1943
File diff suppressed because it is too large
Load Diff
@@ -75,8 +75,8 @@ onMount(async () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const groupedPostsArray = Object.keys(grouped).map((yearStr) => ({
|
const groupedPostsArray = Object.keys(grouped).map((yearStr) => ({
|
||||||
year: Number.parseInt(yearStr),
|
year: Number.parseInt(yearStr, 10),
|
||||||
posts: grouped[Number.parseInt(yearStr)],
|
posts: grouped[Number.parseInt(yearStr, 10)],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
groupedPostsArray.sort((a, b) => b.year - a.year);
|
groupedPostsArray.sort((a, b) => b.year - a.year);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const { badge, url, label } = Astro.props;
|
|||||||
{ badge !== undefined && badge !== null && badge !== '' &&
|
{ badge !== undefined && badge !== null && badge !== '' &&
|
||||||
<div class="transition px-2 h-7 ml-4 min-w-[2rem] rounded-lg text-sm font-bold
|
<div class="transition px-2 h-7 ml-4 min-w-[2rem] rounded-lg text-sm font-bold
|
||||||
text-[var(--btn-content)] dark:text-[var(--deep-text)]
|
text-[var(--btn-content)] dark:text-[var(--deep-text)]
|
||||||
bg-[oklch(0.95_0.025_var(--hue))] dark:bg-[var(--primary)]
|
bg-[var(--btn-regular-bg)] dark:bg-[var(--primary)]
|
||||||
flex items-center justify-center">
|
flex items-center justify-center">
|
||||||
{ badge }
|
{ badge }
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ $: if (hue || hue === 0) {
|
|||||||
before:absolute before:-left-3 before:top-[0.33rem]"
|
before:absolute before:-left-3 before:top-[0.33rem]"
|
||||||
>
|
>
|
||||||
{i18n(I18nKey.themeColor)}
|
{i18n(I18nKey.themeColor)}
|
||||||
<button aria-label="Reset to Default" class="btn-regular w-7 h-7 rounded-md active:scale-90"
|
<button aria-label="Reset to Default" class="btn-regular w-7 h-7 rounded-md active:scale-90 will-change-transform"
|
||||||
class:opacity-0={hue === defaultHue} class:pointer-events-none={hue === defaultHue} on:click={resetHue}>
|
class:opacity-0={hue === defaultHue} class:pointer-events-none={hue === defaultHue} on:click={resetHue}>
|
||||||
<div class="text-[var(--btn-content)]">
|
<div class="text-[var(--btn-content)]">
|
||||||
<Icon icon="fa6-solid:arrow-rotate-left" class="text-[0.875rem]"></Icon>
|
<Icon icon="fa6-solid:arrow-rotate-left" class="text-[0.875rem]"></Icon>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const config = profileConfig;
|
|||||||
<div class="font-bold text-xl text-center mb-1 dark:text-neutral-50 transition">{config.name}</div>
|
<div class="font-bold text-xl text-center mb-1 dark:text-neutral-50 transition">{config.name}</div>
|
||||||
<div class="h-1 w-5 bg-[var(--primary)] mx-auto rounded-full mb-2 transition"></div>
|
<div class="h-1 w-5 bg-[var(--primary)] mx-auto rounded-full mb-2 transition"></div>
|
||||||
<div class="text-center text-neutral-400 mb-2.5 transition">{config.bio}</div>
|
<div class="text-center text-neutral-400 mb-2.5 transition">{config.bio}</div>
|
||||||
<div class="flex gap-2 justify-center mb-1">
|
<div class="flex flex-wrap gap-2 justify-center mb-1">
|
||||||
{config.links.length > 1 && config.links.map(item =>
|
{config.links.length > 1 && config.links.map(item =>
|
||||||
<a rel="me" aria-label={item.name} href={item.url} target="_blank" class="btn-regular rounded-lg h-10 w-10 active:scale-90">
|
<a rel="me" aria-label={item.name} href={item.url} target="_blank" class="btn-regular rounded-lg h-10 w-10 active:scale-90">
|
||||||
<Icon name={item.icon} class="text-[1.5rem]"></Icon>
|
<Icon name={item.icon} class="text-[1.5rem]"></Icon>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import type { MarkdownHeading } from "astro";
|
import type { MarkdownHeading } from "astro";
|
||||||
import { siteConfig } from "../../config";
|
import { siteConfig } from "../../config";
|
||||||
|
import { url } from "../../utils/url-utils";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
class?: string;
|
class?: string;
|
||||||
@@ -15,8 +16,7 @@ for (const heading of headings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const className = Astro.props.class;
|
const className = Astro.props.class;
|
||||||
|
const isPostsRoute = Astro.url.pathname.startsWith(url("/posts/"));
|
||||||
const isPostsRoute = Astro.url.pathname.startsWith("/posts/");
|
|
||||||
|
|
||||||
const removeTailingHash = (text: string) => {
|
const removeTailingHash = (text: string) => {
|
||||||
let lastIndexOfHash = text.lastIndexOf("#");
|
let lastIndexOfHash = text.lastIndexOf("#");
|
||||||
@@ -55,7 +55,7 @@ const maxLevel = siteConfig.toc.depth;
|
|||||||
}]}>{removeTailingHash(heading.text)}</div>
|
}]}>{removeTailingHash(heading.text)}</div>
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
<div id="active-indicator" class:list={[{'hidden': headings.length == 0}, "-z-10 absolute bg-[var(--toc-btn-hover)] left-0 right-0 rounded-xl transition-all " +
|
<div id="active-indicator" style="opacity: 0" class:list={[{'hidden': headings.length == 0}, "-z-10 absolute bg-[var(--toc-btn-hover)] left-0 right-0 rounded-xl transition-all " +
|
||||||
"group-hover:bg-transparent border-2 border-[var(--toc-btn-hover)] group-hover:border-[var(--toc-btn-active)] border-dashed"]}></div>
|
"group-hover:bg-transparent border-2 border-[var(--toc-btn-hover)] group-hover:border-[var(--toc-btn-active)] border-dashed"]}></div>
|
||||||
</table-of-contents>}
|
</table-of-contents>}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ class TableOfContents extends HTMLElement {
|
|||||||
|
|
||||||
toggleActiveHeading = () => {
|
toggleActiveHeading = () => {
|
||||||
let i = this.active.length - 1;
|
let i = this.active.length - 1;
|
||||||
let min = this.active.length - 1, max = 0;
|
let min = this.active.length - 1, max = -1;
|
||||||
while (i >= 0 && !this.active[i]) {
|
while (i >= 0 && !this.active[i]) {
|
||||||
this.tocEntries[i].classList.remove(this.visibleClass);
|
this.tocEntries[i].classList.remove(this.visibleClass);
|
||||||
i--;
|
i--;
|
||||||
@@ -112,11 +112,15 @@ class TableOfContents extends HTMLElement {
|
|||||||
this.tocEntries[i].classList.remove(this.visibleClass);
|
this.tocEntries[i].classList.remove(this.visibleClass);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
let parentOffset = this.tocEl?.getBoundingClientRect().top || 0;
|
if (min > max) {
|
||||||
let scrollOffset = this.tocEl?.scrollTop || 0;
|
this.activeIndicator?.setAttribute("style", `opacity: 0`);
|
||||||
let top = this.tocEntries[min].getBoundingClientRect().top - parentOffset + scrollOffset;
|
} else {
|
||||||
let bottom = this.tocEntries[max].getBoundingClientRect().bottom - parentOffset + scrollOffset;
|
let parentOffset = this.tocEl?.getBoundingClientRect().top || 0;
|
||||||
this.activeIndicator?.setAttribute("style", `top: ${top}px; height: ${bottom - top}px`);
|
let scrollOffset = this.tocEl?.scrollTop || 0;
|
||||||
|
let top = this.tocEntries[min].getBoundingClientRect().top - parentOffset + scrollOffset;
|
||||||
|
let bottom = this.tocEntries[max].getBoundingClientRect().bottom - parentOffset + scrollOffset;
|
||||||
|
this.activeIndicator?.setAttribute("style", `top: ${top}px; height: ${bottom - top}px`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
scrollToActiveHeading = () => {
|
scrollToActiveHeading = () => {
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import { LinkPreset } from "./types/config";
|
|||||||
export const siteConfig: SiteConfig = {
|
export const siteConfig: SiteConfig = {
|
||||||
title: "Fuwari",
|
title: "Fuwari",
|
||||||
subtitle: "Demo Site",
|
subtitle: "Demo Site",
|
||||||
lang: "en", // 'en', 'zh_CN', 'zh_TW', 'ja', 'ko', 'es', 'th'
|
lang: "en", // Language code, e.g. 'en', 'zh_CN', 'ja', etc.
|
||||||
themeColor: {
|
themeColor: {
|
||||||
hue: 250, // Default hue for the theme color, from 0 to 360. e.g. red: 0, teal: 200, cyan: 250, pink: 345
|
hue: 250, // Default hue for the theme color, from 0 to 360. e.g. red: 0, teal: 200, cyan: 250, pink: 345
|
||||||
fixed: false, // Hide the theme color picker for visitors
|
fixed: false, // Hide the theme color picker for visitors
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ const postsCollection = defineCollection({
|
|||||||
nextSlug: z.string().default(""),
|
nextSlug: z.string().default(""),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
const specCollection = defineCollection({
|
||||||
|
schema: z.object({}),
|
||||||
|
});
|
||||||
export const collections = {
|
export const collections = {
|
||||||
posts: postsCollection,
|
posts: postsCollection,
|
||||||
|
spec: specCollection,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,3 +94,14 @@ This is a note with a custom title.
|
|||||||
> [!TIP]
|
> [!TIP]
|
||||||
> The GitHub syntax is also supported.
|
> The GitHub syntax is also supported.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Spoiler
|
||||||
|
|
||||||
|
You can add spoilers to your text. The text also supports **Markdown** syntax.
|
||||||
|
|
||||||
|
The content :spoiler[is hidden **ayyy**]!
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
The content :spoiler[is hidden **ayyy**]!
|
||||||
|
|
||||||
|
```
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import Key from "../i18nKey";
|
||||||
|
import type { Translation } from "../translation";
|
||||||
|
|
||||||
|
export const id: Translation = {
|
||||||
|
[Key.home]: "Beranda",
|
||||||
|
[Key.about]: "Tentang",
|
||||||
|
[Key.archive]: "Arsip",
|
||||||
|
[Key.search]: "Cari",
|
||||||
|
|
||||||
|
[Key.tags]: "Tag",
|
||||||
|
[Key.categories]: "Kategori",
|
||||||
|
[Key.recentPosts]: "Postingan Terbaru",
|
||||||
|
|
||||||
|
[Key.comments]: "Komentar",
|
||||||
|
|
||||||
|
[Key.untitled]: "Tanpa Judul",
|
||||||
|
[Key.uncategorized]: "Tanpa Kategori",
|
||||||
|
[Key.noTags]: "Tanpa Tag",
|
||||||
|
|
||||||
|
[Key.wordCount]: "kata",
|
||||||
|
[Key.wordsCount]: "kata",
|
||||||
|
[Key.minuteCount]: "menit",
|
||||||
|
[Key.minutesCount]: "menit",
|
||||||
|
[Key.postCount]: "postingan",
|
||||||
|
[Key.postsCount]: "postingan",
|
||||||
|
|
||||||
|
[Key.themeColor]: "Warna Tema",
|
||||||
|
|
||||||
|
[Key.lightMode]: "Terang",
|
||||||
|
[Key.darkMode]: "Gelap",
|
||||||
|
[Key.systemMode]: "Sistem",
|
||||||
|
|
||||||
|
[Key.more]: "Lainnya",
|
||||||
|
|
||||||
|
[Key.author]: "Penulis",
|
||||||
|
[Key.publishedAt]: "Diterbitkan pada",
|
||||||
|
[Key.license]: "Lisensi",
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import Key from "../i18nKey";
|
||||||
|
import type { Translation } from "../translation";
|
||||||
|
|
||||||
|
export const tr: Translation = {
|
||||||
|
[Key.home]: "Anasayfa",
|
||||||
|
[Key.about]: "Hakkında",
|
||||||
|
[Key.archive]: "Arşiv",
|
||||||
|
[Key.search]: "Ara",
|
||||||
|
|
||||||
|
[Key.tags]: "Taglar",
|
||||||
|
[Key.categories]: "Katagoriler",
|
||||||
|
[Key.recentPosts]: "Son Paylaşımlar",
|
||||||
|
|
||||||
|
[Key.comments]: "Yorumlar",
|
||||||
|
|
||||||
|
[Key.untitled]: "Başlıksız",
|
||||||
|
[Key.uncategorized]: "Katagorisiz",
|
||||||
|
[Key.noTags]: "Tag Bulunamadı",
|
||||||
|
|
||||||
|
[Key.wordCount]: "kelime",
|
||||||
|
[Key.wordsCount]: "kelime",
|
||||||
|
[Key.minuteCount]: "dakika",
|
||||||
|
[Key.minutesCount]: "dakika",
|
||||||
|
[Key.postCount]: "gönderi",
|
||||||
|
[Key.postsCount]: "gönderiler",
|
||||||
|
|
||||||
|
[Key.themeColor]: "Tema Rengi",
|
||||||
|
|
||||||
|
[Key.lightMode]: "Aydınlık",
|
||||||
|
[Key.darkMode]: "Koyu",
|
||||||
|
[Key.systemMode]: "Sistem",
|
||||||
|
|
||||||
|
[Key.more]: "Daha Fazla",
|
||||||
|
|
||||||
|
[Key.author]: "Yazar",
|
||||||
|
[Key.publishedAt]: "Yayınlanma:",
|
||||||
|
[Key.license]: "Lisans",
|
||||||
|
};
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import Key from "../i18nKey";
|
||||||
|
import type { Translation } from "../translation";
|
||||||
|
|
||||||
|
export const vi: Translation = {
|
||||||
|
[Key.home]: "Trang chủ",
|
||||||
|
[Key.about]: "Giới thiệu",
|
||||||
|
[Key.archive]: "Kho bài",
|
||||||
|
[Key.search]: "Tìm kiếm",
|
||||||
|
|
||||||
|
[Key.tags]: "Thẻ",
|
||||||
|
[Key.categories]: "Danh mục",
|
||||||
|
[Key.recentPosts]: "Bài viết mới nhất",
|
||||||
|
|
||||||
|
[Key.comments]: "Bình luận",
|
||||||
|
|
||||||
|
[Key.untitled]: "Không tiêu đề",
|
||||||
|
[Key.uncategorized]: "Chưa phân loại",
|
||||||
|
[Key.noTags]: "Chưa có thẻ",
|
||||||
|
|
||||||
|
[Key.wordCount]: "từ",
|
||||||
|
[Key.wordsCount]: "từ",
|
||||||
|
[Key.minuteCount]: "phút đọc",
|
||||||
|
[Key.minutesCount]: "phút đọc",
|
||||||
|
[Key.postCount]: "bài viết",
|
||||||
|
[Key.postsCount]: "bài viết",
|
||||||
|
|
||||||
|
[Key.themeColor]: "Màu giao diện",
|
||||||
|
|
||||||
|
[Key.lightMode]: "Sáng",
|
||||||
|
[Key.darkMode]: "Tối",
|
||||||
|
[Key.systemMode]: "Hệ thống",
|
||||||
|
|
||||||
|
[Key.more]: "Thêm",
|
||||||
|
|
||||||
|
[Key.author]: "Tác giả",
|
||||||
|
[Key.publishedAt]: "Đăng vào lúc",
|
||||||
|
[Key.license]: "Giấy phép bản quyền",
|
||||||
|
};
|
||||||
@@ -2,9 +2,12 @@ import { siteConfig } from "../config";
|
|||||||
import type I18nKey from "./i18nKey";
|
import type I18nKey from "./i18nKey";
|
||||||
import { en } from "./languages/en";
|
import { en } from "./languages/en";
|
||||||
import { es } from "./languages/es";
|
import { es } from "./languages/es";
|
||||||
|
import { id } from "./languages/id";
|
||||||
import { ja } from "./languages/ja";
|
import { ja } from "./languages/ja";
|
||||||
import { ko } from "./languages/ko";
|
import { ko } from "./languages/ko";
|
||||||
import { th } from "./languages/th";
|
import { th } from "./languages/th";
|
||||||
|
import { tr } from "./languages/tr";
|
||||||
|
import { vi } from "./languages/vi";
|
||||||
import { zh_CN } from "./languages/zh_CN";
|
import { zh_CN } from "./languages/zh_CN";
|
||||||
import { zh_TW } from "./languages/zh_TW";
|
import { zh_TW } from "./languages/zh_TW";
|
||||||
|
|
||||||
@@ -28,6 +31,11 @@ const map: { [key: string]: Translation } = {
|
|||||||
ko_kr: ko,
|
ko_kr: ko,
|
||||||
th: th,
|
th: th,
|
||||||
th_th: th,
|
th_th: th,
|
||||||
|
vi: vi,
|
||||||
|
vi_vn: vi,
|
||||||
|
id: id,
|
||||||
|
tr: tr,
|
||||||
|
tr_tr: tr,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getTranslation(lang: string): Translation {
|
export function getTranslation(lang: string): Translation {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import ArchivePanel from "@components/ArchivePanel.svelte";
|
|||||||
import I18nKey from "@i18n/i18nKey";
|
import I18nKey from "@i18n/i18nKey";
|
||||||
import { i18n } from "@i18n/translation";
|
import { i18n } from "@i18n/translation";
|
||||||
import MainGridLayout from "@layouts/MainGridLayout.astro";
|
import MainGridLayout from "@layouts/MainGridLayout.astro";
|
||||||
import { getSortedPosts } from "../utils/content-utils";
|
import { getSortedPostsList } from "../utils/content-utils";
|
||||||
|
|
||||||
const sortedPosts = await getSortedPosts();
|
const sortedPostsList = await getSortedPostsList();
|
||||||
---
|
---
|
||||||
|
|
||||||
<MainGridLayout title={i18n(I18nKey.archive)}>
|
<MainGridLayout title={i18n(I18nKey.archive)}>
|
||||||
<ArchivePanel sortedPosts={sortedPosts} client:only="svelte"></ArchivePanel>
|
<ArchivePanel sortedPosts={sortedPostsList} client:only="svelte"></ArchivePanel>
|
||||||
</MainGridLayout>
|
</MainGridLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import rss from "@astrojs/rss";
|
import rss from "@astrojs/rss";
|
||||||
import { getSortedPosts } from "@utils/content-utils";
|
import { getSortedPosts } from "@utils/content-utils";
|
||||||
|
import { url } from "@utils/url-utils";
|
||||||
import type { APIContext } from "astro";
|
import type { APIContext } from "astro";
|
||||||
import MarkdownIt from "markdown-it";
|
import MarkdownIt from "markdown-it";
|
||||||
import sanitizeHtml from "sanitize-html";
|
import sanitizeHtml from "sanitize-html";
|
||||||
@@ -30,7 +31,7 @@ export async function GET(context: APIContext) {
|
|||||||
title: post.data.title,
|
title: post.data.title,
|
||||||
pubDate: post.data.published,
|
pubDate: post.data.published,
|
||||||
description: post.data.description || "",
|
description: post.data.description || "",
|
||||||
link: `/posts/${post.slug}/`,
|
link: url(`/posts/${post.slug}/`),
|
||||||
content: sanitizeHtml(parser.render(cleanedContent), {
|
content: sanitizeHtml(parser.render(cleanedContent), {
|
||||||
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
|
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { definePlugin } from "@expressive-code/core";
|
|||||||
export function pluginLanguageBadge() {
|
export function pluginLanguageBadge() {
|
||||||
return definePlugin({
|
return definePlugin({
|
||||||
name: "Language Badge",
|
name: "Language Badge",
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
baseStyles: ({ _cssVar }) => `
|
baseStyles: ({ _cssVar }) => `
|
||||||
[data-language]::before {
|
[data-language]::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -15,6 +15,7 @@ export function pluginLanguageBadge() {
|
|||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
padding: 0.1rem 0.5rem;
|
padding: 0.1rem 0.5rem;
|
||||||
content: attr(data-language);
|
content: attr(data-language);
|
||||||
|
font-family: "JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
.expressive-code .frame {
|
.expressive-code {
|
||||||
@apply !shadow-none;
|
.frame {
|
||||||
|
@apply !shadow-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: "JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,3 +139,14 @@
|
|||||||
.collapsed {
|
.collapsed {
|
||||||
height: var(--collapsedHeight);
|
height: var(--collapsedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-md spoiler {
|
||||||
|
@apply bg-[var(--codeblock-bg)] hover:bg-transparent px-1 py-0.5 overflow-hidden rounded-md transition-all duration-150;
|
||||||
|
|
||||||
|
&:not(:hover) {
|
||||||
|
color: var(--codeblock-bg);
|
||||||
|
* {
|
||||||
|
color: var(--codeblock-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
underline decoration-[var(--link-underline)] decoration-1 decoration-dashed underline-offset-4;
|
underline decoration-[var(--link-underline)] decoration-1 decoration-dashed underline-offset-4;
|
||||||
box-decoration-break: clone;
|
box-decoration-break: clone;
|
||||||
-webkit-box-decoration-break: clone;
|
-webkit-box-decoration-break: clone;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
&:hover, &:active {
|
&:hover, &:active {
|
||||||
@apply decoration-transparent;
|
@apply decoration-transparent;
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ define({
|
|||||||
--admonitions-color-warning: oklch(0.7 0.14 60) oklch(0.75 0.14 60)
|
--admonitions-color-warning: oklch(0.7 0.14 60) oklch(0.75 0.14 60)
|
||||||
--admonitions-color-caution: oklch(0.6 0.2 25) oklch(0.65 0.2 25)
|
--admonitions-color-caution: oklch(0.6 0.2 25) oklch(0.65 0.2 25)
|
||||||
|
|
||||||
--toc-badge-bg: oklch(0.9 0.045 var(--hue)) var(--btn-regular-bg)
|
--toc-badge-bg: oklch(0.89 0.050 var(--hue)) var(--btn-regular-bg)
|
||||||
--toc-btn-hover: oklch(0.92 0.015 var(--hue)) oklch(0.22 0.02 var(--hue))
|
--toc-btn-hover: oklch(0.926 0.015 var(--hue)) oklch(0.22 0.02 var(--hue))
|
||||||
--toc-btn-active: oklch(0.90 0.015 var(--hue)) oklch(0.25 0.02 var(--hue))
|
--toc-btn-active: oklch(0.90 0.015 var(--hue)) oklch(0.25 0.02 var(--hue))
|
||||||
--toc-width: calc((100vw - var(--page-width)) / 2 - 1rem)
|
--toc-width: calc((100vw - var(--page-width)) / 2 - 1rem)
|
||||||
--toc-item-active: oklch(0.70 0.13 var(--hue)) oklch(0.35 0.07 var(--hue))
|
--toc-item-active: oklch(0.70 0.13 var(--hue)) oklch(0.35 0.07 var(--hue))
|
||||||
|
|||||||
+11
-1
@@ -4,7 +4,17 @@ export type SiteConfig = {
|
|||||||
title: string;
|
title: string;
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
|
|
||||||
lang: string;
|
lang:
|
||||||
|
| "en"
|
||||||
|
| "zh_CN"
|
||||||
|
| "zh_TW"
|
||||||
|
| "ja"
|
||||||
|
| "ko"
|
||||||
|
| "es"
|
||||||
|
| "th"
|
||||||
|
| "vi"
|
||||||
|
| "tr"
|
||||||
|
| "id";
|
||||||
|
|
||||||
themeColor: {
|
themeColor: {
|
||||||
hue: number;
|
hue: number;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { getCollection } from "astro:content";
|
import { type CollectionEntry, getCollection } from "astro:content";
|
||||||
import I18nKey from "@i18n/i18nKey";
|
import I18nKey from "@i18n/i18nKey";
|
||||||
import { i18n } from "@i18n/translation";
|
import { i18n } from "@i18n/translation";
|
||||||
import { getCategoryUrl } from "@utils/url-utils.ts";
|
import { getCategoryUrl } from "@utils/url-utils.ts";
|
||||||
|
|
||||||
export async function getSortedPosts() {
|
// // Retrieve posts and sort them by publication date
|
||||||
|
async function getRawSortedPosts() {
|
||||||
const allBlogPosts = await getCollection("posts", ({ data }) => {
|
const allBlogPosts = await getCollection("posts", ({ data }) => {
|
||||||
return import.meta.env.PROD ? data.draft !== true : true;
|
return import.meta.env.PROD ? data.draft !== true : true;
|
||||||
});
|
});
|
||||||
@@ -13,6 +14,11 @@ export async function getSortedPosts() {
|
|||||||
const dateB = new Date(b.data.published);
|
const dateB = new Date(b.data.published);
|
||||||
return dateA > dateB ? -1 : 1;
|
return dateA > dateB ? -1 : 1;
|
||||||
});
|
});
|
||||||
|
return sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSortedPosts() {
|
||||||
|
const sorted = await getRawSortedPosts();
|
||||||
|
|
||||||
for (let i = 1; i < sorted.length; i++) {
|
for (let i = 1; i < sorted.length; i++) {
|
||||||
sorted[i].data.nextSlug = sorted[i - 1].slug;
|
sorted[i].data.nextSlug = sorted[i - 1].slug;
|
||||||
@@ -25,7 +31,21 @@ export async function getSortedPosts() {
|
|||||||
|
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
export type PostForList = {
|
||||||
|
slug: string;
|
||||||
|
data: CollectionEntry<"posts">["data"];
|
||||||
|
};
|
||||||
|
export async function getSortedPostsList(): Promise<PostForList[]> {
|
||||||
|
const sortedFullPosts = await getRawSortedPosts();
|
||||||
|
|
||||||
|
// delete post.body
|
||||||
|
const sortedPostsList = sortedFullPosts.map((post) => ({
|
||||||
|
slug: post.slug,
|
||||||
|
data: post.data,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return sortedPostsList;
|
||||||
|
}
|
||||||
export type Tag = {
|
export type Tag = {
|
||||||
name: string;
|
name: string;
|
||||||
count: number;
|
count: number;
|
||||||
@@ -37,8 +57,8 @@ export async function getTagList(): Promise<Tag[]> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const countMap: { [key: string]: number } = {};
|
const countMap: { [key: string]: number } = {};
|
||||||
allBlogPosts.map((post: { data: { tags: string[] } }) => {
|
allBlogPosts.forEach((post: { data: { tags: string[] } }) => {
|
||||||
post.data.tags.map((tag: string) => {
|
post.data.tags.forEach((tag: string) => {
|
||||||
if (!countMap[tag]) countMap[tag] = 0;
|
if (!countMap[tag]) countMap[tag] = 0;
|
||||||
countMap[tag]++;
|
countMap[tag]++;
|
||||||
});
|
});
|
||||||
@@ -63,7 +83,7 @@ export async function getCategoryList(): Promise<Category[]> {
|
|||||||
return import.meta.env.PROD ? data.draft !== true : true;
|
return import.meta.env.PROD ? data.draft !== true : true;
|
||||||
});
|
});
|
||||||
const count: { [key: string]: number } = {};
|
const count: { [key: string]: number } = {};
|
||||||
allBlogPosts.map((post: { data: { category: string | null } }) => {
|
allBlogPosts.forEach((post: { data: { category: string | null } }) => {
|
||||||
if (!post.data.category) {
|
if (!post.data.category) {
|
||||||
const ucKey = i18n(I18nKey.uncategorized);
|
const ucKey = i18n(I18nKey.uncategorized);
|
||||||
count[ucKey] = count[ucKey] ? count[ucKey] + 1 : 1;
|
count[ucKey] = count[ucKey] ? count[ucKey] + 1 : 1;
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import type { LIGHT_DARK_MODE } from "@/types/config";
|
|||||||
export function getDefaultHue(): number {
|
export function getDefaultHue(): number {
|
||||||
const fallback = "250";
|
const fallback = "250";
|
||||||
const configCarrier = document.getElementById("config-carrier");
|
const configCarrier = document.getElementById("config-carrier");
|
||||||
return Number.parseInt(configCarrier?.dataset.hue || fallback);
|
return Number.parseInt(configCarrier?.dataset.hue || fallback, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHue(): number {
|
export function getHue(): number {
|
||||||
const stored = localStorage.getItem("hue");
|
const stored = localStorage.getItem("hue");
|
||||||
return stored ? Number.parseInt(stored) : getDefaultHue();
|
return stored ? Number.parseInt(stored, 10) : getDefaultHue();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setHue(hue: number): void {
|
export function setHue(hue: number): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user