Tags: typed tags on poets, books, works and couplets; tag pages; tag: in search #65

Merged
anas merged 1 commits from feature/tags into main 2026-10-09 12:43:57 +00:00
Owner

Part of #52. Still to come in #52: tags on phrases and single words, and tags as a facet beside the author filter.

Tags

  • Typed tags: موضوع، صنف، بحر، شخصیت، مقام، دور and free ٹیگ.
  • What can be tagged: poets (their page), books and chapters, works, and a single couplet of a work (شعر n, counted from 1).

Moderation

  • ٹیگ button on poet, book/chapter and work pages for moderators with the new tags permission (ٹیگ in grants). Editing text does not give it.
  • Tagging is a revision of type tags-category or tags-work, going through the same L2 → L1 → admin pipeline with history (/mod/tags/<kind>/<id>). An unchanged draft is not kept.
  • The editor has one row per tag: where (the whole work or a couplet), type and name. Existing names are suggested, and each box has the Urdu keyboard and Roman typing. The diff and preview show the tags.

Publishing

  • Writes divan-data/divan/<url>.tags (beside the work's .dtx or the section's .order) and commits it. Removing the last tag deletes the file.
  • Updates the site's tags.
  • The import reloads every .tags file, so divan-data stays the record.

Reading

  • Tag chips under the title; couplet tags under their couplet.
  • /tag/<type>/<name> lists poets, books and works carrying the tag, with the tagged couplets' lines linked to the couplet.
  • /tags lists all tags by type; it is linked in the footer.

Search

  • tag:عشق or ٹیگ:عشق keeps works tagged on the work, a couplet or their book. Quotes work for names with spaces. Words can be combined with a tag.
  • With only a tag, the snippet is the tagged couplet.
  • Tags whose names match the words show as a ٹیگ group.

Also in this PR

  • Tests: test files now run one at a time, because they share Ghalib's ghazals; this caused the earlier intermittent failure. The library test now picks a ghazal with at least three couplets; the one it got by chance had two.
  • Button row: the moderation buttons on pages now sit in a div. A <form> closes a <p>, which pushed the new button onto its own line.

Tested

  • npm test: 40 pass. New tests cover:
    • parsing (types, couplets, Urdu digits, repeats, order);
    • permission: text editing ≠ tagging;
    • an unknown type, a missing couplet and a couplet tag on a section are refused;
    • L2 → L1 → admin publish of a work and a section;
    • the .tags file and commit;
    • the tag pages, including the couplet lines;
    • the import reload;
    • removing all tags deletes the file.
  • The tag search was checked against the API.
  • Headless Chrome as an L2 with a tags grant:
    • ٹیگ opens the editor;
    • a whole-work tag and a couplet-2 tag were added and saved; the preview and rows survive a reload;
    • the on-screen keyboard types into a new row;
    • chips appear on the page and under the couplet;
    • the tag page links to #c1;
    • ٹیگ:عشق finds the work;
    • the tags index works.
  • Not published from the browser, so as not to commit to the real divan-data. Test data removed.

Local setup: apply db/schema.sql (the import or dict-sync does it).

Noticed, not in this PR: for signed-in moderators at about 750px wide, the header links crowd the search box.

🤖 Generated with Claude Code

Part of #52. Still to come in #52: tags on phrases and single words, and tags as a facet beside the author filter. **Tags** - Typed tags: **موضوع، صنف، بحر، شخصیت، مقام، دور** and free **ٹیگ**. - What can be tagged: poets (their page), books and chapters, works, and a single couplet of a work (**شعر n**, counted from 1). **Moderation** - **ٹیگ** button on poet, book/chapter and work pages for moderators with the new **tags** permission (`ٹیگ` in grants). Editing text does not give it. - Tagging is a revision of type `tags-category` or `tags-work`, going through the same L2 → L1 → admin pipeline with history (`/mod/tags/<kind>/<id>`). An unchanged draft is not kept. - The editor has one row per tag: where (the whole work or a couplet), type and name. Existing names are suggested, and each box has the Urdu keyboard and Roman typing. The diff and preview show the tags. **Publishing** - Writes `divan-data/divan/<url>.tags` (beside the work's `.dtx` or the section's `.order`) and commits it. Removing the last tag deletes the file. - Updates the site's tags. - The import reloads every `.tags` file, so divan-data stays the record. **Reading** - Tag chips under the title; couplet tags under their couplet. - `/tag/<type>/<name>` lists poets, books and works carrying the tag, with the tagged couplets' lines linked to the couplet. - `/tags` lists all tags by type; it is linked in the footer. **Search** - `tag:عشق` or `ٹیگ:عشق` keeps works tagged on the work, a couplet or their book. Quotes work for names with spaces. Words can be combined with a tag. - With only a tag, the snippet is the tagged couplet. - Tags whose names match the words show as a **ٹیگ** group. **Also in this PR** - **Tests:** test files now run one at a time, because they share Ghalib's ghazals; this caused the earlier intermittent failure. The library test now picks a ghazal with at least three couplets; the one it got by chance had two. - **Button row:** the moderation buttons on pages now sit in a `div`. A `<form>` closes a `<p>`, which pushed the new button onto its own line. **Tested** - `npm test`: 40 pass. New tests cover: - parsing (types, couplets, Urdu digits, repeats, order); - permission: text editing ≠ tagging; - an unknown type, a missing couplet and a couplet tag on a section are refused; - L2 → L1 → admin publish of a work and a section; - the `.tags` file and commit; - the tag pages, including the couplet lines; - the import reload; - removing all tags deletes the file. - The tag search was checked against the API. - Headless Chrome as an L2 with a tags grant: - **ٹیگ** opens the editor; - a whole-work tag and a couplet-2 tag were added and saved; the preview and rows survive a reload; - the on-screen keyboard types into a new row; - chips appear on the page and under the couplet; - the tag page links to `#c1`; - `ٹیگ:عشق` finds the work; - the tags index works. - Not published from the browser, so as not to commit to the real divan-data. Test data removed. **Local setup:** apply `db/schema.sql` (the import or dict-sync does it). **Noticed, not in this PR:** for signed-in moderators at about 750px wide, the header links crowd the search box. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
anas added 1 commit 2026-10-09 12:42:39 +00:00
- Types موضوع، صنف، بحر، شخصیت، مقام، دور and free ٹیگ; a work's tag may be on one couplet (شعر n, from 1).
- Tagging is a revision (tags-category / tags-work) through the L2 -> L1 -> admin pipeline with the new 'tags'
  permission; publishing writes divan-data/divan/<url>.tags, commits it and updates the site; the import reloads them.
- Pages show tag chips (couplet tags under the couplet); /tag/<type>/<name> lists what carries a tag; /tags lists all.
- Search: tag:عشق / ٹیگ:"حب الوطنی" filters works (tagged work, couplet or book), matching tags shown as a group.
- Tag editor rows with suggestions, Urdu keyboard and Roman typing.
- Tests run one file at a time (they share Ghalib's ghazals); the library test picks a ghazal with three couplets.
- Mod buttons sit in a div (a form closes a p, which broke the row).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anas merged commit c2293f9794 into main 2026-10-09 12:43:57 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: anas/divan#65
No description provided.