Implements tag/category system backend following microformats2 p-category specification. Database changes: - Migration 008: Add tags and note_tags tables - Normalized tag storage (case-insensitive lookup, display name preserved) - Indexes for performance New module: - starpunk/tags.py: Tag management functions - normalize_tag: Normalize tag strings - get_or_create_tag: Get or create tag records - add_tags_to_note: Associate tags with notes (replaces existing) - get_note_tags: Retrieve note tags (alphabetically ordered) - get_tag_by_name: Lookup tag by normalized name - get_notes_by_tag: Get all notes with specific tag - parse_tag_input: Parse comma-separated tag input Model updates: - Note.tags property (lazy-loaded, prefer pre-loading in routes) - Note.to_dict() add include_tags parameter CRUD updates: - create_note() accepts tags parameter - update_note() accepts tags parameter (None = no change, [] = remove all) Micropub integration: - Pass tags to create_note() (tags already extracted by extract_tags()) - Return tags in q=source response Per design doc: docs/design/v1.3.0/microformats-tags-design.md Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
4.8 KiB
Caption Display Update - Alt Text Only (v1.1.2)
Status
Superseded by media-display-fixes.md
This document contains an earlier approach to caption handling. The authoritative specification is now in media-display-fixes.md which provides a complete solution for media display including caption handling, CSS constraints, and homepage media.
Context
User has clarified that media captions should be used as alt text only, not displayed as visible <figcaption> elements in the note body.
Decision
Remove all visible caption display from templates while maintaining caption data for accessibility (alt text) purposes.
Required Changes
1. CSS Updates
File: /home/phil/Projects/starpunk/static/css/style.css
Remove: Lines related to figcaption styling (line 17 in the media CSS section)
/* REMOVE THIS LINE */
.note-media figcaption, .e-content figcaption { margin-top: var(--spacing-sm); font-size: 0.875rem; color: var(--color-text-light); font-style: italic; }
The remaining CSS should be:
/* Media Display Styles (v1.2.0) - Updated for alt-text only captions */
.note-media { margin-bottom: var(--spacing-md); }
.note-media img, .e-content img, .u-photo { max-width: 100%; height: auto; display: block; border-radius: var(--border-radius); }
/* Multiple media items grid */
.note-media { display: flex; flex-wrap: wrap; gap: var(--spacing-md); }
.note-media .media-item { flex: 1 1 100%; }
/* Desktop: side-by-side for multiple images */
@media (min-width: 768px) {
.note-media .media-item:only-child { flex: 1 1 100%; }
.note-media .media-item:not(:only-child) { flex: 1 1 calc(50% - var(--spacing-sm)); }
}
2. Template Updates
File: /home/phil/Projects/starpunk/templates/note.html
Change: Lines 17-29 - Simplify media display structure
From:
{% if note.media %}
<div class="note-media">
{% for item in note.media %}
<figure class="media-item">
<img src="{{ url_for('public.media_file', path=item.path) }}"
alt="{{ item.caption or 'Image' }}"
class="u-photo"
width="{{ item.width }}"
height="{{ item.height }}">
{% if item.caption %}
<figcaption>{{ item.caption }}</figcaption>
{% endif %}
</figure>
{% endfor %}
</div>
{% endif %}
To:
{% if note.media %}
<div class="note-media">
{% for item in note.media %}
<div class="media-item">
<img src="{{ url_for('public.media_file', path=item.path) }}"
alt="{{ item.caption or 'Image' }}"
class="u-photo"
width="{{ item.width }}"
height="{{ item.height }}">
</div>
{% endfor %}
</div>
{% endif %}
Changes:
- Replace
<figure>with<div>(simpler, no semantic figure/caption relationship) - Remove the
{% if item.caption %}block and<figcaption>element entirely - Keep caption in
altattribute for accessibility
File: /home/phil/Projects/starpunk/templates/index.html
Status: No changes needed
- Index template doesn't display media items in the preview
- Only shows truncated content
3. Feed Generators
Status: No changes needed
The feed generators already handle captions correctly:
- RSS, ATOM, and JSON Feed all use captions as alt text in
<img>tags - JSON Feed also includes captions in attachment metadata (correct behavior)
Current implementation (correct):
# In all feed generators
caption = media_item.get('caption', '')
content_html += f'<img src="{media_url}" alt="{caption}" />'
Rationale
- Simplicity: Removing visible captions reduces visual clutter
- Accessibility: Alt text provides necessary context for screen readers
- User Intent: Captions are metadata, not content to be displayed
- Clean Design: Images speak for themselves without redundant text
Implementation Checklist
- Update CSS to remove figcaption styles
- Update note.html template to remove figcaption elements
- Test with images that have captions
- Test with images without captions
- Verify alt text is properly set
- Test responsive layout still works
- Verify feed output unchanged
Testing Requirements
-
Visual Testing:
- Confirm no caption text appears below images
- Verify image layout unchanged
- Test responsive behavior on mobile/desktop
-
Accessibility Testing:
- Inspect HTML to confirm alt attributes are set
- Test with screen reader to verify alt text is announced
-
Feed Testing:
- Verify RSS/ATOM/JSON feeds still include alt text
- Confirm JSON Feed attachments retain title field
Standards Compliance
- HTML: Valid use of img alt attribute
- Accessibility: WCAG 2.1 Level A compliance for images
- IndieWeb: Maintains u-photo microformat class
- Progressive Enhancement: Images functional without CSS