mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
Add Open Graph and Twitter Card meta tags to all public pages
- templates/public/head.php: add centralised OG/Twitter tag rendering via $ogTags array; supports type, title, description, url, image, image_alt, site_name, article_author, article_published_time; twitter:card switches between summary_large_image / summary based on presence of og:image - public/tfe.php: populate full article OG tags — og:type=article, canonical URL, og:image resolved from banner_path → first image file in thesis_files → omitted, og:image:alt, article:author, article:published_time (year-01-01); twitter:card summary_large_image when image present - public/index.php, search.php, apropos.php, licence.php: add basic og:type=website tags (title, description, canonical url, site_name) Sharing a thesis link on Slack, WhatsApp, iMessage, or any social platform will now render a rich preview card with the thesis title, synopsis excerpt, and cover/banner image.
This commit is contained in:
8
TODO.md
8
TODO.md
@@ -539,9 +539,11 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
|||||||
site blurb for `index.php`, synopsis excerpt for `tfe.php`, page content intro for
|
site blurb for `index.php`, synopsis excerpt for `tfe.php`, page content intro for
|
||||||
`apropos.php`/`licence.php`. Necessary for search indexing and link preview cards.
|
`apropos.php`/`licence.php`. Necessary for search indexing and link preview cards.
|
||||||
|
|
||||||
- [ ] **No Open Graph tags** - `tfe.php` is the ideal candidate for `og:title`, `og:description`
|
- [x] **No Open Graph tags** - `tfe.php` now emits `og:type=article`, `og:title`, `og:description`,
|
||||||
(synopsis), `og:image` (banner or cover path through `/media.php`), `og:type=article`.
|
`og:url`, `og:image` (banner → first image file → none), `og:image:alt`, `og:site_name`,
|
||||||
Without them, sharing a thesis link on social media or messaging apps shows a blank preview.
|
`article:author`, `article:published_time`, plus `twitter:card`/`twitter:title`/`twitter:description`/
|
||||||
|
`twitter:image`. All other public pages (`index`, `search`, `apropos`, `licence`) emit basic
|
||||||
|
`og:type=website` tags. OG rendering is centralised in `templates/public/head.php` via `$ogTags` array.
|
||||||
|
|
||||||
### H - Minor / low-hanging fruit
|
### H - Minor / low-hanging fruit
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ $pd->setSafeMode(true);
|
|||||||
$aboutHtml = $pd->text($rawContent);
|
$aboutHtml = $pd->text($rawContent);
|
||||||
$pageTitle = 'À Propos – Posterg';
|
$pageTitle = 'À Propos – Posterg';
|
||||||
$metaDescription = 'À propos de Posterg, le répertoire des mémoires de fin d\'études de l\'erg – École de Recherches Graphiques de Bruxelles.';
|
$metaDescription = 'À propos de Posterg, le répertoire des mémoires de fin d\'études de l\'erg – École de Recherches Graphiques de Bruxelles.';
|
||||||
|
$ogTags = [
|
||||||
|
'type' => 'website',
|
||||||
|
'title' => $pageTitle,
|
||||||
|
'description' => $metaDescription,
|
||||||
|
'url' => 'https://posterg.erg.be/apropos.php',
|
||||||
|
'site_name' => 'Posterg – ERG',
|
||||||
|
];
|
||||||
$extraCss = ['assets/apropos.css'];
|
$extraCss = ['assets/apropos.css'];
|
||||||
?>
|
?>
|
||||||
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
||||||
|
|||||||
@@ -52,6 +52,13 @@ try {
|
|||||||
$currentNav = '';
|
$currentNav = '';
|
||||||
$pageTitle = 'Posterg – Mémoires de l\'ERG';
|
$pageTitle = 'Posterg – Mémoires de l\'ERG';
|
||||||
$metaDescription = 'Posterg répertorie et valorise les mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles.';
|
$metaDescription = 'Posterg répertorie et valorise les mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles.';
|
||||||
|
$ogTags = [
|
||||||
|
'type' => 'website',
|
||||||
|
'title' => $pageTitle,
|
||||||
|
'description' => $metaDescription,
|
||||||
|
'url' => 'https://posterg.erg.be/',
|
||||||
|
'site_name' => 'Posterg – ERG',
|
||||||
|
];
|
||||||
$extraCss = ['assets/main.css'];
|
$extraCss = ['assets/main.css'];
|
||||||
?>
|
?>
|
||||||
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ $html = $pd->text($content);
|
|||||||
|
|
||||||
$pageTitle = $licencePageTitle . ' – Posterg';
|
$pageTitle = $licencePageTitle . ' – Posterg';
|
||||||
$metaDescription = 'Informations sur les licences d\'utilisation des mémoires publiés sur Posterg, le répertoire des TFE de l\'erg.';
|
$metaDescription = 'Informations sur les licences d\'utilisation des mémoires publiés sur Posterg, le répertoire des TFE de l\'erg.';
|
||||||
|
$ogTags = [
|
||||||
|
'type' => 'website',
|
||||||
|
'title' => $pageTitle,
|
||||||
|
'description' => $metaDescription,
|
||||||
|
'url' => 'https://posterg.erg.be/licence.php',
|
||||||
|
'site_name' => 'Posterg – ERG',
|
||||||
|
];
|
||||||
$extraCss = ['assets/apropos.css'];
|
$extraCss = ['assets/apropos.css'];
|
||||||
?>
|
?>
|
||||||
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ $currentNav = 'repertoire';
|
|||||||
$searchBarValue = $_GET['query'] ?? '';
|
$searchBarValue = $_GET['query'] ?? '';
|
||||||
$pageTitle = 'Répertoire – Posterg';
|
$pageTitle = 'Répertoire – Posterg';
|
||||||
$metaDescription = 'Parcourez le répertoire des mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles. Recherche par année, orientation, atelier et mots-clés.';
|
$metaDescription = 'Parcourez le répertoire des mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles. Recherche par année, orientation, atelier et mots-clés.';
|
||||||
|
$ogTags = [
|
||||||
|
'type' => 'website',
|
||||||
|
'title' => $pageTitle,
|
||||||
|
'description' => $metaDescription,
|
||||||
|
'url' => 'https://posterg.erg.be/search.php',
|
||||||
|
'site_name' => 'Posterg – ERG',
|
||||||
|
];
|
||||||
$extraCss = ['assets/search.css'];
|
$extraCss = ['assets/search.css'];
|
||||||
?>
|
?>
|
||||||
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
||||||
|
|||||||
@@ -25,6 +25,37 @@ $metaDescription = mb_strlen($_synopsisRaw) > 160
|
|||||||
? mb_substr($_synopsisRaw, 0, 157) . '…'
|
? mb_substr($_synopsisRaw, 0, 157) . '…'
|
||||||
: (empty($_synopsisRaw) ? 'Mémoire de fin d\'études – Posterg, répertoire des TFE de l\'erg.' : $_synopsisRaw);
|
: (empty($_synopsisRaw) ? 'Mémoire de fin d\'études – Posterg, répertoire des TFE de l\'erg.' : $_synopsisRaw);
|
||||||
unset($_tfeAuthor, $_synopsisRaw);
|
unset($_tfeAuthor, $_synopsisRaw);
|
||||||
|
|
||||||
|
// --- Open Graph / Twitter Card tags ------------------------------------------
|
||||||
|
$_ogBaseUrl = 'https://posterg.erg.be';
|
||||||
|
// Resolve OG image: banner → first image file → none
|
||||||
|
$_ogImage = '';
|
||||||
|
if (!empty($data['banner_path'])) {
|
||||||
|
$_ogImage = $_ogBaseUrl . '/media.php?path=' . rawurlencode($data['banner_path']);
|
||||||
|
} elseif (!empty($data['files'])) {
|
||||||
|
foreach ($data['files'] as $_f) {
|
||||||
|
$_ext = strtolower(pathinfo($_f['file_path'], PATHINFO_EXTENSION));
|
||||||
|
if (in_array($_ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
||||||
|
$_ogImage = $_ogBaseUrl . '/media.php?path=' . rawurlencode($_f['file_path']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($_f, $_ext);
|
||||||
|
}
|
||||||
|
$ogTags = [
|
||||||
|
'type' => 'article',
|
||||||
|
'title' => $data['title'] . (!empty($data['authors']) ? ' – ' . $data['authors'] : ''),
|
||||||
|
'description' => $metaDescription,
|
||||||
|
'url' => $_ogBaseUrl . '/tfe.php?id=' . $thesisId,
|
||||||
|
'image' => $_ogImage,
|
||||||
|
'image_alt' => $data['title'] . (!empty($data['authors']) ? ' par ' . $data['authors'] : ''),
|
||||||
|
'site_name' => 'Posterg – ERG',
|
||||||
|
'article_author' => $data['authors'] ?? '',
|
||||||
|
'article_published_time' => !empty($data['year']) ? $data['year'] . '-01-01' : '',
|
||||||
|
];
|
||||||
|
unset($_ogBaseUrl, $_ogImage);
|
||||||
|
// --- End Open Graph ----------------------------------------------------------
|
||||||
|
|
||||||
$extraCss = ['assets/tfe.css'];
|
$extraCss = ['assets/tfe.css'];
|
||||||
?>
|
?>
|
||||||
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
<?php include APP_ROOT . '/templates/public/head.php'; ?>
|
||||||
|
|||||||
@@ -7,6 +7,47 @@
|
|||||||
<?php if (!empty($metaDescription)): ?>
|
<?php if (!empty($metaDescription)): ?>
|
||||||
<meta name="description" content="<?= htmlspecialchars($metaDescription) ?>">
|
<meta name="description" content="<?= htmlspecialchars($metaDescription) ?>">
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php
|
||||||
|
// Open Graph / Twitter Card tags — populated per-page via $ogTags array.
|
||||||
|
// Keys: type, title, description, url, image, image_alt, site_name, article_author, article_published_time
|
||||||
|
if (!empty($ogTags)):
|
||||||
|
$ogType = $ogTags['type'] ?? 'website';
|
||||||
|
$ogTitle = $ogTags['title'] ?? ($pageTitle ?? 'Posterg');
|
||||||
|
$ogDescription = $ogTags['description'] ?? ($metaDescription ?? '');
|
||||||
|
$ogUrl = $ogTags['url'] ?? '';
|
||||||
|
$ogImage = $ogTags['image'] ?? '';
|
||||||
|
$ogImageAlt = $ogTags['image_alt'] ?? $ogTitle;
|
||||||
|
$ogSiteName = $ogTags['site_name'] ?? 'Posterg – ERG';
|
||||||
|
?>
|
||||||
|
<meta property="og:type" content="<?= htmlspecialchars($ogType) ?>">
|
||||||
|
<meta property="og:site_name" content="<?= htmlspecialchars($ogSiteName) ?>">
|
||||||
|
<meta property="og:title" content="<?= htmlspecialchars($ogTitle) ?>">
|
||||||
|
<?php if (!empty($ogDescription)): ?>
|
||||||
|
<meta property="og:description" content="<?= htmlspecialchars($ogDescription) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($ogUrl)): ?>
|
||||||
|
<meta property="og:url" content="<?= htmlspecialchars($ogUrl) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($ogImage)): ?>
|
||||||
|
<meta property="og:image" content="<?= htmlspecialchars($ogImage) ?>">
|
||||||
|
<meta property="og:image:alt" content="<?= htmlspecialchars($ogImageAlt) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($ogTags['article_author'])): ?>
|
||||||
|
<meta property="article:author" content="<?= htmlspecialchars($ogTags['article_author']) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($ogTags['article_published_time'])): ?>
|
||||||
|
<meta property="article:published_time" content="<?= htmlspecialchars($ogTags['article_published_time']) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<meta name="twitter:card" content="<?= !empty($ogImage) ? 'summary_large_image' : 'summary' ?>">
|
||||||
|
<meta name="twitter:title" content="<?= htmlspecialchars($ogTitle) ?>">
|
||||||
|
<?php if (!empty($ogDescription)): ?>
|
||||||
|
<meta name="twitter:description" content="<?= htmlspecialchars($ogDescription) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (!empty($ogImage)): ?>
|
||||||
|
<meta name="twitter:image" content="<?= htmlspecialchars($ogImage) ?>">
|
||||||
|
<meta name="twitter:image:alt" content="<?= htmlspecialchars($ogImageAlt) ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endif; ?>
|
||||||
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
|
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
|
||||||
<link rel="stylesheet" href="assets/modern-normalize.min.css">
|
<link rel="stylesheet" href="assets/modern-normalize.min.css">
|
||||||
<link rel="stylesheet" href="assets/common.css">
|
<link rel="stylesheet" href="assets/common.css">
|
||||||
|
|||||||
Reference in New Issue
Block a user