Fix README gaps: author-profile files, tag registry, search accuracy (AI)

author-profile.css/html and cmjs/blog-config/tags.json existed and
were used but were undocumented. Also fixes the search feature
description (it already matched tags, not just title/description/
author) and adds a tag-filtering bullet to match the routing table.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AXSVPS3UmmASiiprPfcnUd
This commit is contained in:
biosiasandClaude Sonnet 5 committed 2026-09-11 12:41:41 +02:00
1 parent 84f21956fa
commit 601f2902f5
1 file changed
+38 -11
+38 -11
View File
@@ -13,15 +13,17 @@ A minimal CMS where articles are Markdown files rendered in the browser. No buil
## Features
- **Dark mode** — automatically follows the OS `prefers-color-scheme` setting; no toggle needed.
- **Client-side search** — the search box in the header filters all articles by title, description, author, and category in-memory. Navigates to `#search/query` so results are bookmarkable.
- **Client-side search** — the search box in the header filters all articles by title, description, author, category, and tags in-memory. Navigates to `#search/query` so results are bookmarkable.
- **Reading time** — estimated from the article word count (200 wpm) and shown on list cards and in article headers. Computed automatically; no frontmatter field needed.
- **Table of contents** — auto-generated from `h2`/`h3` headings and inserted at the top of the article body. Only appears when the article has three or more headings.
- **Back link** — a "← Back to articles" link above every article for one-click navigation back to the list.
- **Pagination** — article list paginates at 20 articles per page; page state is encoded in the hash so browser history works.
- **Author and category filtering** — clicking an author name or category badge shows a filtered list. Both support pagination.
- **Author, category, and tag filtering** — clicking an author name, category badge, or tag pill shows a filtered list. All three support pagination.
- **Responsive layout** — layout, cards, images, and pagination all adapt to narrow screens (breakpoint at 640 px).
- **Keyboard navigation** — all interactive elements have visible `:focus-visible` outlines for keyboard users.
- **Author profiles** — a profile card with bio and social links is shown at the top of each author's article list. Created by adding `articles/{author}/{author}.md`.
- **Offline-friendly caching** — discovered articles are cached in IndexedDB, so repeat visits skip re-fetching content that hasn't changed.
- **Translatable UI** — every UI string is looked up from a locale JSON file (English, Czech, and Slovak ship by default); adding a language needs no code changes.
## Project structure
@@ -38,11 +40,12 @@ cmjs/
└── cmjs/ # App content — articles, templates, component styles
├── css/
│ └── components/
│ ├── card.css # Article list cards and filter heading
│ ├── article.css # Single article view, back link, hero image
│ ├── content.css # Rendered markdown styles (.content *)
│ ├── pagination.css # Prev/next page navigation
│ └── toc.css # Auto-generated table of contents
│ ├── card.css # Article list cards and filter heading
│ ├── article.css # Single article view, back link, hero image
│ ├── content.css # Rendered markdown styles (.content *)
│ ├── pagination.css # Prev/next page navigation
│ ├── toc.css # Auto-generated table of contents
│ └── author-profile.css # Author profile card (avatar, bio, social links)
├── js/
│ ├── config.js # BASE_URL, MARKED_URL, PICTURES_URL (all via import.meta.url)
│ ├── frontmatter.js # parseFrontmatter() — pure YAML-front parser
@@ -58,8 +61,11 @@ cmjs/
│ ├── cs.json # Czech translation
│ └── sk.json # Slovak translation
├── templates/
│ ├── card.html # Article list card layout
│ └── article.html # Full article view layout
│ ├── card.html # Article list card layout
│ ├── article.html # Full article view layout
│ └── author-profile.html # Author profile card layout
├── blog-config/
│ └── tags.json # Tag id → human-readable label registry — see "Tag labels" below
├── articles/
│ └── author/ # One directory per author
│ ├── author.md # Author profile (optional)
@@ -87,6 +93,24 @@ cmjs/
`author` is derived from the directory path — no frontmatter field needed for it. Publish date,
tags, and category are derived from the `.date`/`.tag` marker files, not frontmatter.
### Tag labels
A `.tag` marker's filename is just an id (e.g. `kometa`) — the human-readable label shown in
the sidebar and on tag pills comes from `cmjs/blog-config/tags.json`:
```json
{
"schemaVersion": 1,
"tags": [
{ "id": "kometa", "label": "Comet", "description": "", "aliases": [], "active": true }
]
}
```
Registering an id here is optional — an unregistered tag id still works, it just displays as
its raw id instead of a friendly label. `expa-YYYY` year ids don't need to be registered here;
they're recognised automatically by pattern and don't use this label registry.
### Frontmatter format
```yaml
@@ -163,10 +187,12 @@ Author names and category tags on each card and article are clickable links to t
## Customising the layout
The HTML structure for the article list card and the full article view live in `cmjs/templates/`:
The HTML structure for the article list card, the full article view, and the author profile
card live in `cmjs/templates/`:
- `cmjs/templates/card.html` — the card shown in the article list
- `cmjs/templates/article.html` — the full article view (header, hero image, content)
- `cmjs/templates/author-profile.html` — the profile card (avatar, bio, social links)
Edit these files directly to change layout — no JS changes needed. Elements are identified by `data-field` attributes, which is how the JS modules find and populate them. Keep existing `data-field` values when rearranging; add new ones if you add new fields.
@@ -214,9 +240,10 @@ To add cmjs to any HTML page, three things are needed: the CSS, the two mount-po
<link rel="stylesheet" href="cmjs/css/components/content.css">
<link rel="stylesheet" href="cmjs/css/components/pagination.css">
<link rel="stylesheet" href="cmjs/css/components/toc.css">
<link rel="stylesheet" href="cmjs/css/components/author-profile.css">
```
The site-level CSS files (`reset.css`, `header.css`, `layout.css`) are optional — they style the shell around the CMS. If your page already has a layout and reset, you can skip them and only load the component stylesheets. Note that `reset.css` also defines the CSS custom properties (colours, radius) used throughout — if you skip it, define the variables yourself.
The site-level CSS files (`reset.css`, `header.css`, `layout.css`) are optional — they style the shell around the CMS. If your page already has a layout and reset, you can skip them and only load the component stylesheets. Note that `reset.css` also defines the CSS custom properties (colours, radius) used throughout — if you skip it, define the variables yourself. `author-profile.css` is only needed if any of your authors have a profile file (see "Author profiles" above) — safe to skip otherwise.
### 2. Mount points — in `<body>`