Include lead image in feed item descriptions
The API already returns image_affiche_scale/image_full_scale for every item (news and events alike), no extra request needed — just wasn't being used. Embedded as an <img> at the top of the HTML description so feed readers display it inline with the article. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -37,7 +37,7 @@ function build_news_feed(): string
|
|||||||
'link' => SITE . '/actualites/' . slugify($title) . '?u=' . rawurlencode($uid),
|
'link' => SITE . '/actualites/' . slugify($title) . '?u=' . rawurlencode($uid),
|
||||||
'guid' => $uid,
|
'guid' => $uid,
|
||||||
'pubDate' => $item['effective'] ?? $item['created'] ?? null,
|
'pubDate' => $item['effective'] ?? $item['created'] ?? null,
|
||||||
'description' => full_body_html($item),
|
'description' => full_body_html($item, $title),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return build_rss(
|
return build_rss(
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ function build_events_feed(): string
|
|||||||
$uid = $item['UID'] ?? $id;
|
$uid = $item['UID'] ?? $id;
|
||||||
$meta = format_event_meta($item);
|
$meta = format_event_meta($item);
|
||||||
$description = ($meta !== '' ? '<p>' . htmlspecialchars($meta, ENT_QUOTES, 'UTF-8') . '</p>' : '')
|
$description = ($meta !== '' ? '<p>' . htmlspecialchars($meta, ENT_QUOTES, 'UTF-8') . '</p>' : '')
|
||||||
. full_body_html($item);
|
. full_body_html($item, $title);
|
||||||
// Un evenement recurrent partage le meme UID sur toutes ses
|
// Un evenement recurrent partage le meme UID sur toutes ses
|
||||||
// occurrences (memes UID, dates differentes) : on suffixe le guid
|
// occurrences (memes UID, dates differentes) : on suffixe le guid
|
||||||
// avec la date de debut pour rester unique par occurrence, comme
|
// avec la date de debut pour rester unique par occurrence, comme
|
||||||
|
|||||||
+19
-4
@@ -135,17 +135,32 @@ function attachments_html(array $item): string
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corps HTML complet d'un item (texte riche + pieces jointes), avec
|
* Image principale de l'item (deja fournie par l'API, aucune requete
|
||||||
* repli sur le resume court si le texte complet est vide.
|
* supplementaire necessaire). "paysage_affiche" est une taille
|
||||||
|
* intermediaire raisonnable pour une image de flux RSS.
|
||||||
*/
|
*/
|
||||||
function full_body_html(array $item): string
|
function lead_image_html(array $item, string $title): string
|
||||||
|
{
|
||||||
|
$url = $item['image_affiche_scale'] ?? $item['image_full_scale'] ?? null;
|
||||||
|
if (!$url) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return '<p><img src="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" alt="'
|
||||||
|
. htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '" /></p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corps HTML complet d'un item (image + texte riche + pieces jointes),
|
||||||
|
* avec repli sur le resume court si le texte complet est vide.
|
||||||
|
*/
|
||||||
|
function full_body_html(array $item, string $title): string
|
||||||
{
|
{
|
||||||
$body = trim($item['text_fr']['data'] ?? '');
|
$body = trim($item['text_fr']['data'] ?? '');
|
||||||
if ($body === '') {
|
if ($body === '') {
|
||||||
$summary = strip_html($item['description_fr'] ?? $item['description'] ?? null);
|
$summary = strip_html($item['description_fr'] ?? $item['description'] ?? null);
|
||||||
$body = $summary !== '' ? '<p>' . htmlspecialchars($summary, ENT_QUOTES, 'UTF-8') . '</p>' : '';
|
$body = $summary !== '' ? '<p>' . htmlspecialchars($summary, ENT_QUOTES, 'UTF-8') . '</p>' : '';
|
||||||
}
|
}
|
||||||
return $body . attachments_html($item);
|
return lead_image_html($item, $title) . $body . attachments_html($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rfc822(?string $isoDate): string
|
function rfc822(?string $isoDate): string
|
||||||
|
|||||||
+15
-5
@@ -101,14 +101,24 @@ def attachments_html(item: dict) -> str:
|
|||||||
return "".join(parts)
|
return "".join(parts)
|
||||||
|
|
||||||
|
|
||||||
def full_body_html(item: dict) -> str:
|
def lead_image_html(item: dict, title: str) -> str:
|
||||||
"""Corps HTML complet (texte riche + pieces jointes), repli sur le resume court."""
|
"""Image principale de l'item, deja fournie par l'API (aucune requete
|
||||||
|
supplementaire necessaire). "paysage_affiche" est une taille
|
||||||
|
intermediaire raisonnable pour une image de flux RSS."""
|
||||||
|
url = item.get("image_affiche_scale") or item.get("image_full_scale")
|
||||||
|
if not url:
|
||||||
|
return ""
|
||||||
|
return f'<p><img src="{html.escape(url)}" alt="{html.escape(title)}" /></p>'
|
||||||
|
|
||||||
|
|
||||||
|
def full_body_html(item: dict, title: str) -> str:
|
||||||
|
"""Corps HTML complet (image + texte riche + pieces jointes), repli sur le resume court."""
|
||||||
text_fr = item.get("text_fr")
|
text_fr = item.get("text_fr")
|
||||||
body = (text_fr.get("data") or "").strip() if isinstance(text_fr, dict) else ""
|
body = (text_fr.get("data") or "").strip() if isinstance(text_fr, dict) else ""
|
||||||
if not body:
|
if not body:
|
||||||
summary = strip_html(item.get("description_fr") or item.get("description"))
|
summary = strip_html(item.get("description_fr") or item.get("description"))
|
||||||
body = f"<p>{html.escape(summary)}</p>" if summary else ""
|
body = f"<p>{html.escape(summary)}</p>" if summary else ""
|
||||||
return body + attachments_html(item)
|
return lead_image_html(item, title) + body + attachments_html(item)
|
||||||
|
|
||||||
|
|
||||||
def parse_dt(value: str | None) -> datetime | None:
|
def parse_dt(value: str | None) -> datetime | None:
|
||||||
@@ -133,7 +143,7 @@ def build_news_items() -> list[str]:
|
|||||||
title = item.get("title_fr") or item.get("title") or "(sans titre)"
|
title = item.get("title_fr") or item.get("title") or "(sans titre)"
|
||||||
guid = item.get("UID") or item_id
|
guid = item.get("UID") or item_id
|
||||||
link = f"{SITE}/actualites/{slugify(title)}?u={guid}"
|
link = f"{SITE}/actualites/{slugify(title)}?u={guid}"
|
||||||
description = full_body_html(item)
|
description = full_body_html(item, title)
|
||||||
pub_dt = parse_dt(item.get("effective") or item.get("created"))
|
pub_dt = parse_dt(item.get("effective") or item.get("created"))
|
||||||
entries.append(
|
entries.append(
|
||||||
" <item>\n"
|
" <item>\n"
|
||||||
@@ -173,7 +183,7 @@ def build_event_items() -> list[str]:
|
|||||||
guid = item.get("UID") or event_id
|
guid = item.get("UID") or event_id
|
||||||
link = f"{SITE}/agenda/{slugify(title)}?u={guid}"
|
link = f"{SITE}/agenda/{slugify(title)}?u={guid}"
|
||||||
meta = format_event_meta(item)
|
meta = format_event_meta(item)
|
||||||
description = (f"<p>{html.escape(meta)}</p>" if meta else "") + full_body_html(item)
|
description = (f"<p>{html.escape(meta)}</p>" if meta else "") + full_body_html(item, title)
|
||||||
pub_dt = parse_dt(item.get("created") or item.get("start"))
|
pub_dt = parse_dt(item.get("created") or item.get("start"))
|
||||||
# Un evenement recurrent partage le meme UID sur toutes ses
|
# Un evenement recurrent partage le meme UID sur toutes ses
|
||||||
# occurrences : on suffixe le guid avec la date de debut pour
|
# occurrences : on suffixe le guid avec la date de debut pour
|
||||||
|
|||||||
Reference in New Issue
Block a user