Add Zola skill documentation and Solid.js reference; update spec.md with i18n note

This commit is contained in:
Hananoshika Yomaru 2026-05-18 23:00:06 -07:00
parent 9db231b18e
commit 3e6c53b928
4 changed files with 219 additions and 1 deletions

View file

@ -0,0 +1,79 @@
---
name: zola
description: >-
Build and maintain the Open Free Books static site with Zola (Tera templates,
Sass, content/, data/, theme) and Solid.js frontend. Use when editing zola.toml,
content/, themes/openfreebooks/templates/, Sass, static assets, frontend/src/,
bundle.js, or running zola build/serve.
---
# Zola (Open Free Books)
Static site: **Zola** + custom theme `openfreebooks`. Output goes to `public/` (gitignored). Deploy via Wrangler from `public/`.
## Layout
| Path | Role |
|------|------|
| `zola.toml` | Site config, `[extra]` URLs for templates |
| `content/` | Pages (`*.md` + front matter, `template = "…"`) |
| `data/` | JSON for `load_data()` (contributors, credits) |
| `static/` | Copied to site root (`favicons`, `icons/`, etc.) |
| `themes/openfreebooks/templates/` | Tera HTML, partials, macros |
| `themes/openfreebooks/sass/` | Source styles → compiled `public/main.css` |
| `themes/openfreebooks/static/` | **Only** committed build artifact: `js/bundle.js` |
See [reference.md](reference.md) for Tera pitfalls and build checks.
## Commands
```bash
bun run build:js # Vite → themes/openfreebooks/static/js/bundle.js
zola serve # dev at http://127.0.0.1:1111
bun run build # build:js + zola build → public/
```
After Sass or template changes, run `zola build` (or `zola serve`). Do **not** copy `public/` into `themes/openfreebooks/static/`.
## Templates (Tera)
- Extend `base.html`; use `{% block content %}` for page bodies.
- **`{% import "macros/….html" as ns %}`** only in templates that **extend** a layout (e.g. `index.html`), **not** inside `{% include %}` partials.
- Macro calls use **keyword arguments**: `{{ ns::macro_name(arg=value) }}`.
- Prefer **partials** under `templates/partials/`; kebab-case filenames.
- Icons: Tabler SVGs in `static/icons/social/`; inline copies in `templates/partials/icons/social/*.html` included from `macros/social-icons.html`.
## Data files
```tera
{% set data = load_data(path="data/contributors.json", format="json") %}
```
On Zola 0.22+, use the `data/…` path (not bare `contributors.json` at repo root).
## New page checklist
1. Add `content/your-page.md` with `title`, `template = "your-template.html"`.
2. Add `themes/openfreebooks/templates/your-template.html` extending `base.html`.
3. Add Sass in `themes/openfreebooks/sass/` and `@import` in `main.scss`.
4. Wire footer/nav URLs in `zola.toml` `[extra]` if needed.
## Styling
- No inline Tailwind; use Sass partials and `class=""` on elements.
- Design tokens in `_tokens.scss`; section patterns in `_components.scss`, `_why-sections.scss`, etc.
- Grain overlay and dark mode via `data-theme` + CSS variables.
## Solid.js
Client behavior (header, marquee, scroll reveal, dialogs, theme toggle) lives in `frontend/` and mounts from `base.html` via `js/bundle.js`.
**When changing `frontend/` or adding interactivity**, read [zola-solid.md](zola-solid.md) before editing JS.
## Verify
```bash
bun run build
```
Confirm `public/main.css` contains new selectors (no stale `themes/openfreebooks/static/main.css` overriding compile). Confirm HTML under `public/` matches templates, not an old `themes/openfreebooks/static/index.html`.

View file

