Files
devplacepy/devplacepy/templates/_attachment_display.html
T
blindxfishandClaude Opus 5 24a79177e8 Show a post's image on its card, and show it full size
_attachment_display.html iterates a context variable named
`attachments`, so every caller binds it before the include.
_post_card.html was the one caller that did not: it guarded on
item.attachments but included the partial with nothing bound, so the
gallery looped over whatever `attachments` happened to be in the
surrounding page context and rendered empty. Every post with an image
looked image-less on the feed and on profiles, and on a project page -
where project_detail.html sets `attachments` at template scope for the
project's own files - a devlog card would have rendered the project's
files as its own.

With the image actually reaching the card, render a lone one properly:
a gallery holding exactly one item gets a `single` class and takes the
full content column (max-height 480px, object-fit contain, no hover
scale), matching the original DevPlace. That branch serves the stored
original rather than thumbnail_url, because a thumbnail is 200px on its
longest side and stretching it to the column width is visibly blurry.

Animated GIFs needed no change and now have a test proving it: they
never had a thumbnail to flatten, so they already took the original-file
path and simply render larger.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 23:12:39 +02:00

21 lines
1.2 KiB
HTML

{% set _single = attachments|length == 1 %}
<div class="attachment-gallery{% if _single %} single{% endif %}">
{% for att in attachments %}
<div class="attachment-gallery-item">
{% if att.get('is_image') %}
<img src="{{ att['url'] if _single or not att.get('thumbnail_url') else att['thumbnail_url'] }}" alt="{{ att.get('original_filename', '') }}" loading="lazy" class="gallery-thumb" data-lightbox data-full="{{ att['url'] }}" data-mime="{{ att.get('mime_type', '') }}">
{% elif att.get('is_video') %}
<video src="{{ att['url'] }}" controls preload="metadata" class="gallery-video"></video>
{% elif att.get('is_audio') %}
<audio src="{{ att['url'] }}" controls preload="metadata" class="gallery-audio"></audio>
{% else %}
<a href="{{ att['url'] }}" target="_blank" rel="noopener" class="non-image" download="{{ att.get('original_filename', 'file') }}">
<span class="icon">{{ file_icon_emoji(att.get('original_filename', 'file')) }}</span>
<span class="name">{{ att.get('original_filename', 'file') }}</span>
<span class="size">{{ format_file_size(att.get('file_size', 0)) }}</span>
</a>
{% endif %}
</div>
{% endfor %}
</div>