mirror of
https://github.com/tiennm99/bonsai.git
synced 2026-09-02 18:18:37 +00:00
feat(theme): optional RSS feed of params.links
Closes #8. Opt-in via `params.rss = true` (off by default). When enabled: - layouts/index.rss.xml renders an RSS 2.0 feed of [[params.links]] at /index.xml — one <item> per link, pubDate = build time - head.html emits <link rel="alternate" type="application/rss+xml"> - Users must remove "RSS" from their disableKinds to let Hugo emit it Channel populated from params.{name,tagline,bio} and site.BaseURL. Item shape: <title> = link title, <link> = link URL, <guid isPermaLink="false"> = bonsai-link-{url}, optional <description>. XML declaration uses safeHTML+printf to defeat Hugo's default escape (otherwise '<?xml ... ?>' becomes '<?xml ... ?>' and breaks parsers). exampleSite enables rss=true to demo the feature; verified output parses as valid XML via Python ElementTree.
This commit is contained in:
@@ -8,6 +8,7 @@ All notable changes to this project are documented here. Format follows [Keep a
|
||||
- **Favicon polish** — opt-in `params.faviconSvg` and `params.appleTouchIcon` for SVG and iOS home-screen icons. Default behavior unchanged when unset.
|
||||
- **Demo-only gallery CSS** — `/themes/` and `/variants/` pages load a separate `static/css/gallery.css`; `static/css/bonsai.css` no longer ships gallery selectors to user sites. Saves ~1.9 KB raw / ~200 B gzipped on every real site. New `head_extra` block in `baseof.html` enables per-page stylesheet additions.
|
||||
- **10 new icons** — set grows from 35 to 45. Brand additions: `bandcamp`, `soundcloud`, `spotify`, `figma`, `dribbble`, `stackoverflow`, `matrix`. Utility additions: `bookopen`, `download`, `heart`. Vendored from Simple Icons v13 (CC0) and Lucide v0.460 (ISC) at the same versions; soft ceiling for v0-line is ~50.
|
||||
- **Optional RSS feed** — opt-in `params.rss = true` renders an RSS 2.0 feed of `[[params.links]]` at `/index.xml` and emits `<link rel="alternate">` in `<head>`. Requires removing `RSS` from `disableKinds`. `pubDate` = build time. Off by default; existing sites unaffected.
|
||||
|
||||
### Changed
|
||||
- **A11y** — sakura accent darkened `#d4456a → #c93f63` (4.04 → 4.49 vs bg) and koi accent darkened `#c8521e → #bd4c1c` (4.17 → 4.63 vs bg) to reach WCAG AA on the gallery accent chip. Brand intent preserved (cherry blossom pink / koi orange). README hex table synced.
|
||||
|
||||
@@ -97,6 +97,7 @@ disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"]
|
||||
| `colorTheme` | string | `bonsai` | Palette: `bonsai`, `sakura`, `sumi`, or `koi`. See [Color themes](#color-themes). |
|
||||
| `layout` | string | `stack` | Link arrangement: `stack`, `grid`, or `inline`. See [Layout variants](#layout-variants). |
|
||||
| `themeToggle` | bool | `false` | Render a sun/moon button in the footer + load the toggle script. |
|
||||
| `rss` | bool | `false` | Render an RSS 2.0 feed of `[[params.links]]` at `/index.xml` and emit `<link rel="alternate">` in `<head>`. Requires removing `RSS` from `disableKinds`. |
|
||||
| `ogImage` | bool | `true` | Set `false` to suppress all `og:image` / `twitter:image` tags. |
|
||||
| `ogImageUrl` | string (URL) | — | Explicit OG preview image (1200×630 recommended). Overrides the avatar fallback and upgrades Twitter card to `summary_large_image`. |
|
||||
| `schema` | bool | `true` | Emit schema.org `Person` JSON-LD in `<head>`. Set `false` if you provide your own. |
|
||||
@@ -140,6 +141,20 @@ Three arrangements for `[[params.links]]`. Pick one via `layout` in `[params]`:
|
||||
|
||||
Live preview: **[tiennm99.github.io/bonsai/variants/](https://tiennm99.github.io/bonsai/variants/)**.
|
||||
|
||||
## RSS feed (opt-in)
|
||||
|
||||
Off by default. To enable a feed of your `[[params.links]]` at `/index.xml`:
|
||||
|
||||
```toml
|
||||
# remove "RSS" from disableKinds — Hugo emits it by default but the theme suggests disabling it
|
||||
disableKinds = ["taxonomy", "term", "sitemap", "404"]
|
||||
|
||||
[params]
|
||||
rss = true
|
||||
```
|
||||
|
||||
The theme renders one `<item>` per link. `pubDate` is the build time (links lack intrinsic dates), so the feed updates whenever the site rebuilds — fine for a curated bio, less ideal for high-frequency feeds.
|
||||
|
||||
## i18n
|
||||
|
||||
Theme-rendered strings (nav landmark, theme-toggle labels, default footer) live in `i18n/{lang}.toml`. Bundles for `en` and `vi` ship with the theme.
|
||||
|
||||
@@ -3,8 +3,9 @@ languageCode = "en-us"
|
||||
title = "Tien Nguyen"
|
||||
theme = "bonsai"
|
||||
|
||||
# Bonsai is a single-page bio theme — no need for taxonomies, sitemaps, or RSS.
|
||||
disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"]
|
||||
# Bonsai is a single-page bio theme — taxonomies/sitemaps off; RSS on for the
|
||||
# v0.4 demo (set params.rss = true and remove "RSS" from disableKinds).
|
||||
disableKinds = ["taxonomy", "term", "sitemap", "404"]
|
||||
|
||||
[params]
|
||||
name = "Tien Nguyen"
|
||||
@@ -15,6 +16,7 @@ disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"]
|
||||
colorTheme = "sakura" # try "bonsai" (default), "sakura", "sumi", "koi"
|
||||
layout = "grid" # try "stack" (default), "grid", "inline"
|
||||
themeToggle = true
|
||||
rss = true # opt-in RSS feed of [[params.links]]
|
||||
jobTitle = "Software Engineer"
|
||||
footerText = "© 2026 · made with bonsai"
|
||||
# ogImageUrl = "/og.png" # optional 1200×630 image for social previews
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{{- /* RSS 2.0 feed of [[params.links]].
|
||||
Only emitted when site.Params.rss is true AND user has removed `RSS`
|
||||
from disableKinds in their hugo.toml. */ -}}
|
||||
{{- if site.Params.rss -}}
|
||||
{{- $name := site.Params.name | default site.Title -}}
|
||||
{{- $tagline := site.Params.tagline | default "" -}}
|
||||
{{- $bio := site.Params.bio | default $tagline -}}
|
||||
{{- $now := now -}}
|
||||
{{ printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ $name | transform.XMLEscape }}{{ with $tagline }} — {{ . | transform.XMLEscape }}{{ end }}</title>
|
||||
<link>{{ site.BaseURL | absLangURL }}</link>
|
||||
<description>{{ $bio | transform.XMLEscape }}</description>
|
||||
<generator>Hugo + Bonsai</generator>
|
||||
<language>{{ site.Language.LanguageCode | default site.LanguageCode }}</language>
|
||||
<lastBuildDate>{{ $now.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
|
||||
<atom:link href="{{ "index.xml" | absURL }}" rel="self" type="application/rss+xml" />
|
||||
{{- range site.Params.links }}
|
||||
<item>
|
||||
<title>{{ .title | transform.XMLEscape }}</title>
|
||||
<link>{{ .url }}</link>
|
||||
<guid isPermaLink="false">bonsai-link-{{ .url }}</guid>
|
||||
<pubDate>{{ $now.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{- with .description }}
|
||||
<description>{{ . | transform.XMLEscape }}</description>
|
||||
{{- end }}
|
||||
</item>
|
||||
{{- end }}
|
||||
</channel>
|
||||
</rss>
|
||||
{{- end -}}
|
||||
@@ -46,6 +46,9 @@
|
||||
<link rel="apple-touch-icon" href="{{ . | strings.TrimPrefix "/" | relURL }}" />
|
||||
{{- end }}
|
||||
<link rel="stylesheet" href="{{ `css/bonsai.css` | relURL }}" />
|
||||
{{- if site.Params.rss }}
|
||||
<link rel="alternate" type="application/rss+xml" title="{{ site.Params.name | default site.Title }}" href="{{ `index.xml` | absURL }}" />
|
||||
{{- end }}
|
||||
{{- if site.Params.themeToggle }}
|
||||
{{- /* Inline blocking script (no FOUC): apply saved theme before first paint.
|
||||
Tiny (~140B) — meets the <3KB CSS / minimal-JS budget. */ -}}
|
||||
|
||||
Reference in New Issue
Block a user