feat(tags): Add tag archive route and admin interface integration
Implement Phase 3 of v1.3.0 tags feature per microformats-tags-design.md: Routes (starpunk/routes/public.py): - Add /tag/<tag> archive route with normalization and 404 handling - Pre-load tags in index route for all notes - Pre-load tags in note route for individual notes Admin (starpunk/routes/admin.py): - Parse comma-separated tag input in create route - Parse tag input in update route - Pre-load tags when displaying edit form - Empty tag field removes all tags Templates: - Add tag input field to templates/admin/edit.html - Add tag input field to templates/admin/new.html - Use Jinja2 map filter to display existing tags Implementation details: - Tag URL parameter normalized to lowercase before lookup - Tags pre-loaded using object.__setattr__ pattern (like media) - parse_tag_input() handles trim, dedupe, normalization - All existing tests pass (micropub categories, admin routes) Per architect design: - No pagination on tag archives (acceptable for v1.3.0) - No autocomplete in admin (out of scope) - Follows existing media loading patterns Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
154
docs/projectplan/v1.3.1/RELEASE.md
Normal file
154
docs/projectplan/v1.3.1/RELEASE.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# StarPunk v1.3.1 Release
|
||||
|
||||
**Status**: Planning
|
||||
**Codename**: "Syndicate Tags"
|
||||
**Focus**: Feed Categories/Tags Support
|
||||
|
||||
## Overview
|
||||
|
||||
This patch release adds tags/categories support to all three syndication feed formats (RSS 2.0, Atom 1.0, JSON Feed 1.1). Tags were added to the backend in v1.3.0 but are not currently included in feed output.
|
||||
|
||||
## Features
|
||||
|
||||
### Feed Categories/Tags Support
|
||||
|
||||
Add tag/category elements to all syndication feeds, enabling feed readers and aggregators to categorize and filter content by topic.
|
||||
|
||||
#### RSS 2.0 Categories
|
||||
- Add `<category>` elements for each tag on a note
|
||||
- Use `display_name` as element content for human readability
|
||||
- Optional: Consider using normalized `name` as `domain` attribute for taxonomy identification
|
||||
- Multiple `<category>` elements per item (one per tag)
|
||||
- Reference: RSS 2.0 Specification (www.rssboard.org)
|
||||
|
||||
**Example:**
|
||||
```xml
|
||||
<item>
|
||||
<title>My Post</title>
|
||||
<category>Machine Learning</category>
|
||||
<category>Python</category>
|
||||
</item>
|
||||
```
|
||||
|
||||
#### Atom 1.0 Categories
|
||||
- Add `<category>` elements with RFC 4287 compliance
|
||||
- Required: `term` attribute (normalized tag name for machine processing)
|
||||
- Optional: `label` attribute (display name for human readability)
|
||||
- Optional: Consider `scheme` attribute for taxonomy URI
|
||||
- Multiple `<category>` elements per entry (one per tag)
|
||||
- Reference: RFC 4287 Section 4.2.2
|
||||
|
||||
**Example:**
|
||||
```xml
|
||||
<entry>
|
||||
<title>My Post</title>
|
||||
<category term="machine-learning" label="Machine Learning"/>
|
||||
<category term="python" label="Python"/>
|
||||
</entry>
|
||||
```
|
||||
|
||||
#### JSON Feed 1.1 Tags
|
||||
- Add `tags` array to each item object
|
||||
- Array contains `display_name` strings (human-readable)
|
||||
- Empty array or omit field if no tags
|
||||
- Reference: JSON Feed 1.1 Specification (jsonfeed.org)
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"items": [{
|
||||
"title": "My Post",
|
||||
"tags": ["Machine Learning", "Python"]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Scope
|
||||
|
||||
### In Scope
|
||||
- RSS feed category elements (`starpunk/feeds/rss.py`)
|
||||
- Atom feed category elements (`starpunk/feeds/atom.py`)
|
||||
- JSON Feed tags array (`starpunk/feeds/json_feed.py`)
|
||||
- Load tags in feed generation routes (`starpunk/routes/public.py`)
|
||||
- Unit tests for each feed format with tags
|
||||
- Integration tests for feed generation with tagged notes
|
||||
|
||||
### Out of Scope (Deferred)
|
||||
- Tag-filtered feeds (e.g., `/feed.rss?tag=python`) - consider for v1.4.0
|
||||
- Tag cloud/list in feeds - not part of feed specs
|
||||
- Category hierarchy/taxonomy URIs - keep simple for v1
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Tag Data Loading
|
||||
Notes are already loaded with `include_tags=True` capability in the model. Feed routes need to ensure tags are loaded when fetching notes:
|
||||
- Check if `get_note_tags()` is called or if notes have `.tags` populated
|
||||
- Pass tags to feed generation functions
|
||||
|
||||
### Feed Generator Changes
|
||||
Each feed module needs modification to accept and render tags:
|
||||
|
||||
1. **RSS (`generate_rss()` / `generate_rss_streaming()`):**
|
||||
- Accept tags from note object
|
||||
- Insert `<category>` elements after description/enclosure
|
||||
|
||||
2. **Atom (`generate_atom()` / `generate_atom_streaming()`):**
|
||||
- Accept tags from note object
|
||||
- Insert `<category term="..." label="..."/>` elements
|
||||
|
||||
3. **JSON Feed (`_build_item_object()`):**
|
||||
- Accept tags from note object
|
||||
- Add `"tags": [...]` array to item object
|
||||
|
||||
### Backward Compatibility
|
||||
- Tags are optional in all three feed specs
|
||||
- Notes without tags will simply have no category/tags elements
|
||||
- No breaking changes to existing feed consumers
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Unit Tests
|
||||
- RSS: Notes with tags generate correct `<category>` elements
|
||||
- RSS: Notes without tags have no `<category>` elements
|
||||
- RSS: Multiple tags generate multiple `<category>` elements
|
||||
- Atom: Notes with tags generate correct `<category>` elements with term/label
|
||||
- Atom: Notes without tags have no `<category>` elements
|
||||
- JSON Feed: Notes with tags have `tags` array
|
||||
- JSON Feed: Notes without tags have empty array or no `tags` field
|
||||
|
||||
### Integration Tests
|
||||
- Full feed generation with mix of tagged and untagged notes
|
||||
- Feed validation against format specifications
|
||||
- Streaming feed generation with tags
|
||||
|
||||
## Dependencies
|
||||
|
||||
- v1.3.0 tags feature must be complete (database + backend)
|
||||
- No new external dependencies required
|
||||
|
||||
## Estimated Effort
|
||||
|
||||
- Small patch release (1-2 hours implementation)
|
||||
- Focused scope: feed modifications only
|
||||
- Well-defined specifications to follow
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. All three feed formats include tags/categories when present
|
||||
2. Feed output validates against respective specifications
|
||||
3. Existing tests continue to pass
|
||||
4. New tests cover tag rendering in feeds
|
||||
5. No regression in feed generation performance
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- `docs/architecture/syndication-architecture.md` - Feed architecture overview
|
||||
- `docs/design/v1.3.0/microformats-tags-design.md` - Tags feature design
|
||||
- ADR-014: RSS Feed Implementation
|
||||
- ADR-059: Full Feed Media Standardization (future media enhancements)
|
||||
|
||||
## Standards References
|
||||
|
||||
- [RSS 2.0 Specification - category element](https://www.rssboard.org/rss-specification#ltcategorygtSubelementOfLtitemgt)
|
||||
- [RFC 4287 - Atom Syndication Format](https://datatracker.ietf.org/doc/html/rfc4287) (Section 4.2.2 for category)
|
||||
- [JSON Feed 1.1 Specification](https://www.jsonfeed.org/version/1.1/) (tags field)
|
||||
Reference in New Issue
Block a user