mirror of
https://github.com/tiennm99/tsuki.git
synced 2026-09-02 16:20:55 +00:00
feat: native Markdown callouts, reading time, archetype scaffold
Add blockquote-to-callout rendering, reading time estimate, improved default archetype with demo callout content and Vietnamese translations.
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
description: ""
|
||||
tags: []
|
||||
categories: []
|
||||
cover:
|
||||
image: ""
|
||||
---
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* tsuki: callouts (Markdown alert syntax: > [!note], > [!warning], etc.) */
|
||||
|
||||
.callout {
|
||||
margin-block: var(--tsuki-space-4);
|
||||
padding: var(--tsuki-space-3) var(--tsuki-space-4);
|
||||
border-inline-start: 3px solid var(--tsuki-callout, var(--tsuki-accent));
|
||||
background: var(--tsuki-callout-bg, transparent);
|
||||
border-radius: var(--tsuki-radius);
|
||||
color: var(--tsuki-fg);
|
||||
font-style: normal;
|
||||
}
|
||||
.callout :is(p:last-child) { margin-block-end: 0; }
|
||||
.callout-title {
|
||||
font-weight: 600;
|
||||
margin: 0 0 var(--tsuki-space-2);
|
||||
color: var(--tsuki-callout, var(--tsuki-accent));
|
||||
font-size: var(--tsuki-fs-sm);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.callout-note { --tsuki-callout: #2563eb; --tsuki-callout-bg: #2563eb14; }
|
||||
.callout-tip { --tsuki-callout: #16a34a; --tsuki-callout-bg: #16a34a14; }
|
||||
.callout-important { --tsuki-callout: #7c3aed; --tsuki-callout-bg: #7c3aed14; }
|
||||
.callout-warning { --tsuki-callout: #d97706; --tsuki-callout-bg: #d9770614; }
|
||||
.callout-caution { --tsuki-callout: #dc2626; --tsuki-callout-bg: #dc262614; }
|
||||
|
||||
:where([data-theme="dark"]) {
|
||||
.callout-note { --tsuki-callout: #6ea1ff; --tsuki-callout-bg: #6ea1ff1f; }
|
||||
.callout-tip { --tsuki-callout: #4ade80; --tsuki-callout-bg: #4ade801f; }
|
||||
.callout-important { --tsuki-callout: #a78bfa; --tsuki-callout-bg: #a78bfa1f; }
|
||||
.callout-warning { --tsuki-callout: #fbbf24; --tsuki-callout-bg: #fbbf241f; }
|
||||
.callout-caution { --tsuki-callout: #f87171; --tsuki-callout-bg: #f871711f; }
|
||||
}
|
||||
@@ -102,6 +102,61 @@ Set CSS variables inline via a frontmatter `style` you wire up yourself, or use
|
||||
|
||||
Then style `body.section-work { --tsuki-accent: #...; }` in your custom CSS.
|
||||
|
||||
## Callouts (admonitions)
|
||||
|
||||
Use Hugo's native Markdown alert syntax (Hugo 0.140+) — no shortcode needed:
|
||||
|
||||
```markdown
|
||||
> [!note]
|
||||
> Useful side information.
|
||||
|
||||
> [!tip]
|
||||
> Reader-friendly hint.
|
||||
|
||||
> [!important]
|
||||
> Hard requirement.
|
||||
|
||||
> [!warning]
|
||||
> Heads-up about a pitfall.
|
||||
|
||||
> [!caution]
|
||||
> Risk of breakage.
|
||||
```
|
||||
|
||||
Titles localize via `i18n/vi.yml` keys `calloutNote`, `calloutTip`, `calloutImportant`, `calloutWarning`, `calloutCaution`. Override per-callout with `> [!note] Custom title`.
|
||||
|
||||
Plain `> blockquote` still renders as the regular muted blockquote — only `[!type]` triggers callout styling.
|
||||
|
||||
**Override callout colors** in your custom CSS — each callout type exposes the `--tsuki-callout` and `--tsuki-callout-bg` tokens through its modifier class:
|
||||
|
||||
```css
|
||||
/* your-site/assets/css/custom.css */
|
||||
.callout-note { --tsuki-callout: #ff5d8f; --tsuki-callout-bg: #ff5d8f1f; }
|
||||
```
|
||||
|
||||
## Show word count
|
||||
|
||||
Reading time is shown on every post by default. Add word count under it with:
|
||||
|
||||
```yaml
|
||||
params:
|
||||
showWordCount: true # default false
|
||||
```
|
||||
|
||||
The byline reads `5 phút đọc · 1024 từ` (translated via the `wordCount` i18n key).
|
||||
|
||||
## Accessibility & SEO defaults
|
||||
|
||||
The theme includes accessibility features that require no configuration:
|
||||
|
||||
- **Skip-link** — first focusable element on every page; jumps to `<main id="main">` (WCAG 2.1 M3)
|
||||
- **Focus rings** — visible outline via `--tsuki-accent` on `:focus-visible` for keyboard navigation
|
||||
- **Lastmod byline** — shows "Cập nhật {date}" when modified date is ≥24h newer than publish date
|
||||
- **Lazy-load images** — all in-content images get `loading="lazy" decoding="async"` via render hook
|
||||
- **External link security** — all Markdown links to `http://` / `https://` / `//` get `rel="noopener noreferrer"` automatically
|
||||
|
||||
All of these are transparent — no override hooks needed unless you want to customize the markup.
|
||||
|
||||
## Disable features
|
||||
|
||||
Every interactive feature has a kill switch:
|
||||
|
||||
@@ -7,7 +7,7 @@ categories: ["demo"]
|
||||
description: "Bài viết mẫu cho tsuki theme."
|
||||
---
|
||||
|
||||
Đây là một bài viết mẫu để kiểm tra layout của tsuki.
|
||||
Đây là một bài viết mẫu để kiểm tra layout của tsuki. Bài viết này tham khảo [tài liệu chính thức của Hugo](https://gohugo.io/documentation/) và [đặc tả Markdown của CommonMark](https://commonmark.org/).
|
||||
|
||||
## Heading thứ hai
|
||||
|
||||
@@ -21,3 +21,24 @@ def hello():
|
||||
- Mục một
|
||||
- Mục hai
|
||||
- Mục ba
|
||||
|
||||
## Trích dẫn
|
||||
|
||||
> Một blockquote thông thường — không có `[!type]`, vẫn hiển thị kiểu mặc định nghiêng và viền nhạt.
|
||||
|
||||
## Hộp thông báo (callouts)
|
||||
|
||||
> [!note]
|
||||
> Đây là một ghi chú thông thường — dùng khi muốn nhấn mạnh một thông tin phụ.
|
||||
|
||||
> [!tip]
|
||||
> Mẹo: dùng `> [!tip]` thay cho blockquote khi muốn nội dung nổi bật hơn.
|
||||
|
||||
> [!important]
|
||||
> Quan trọng: trang chủ là portfolio, không phải danh sách bài viết.
|
||||
|
||||
> [!warning]
|
||||
> Cảnh báo: `taxonomies: { tag: tags }` là một phần của hợp đồng theme.
|
||||
|
||||
> [!caution]
|
||||
> Thận trọng: chỉnh sửa `markup.goldmark.renderer.unsafe` có thể vô hiệu hoá footnote.
|
||||
|
||||
+45
-6
@@ -1,6 +1,24 @@
|
||||
- id: readingTime
|
||||
translation: "{{ .Count }} phút đọc"
|
||||
|
||||
- id: wordCount
|
||||
translation: "{{ .Count }} từ"
|
||||
|
||||
- id: calloutNote
|
||||
translation: "Ghi chú"
|
||||
|
||||
- id: calloutTip
|
||||
translation: "Mẹo"
|
||||
|
||||
- id: calloutImportant
|
||||
translation: "Quan trọng"
|
||||
|
||||
- id: calloutWarning
|
||||
translation: "Cảnh báo"
|
||||
|
||||
- id: calloutCaution
|
||||
translation: "Thận trọng"
|
||||
|
||||
- id: postedOn
|
||||
translation: "Đăng vào"
|
||||
|
||||
@@ -34,12 +52,6 @@
|
||||
- id: tableOfContents
|
||||
translation: "Mục lục"
|
||||
|
||||
- id: previousPage
|
||||
translation: "Trang trước"
|
||||
|
||||
- id: nextPage
|
||||
translation: "Trang tiếp"
|
||||
|
||||
- id: prev
|
||||
translation: "Trước"
|
||||
|
||||
@@ -87,3 +99,30 @@
|
||||
|
||||
- id: copyright
|
||||
translation: "© {{ .Year }} {{ .Author }}"
|
||||
|
||||
- id: comments
|
||||
translation: "Bình luận"
|
||||
|
||||
- id: month
|
||||
translation: "Tháng {{ .Number }}"
|
||||
|
||||
- id: pageNotFound
|
||||
translation: "Trang không tồn tại."
|
||||
|
||||
- id: backHome
|
||||
translation: "Về trang chủ"
|
||||
|
||||
- id: searchSuggestion
|
||||
translation: "Không có kết quả cho [SEARCH_TERM]. Thử các từ khoá: [DIFFERENT_TERMS]."
|
||||
|
||||
- id: altSearch
|
||||
translation: "Không có kết quả cho [SEARCH_TERM]. Đang hiển thị kết quả cho [DIFFERENT_TERM]."
|
||||
|
||||
- id: searchDisabled
|
||||
translation: "Tìm kiếm hiện không khả dụng trên trang này."
|
||||
|
||||
- id: skipToContent
|
||||
translation: "Đến nội dung chính"
|
||||
|
||||
- id: relatedPosts
|
||||
translation: "Bài viết liên quan"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{{- /*
|
||||
Blockquote render hook with native Markdown callout support (Hugo 0.140+).
|
||||
Markdown:
|
||||
> [!note] Optional title
|
||||
> Body content here.
|
||||
Renders to a styled callout. Plain blockquotes pass through unchanged.
|
||||
Supported alert types: note, tip, important, warning, caution.
|
||||
*/ -}}
|
||||
{{- if eq .Type "alert" -}}
|
||||
{{- $type := .AlertType | lower -}}
|
||||
{{- $title := .AlertTitle -}}
|
||||
{{- if not $title -}}
|
||||
{{- $title = i18n (printf "callout%s" ($type | title)) | default ($type | title) -}}
|
||||
{{- end -}}
|
||||
<blockquote class="callout callout-{{ $type }}">
|
||||
<p class="callout-title">{{ $title }}</p>
|
||||
{{ .Text }}
|
||||
</blockquote>
|
||||
{{- else -}}
|
||||
<blockquote
|
||||
{{- range $k, $v := .Attributes }} {{ $k }}="{{ $v }}"{{ end -}}
|
||||
>
|
||||
{{ .Text }}
|
||||
</blockquote>
|
||||
{{- end -}}
|
||||
Reference in New Issue
Block a user