@ -0,0 +1,54 @@
# Zola reference (Open Free Books)
## `zola.toml` extras
```toml
[extra]
site_title = "Open Free Books"
github_url = "https://github.com/hananoshikayomaru/openfreebooks"
browse_url = "/browse/"
about_url = "/about/"
credits_url = "/credits/"
```
Injected into templates and `#site-config` JSON for Solid (see zola-solid subskill).
## Homepage vs sections
- Homepage: `content/_index.md` with `template = "index.html"`.
- Other pages: e.g. `content/credits.md` with `template = "credits.html"`.
- Shared why blocks: `partials/why-sections.html`; community block: `partials/community-section.html`.
## Common Tera errors
| Error | Fix |
|-------|-----|
| `unexpected tag` on `{% import %}` in partial | Move `{% import %}` to parent template (e.g. `index.html`) before `{% include %}` |
| `expected a keyword argument` in macro | Use `{{ macro::name(param=value) }}` |
| `load_data` file not found | Path must be `data/file.json` on Zola 0.22+ |
## Theme `static/` hazard
Zola merges `themes/openfreebooks/static/` **over** generated assets. If `main.css` or `index.html` appear there, they **override** compiled Sass and the real homepage.
**Allowed in theme static:** `js/bundle.js` only (see `.gitignore`).
If styles “don’t apply”, delete stray `themes/openfreebooks/static/main.css` and rebuild.
## Sass pipeline
`themes/openfreebooks/sass/main.scss` imports partials; Zola writes `public/main.css`. Never commit compiled CSS into theme `static/`.
## Credits / contributors pattern
- `data/contributors.json` + `data/credits.json` — source of truth.
- `static/contributors.json` — optional mirror for `/contributors.json` if needed.
- Contributors UI: `partials/contributors-block.html`; credits page: `credits.html` + `partials/credits-content.html`.
## Social icons
1. Source SVGs: `static/icons/social/{kind}.svg` (from [Tabler Icons](https://tabler.io/icons) outline set).
2. Template partials: `templates/partials/icons/social/{kind}.html` (normalized `currentColor`, 20×20).
3. Macro router: `templates/macros/social-icons.html`.
Regenerate partials after updating raw SVGs if stroke/size should stay consistent.

View file

@ -0,0 +1,83 @@
# Solid.js + Vite (Open Free Books)
Reference for client-side work in this Zola repo. Read this when editing `frontend/`, `bundle.js`, or adding interactivity.
## Stack
| Piece | Location |
|-------|----------|
| Source | `frontend/src/` (functional Solid components) |
| Entry | `frontend/src/main.tsx` |
| Build | Vite + `vite-plugin-solid` |
| Output | `themes/openfreebooks/static/js/bundle.js` |
| Loaded in | `themes/openfreebooks/templates/base.html` (`defer`) |
Package manager: **Bun** (`bun install`, `bun run build:js`).
## Config bridge (Zola → Solid)
`base.html` embeds JSON:
```html
<script id="site-config" type="application/json">…</script>
```
`main.tsx` reads it via `readConfig()` for brand, `homeUrl`, `browseUrl`, `aboutUrl`, `githubUrl`. Add new global URLs in **`zola.toml` `[extra]`** and mirror in `base.html` + `readConfig()` types.
## Mount points
| ID / target | Component | Role |
|-------------|-----------|------|
| `#site-header` | `SiteHeader` | Nav + theme toggle |
| `#marquee` | `Marquee` | Homepage quote strip |
| `document.body` | `ScrollRevealBootstrap` | `[data-scroll-reveal-card]` |
| `document.body` | `ContributorsDialogBootstrap` | `<dialog>` for contributors |
| `#footer-year` | `mountFooterYear()` | Copyright year |
Prefer **bootstrap** components that `querySelector` existing markup over re-rendering large HTML regions in Solid.
## Conventions
- **Functional** components only; no class components.
- **No mocks** in Vitest unless the user asks for tests.
- Keep bundles small: mount only what’s needed.
- Styles stay in **Sass** (`themes/openfreebooks/sass/`); use `className` with existing classes, not inline Tailwind.
- Scroll reveal: stagger **per section** (`[data-scroll-reveal]` group), not global index; reveal in-viewport items immediately on load (`scroll-reveal.tsx`).
## Vite config
- `outDir`: `themes/openfreebooks/static`
- `emptyOutDir: false` — do not wipe theme static (only add `js/bundle.js`)
- Single entry: `frontend/src/main.tsx` → `js/bundle.js`
## Workflow
1. Edit `frontend/src/…`.
2. Run `bun run build:js` (or `bun run dev:js` while `zola serve` runs).
3. Hard-refresh browser.
4. For production: `bun run build` then `wrangler deploy`.
## Adding a feature
1. Add mount root in Tera template (empty `<div id="…">` or use existing).
2. Create `frontend/src/components/your-feature.tsx`.
3. Import and `render()` in `main.tsx` (or extend a bootstrap).
4. Add Sass if new UI.
## Dialogs
Contributor modals use native `<dialog>` + `showModal()` in `contributors-dialog.tsx`. Markup lives in `partials/contributors-block.html`.
## Do not
- Commit generated `main.css` or `index.html` under `themes/openfreebooks/static/`.
- Use `emptyOutDir: true` in Vite without restoring allowed theme static files.
## Verify
```bash
bun run build:js
zola build
```
Check `themes/openfreebooks/static/js/bundle.js` updated; hard-refresh if behavior looks stale.

View file

@ -6,4 +6,6 @@ this project is build using zola. interactivity by solid js. deployed to cloudfl
canvas feature use [jsoncanvas](https://jsoncanvas.org/spec/1.0/) standard by Obsidian. Viewer is [JSON canvas viewer](https://github.com/Hesprs/JSON-Canvas-Viewer).
not markdown, html based. but in every page, we should have a copy as md button using [defuddle](https://github.com/kepano/defuddle).
not markdown, html based. but in every page, we should have a copy as md button using [defuddle](https://github.com/kepano/defuddle).
we don't i18n. i18n will be solved in future by big companies.