Skip to content

Commit 0468f8a

Browse files
committed
Fix term-info download captions and thumbnail links to name the template
Downloads section said 'Image files aligned to <the term's own label>' instead of the template it's aligned to, because each Images/Examples entry's id/label describe the depicted term, not the template — e.g. https://virtualflybrain.org/blog/2022/01/01/1447201088-vfb_jrch06ly/ showed 'Image files aligned to 1447201088' twice, once per template, instead of naming JRC2018U and JRCFIB2018Fum. Add get_template_label(), a small cached lookup of each template's own Name, and use it for the download caption instead of the image's label. Thumbnails in the hero card had the same confusion in their alt text, and their links only ever opened the page's own term (?id=<id>), never the specific template + image shown — so clicking a thumbnail didn't open the 3D browser on that alignment. Give each thumbnail a fully descriptive alt ('<tags> <name> (<id>) aligned to <template>') and link to ?id=<id>&i=<template_id>,<image_id> so it opens on the right image.
1 parent 6b3bce9 commit 0468f8a

1 file changed

Lines changed: 55 additions & 7 deletions

File tree

‎vfbterms.py‎

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,23 +311,67 @@ def format_types_section(types_text):
311311

312312
# ─── Formatting Helpers ──────────────────────────────────────────────────────
313313

314+
# Cache of template_id -> the template's own display name (its top-level
315+
# "Name", e.g. "JRC2018U"). An Images/Examples entry's own "id"/"label"
316+
# describe the depicted individual or class instance, not the template it is
317+
# aligned to — so "aligned to <template>" text needs this separate lookup.
318+
# The handful of templates VFB uses are shared across every page, so a
319+
# process-wide cache keeps this to one extra request per template, not per page.
320+
_template_label_lock = threading.Lock()
321+
_template_label_cache = {}
322+
323+
def get_template_label(template_id):
324+
"""Resolve a template's own display name for 'aligned to <template>' text.
325+
326+
Falls back to the raw template_id if the lookup fails.
327+
"""
328+
with _template_label_lock:
329+
cached = _template_label_cache.get(template_id)
330+
if cached is not None:
331+
return cached
332+
label = template_id
333+
template_data = fetch_term_info(template_id)
334+
if template_data:
335+
label = template_data.get("Name", template_id)
336+
with _template_label_lock:
337+
_template_label_cache[template_id] = label
338+
return label
339+
314340
def get_thumbnails(term_data):
315341
"""Extract thumbnail URLs from Images (individuals) or Examples (classes).
316342
317-
Returns list of dicts: {url, label, template_id}
343+
Returns list of dicts: {url, alt, template_id, image_id}.
344+
345+
`alt` is a fully descriptive caption: "<tags> <name> (<id>) aligned to
346+
<template>". `image_id` is the specific depicted term — the page's own Id
347+
for an individual, a distinct instance Id for a class's Examples — and
348+
together with `template_id` builds the 3D-browser deep link in
349+
build_hero_card (?id=<page id>&i=<template_id>,<image_id>), so the
350+
thumbnail actually opens showing that image on that template.
318351
"""
319352
thumbnails = []
353+
term_id = term_data.get("Id", "")
354+
term_name = term_data.get("Name", "")
355+
tags_text = " ".join(t.replace("_", " ") for t in term_data.get("Tags", []))
356+
357+
def make_alt(label, image_id, template_id):
358+
template_label = get_template_label(template_id)
359+
caption = f'{label} ({image_id}) aligned to {template_label}'
360+
return f'{tags_text} {caption}' if tags_text else caption
320361

321362
# Individual terms have Images
322363
images = term_data.get("Images", {})
323364
if images:
324365
for template_id, image_list in images.items():
325366
for img in image_list:
326367
if img.get("thumbnail"):
368+
image_id = img.get("id", term_id)
369+
label = img.get("label", term_name)
327370
thumbnails.append({
328371
"url": img["thumbnail"],
329-
"label": img.get("label", term_data.get("Name", "")),
372+
"alt": make_alt(label, image_id, template_id),
330373
"template_id": template_id,
374+
"image_id": image_id,
331375
})
332376

333377
# Class terms have Examples
@@ -336,10 +380,13 @@ def get_thumbnails(term_data):
336380
for template_id, example_list in examples.items():
337381
for ex in example_list:
338382
if ex.get("thumbnail"):
383+
image_id = ex.get("id", term_id)
384+
label = ex.get("label", term_name)
339385
thumbnails.append({
340386
"url": ex["thumbnail"],
341-
"label": ex.get("label", term_data.get("Name", "")),
387+
"alt": make_alt(label, image_id, template_id),
342388
"template_id": template_id,
389+
"image_id": image_id,
343390
})
344391

345392
return thumbnails[:4] # Limit to 4
@@ -441,13 +488,13 @@ def format_downloads(images):
441488

442489
lines = []
443490
for template_id, image_list in images.items():
491+
template_label = get_template_label(template_id)
444492
for img in image_list:
445-
template_label = template_id
446493
has_downloads = any(img.get(k) for k in ("nrrd", "obj", "swc", "wlz"))
447494
if not has_downloads:
448495
continue
449496

450-
lines.append(f'Image files aligned to {img.get("label", template_label)}:')
497+
lines.append(f'Image files aligned to {template_label}:')
451498
lines.append("")
452499
if img.get("obj"):
453500
lines.append(f'- [Pointcloud (OBJ)]({img["obj"]})')
@@ -558,9 +605,10 @@ def build_hero_card(name, term_id, tags_badges, description_html, comment_html,
558605
]
559606

560607
for thumb in thumbnails:
608+
viewer_url = f'{VFB_BROWSER_BASE}?id={term_id}&i={thumb["template_id"]},{thumb["image_id"]}'
561609
lines.append(
562-
f' <a href="{VFB_BROWSER_BASE}?id={term_id}">'
563-
f'<img src="{thumb["url"]}" alt="{name}" class="img-fluid rounded" '
610+
f' <a href="{viewer_url}">'
611+
f'<img src="{thumb["url"]}" alt="{thumb["alt"]}" class="img-fluid rounded" '
564612
f'style="max-width:200px; background:#000; margin:4px;"/></a>'
565613
)
566614

0 commit comments

Comments
 (0)