fix & feat : SEO desc, feed cover, livres slug auto + filtre (v1.6.21)

- buildAutoSeoDesc() : entités HTML décodées + titre supprimé en tête (#91)
- post_confirm.js : guard null sur #confirm-slug absent (#91)
- feed.php : <media:thumbnail> avec image de couverture RSS (#90)
- admin livres : slug auto depuis le titre + filtre articles (#89)
- BookManager::sanitizeSlug() passé public

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 11:05:01 +02:00
parent 3b22be94e8
commit ca6cfa4ebf
8 changed files with 92 additions and 27 deletions
+19 -12
View File
@@ -69,6 +69,19 @@ function log404(string $url): void
@file_put_contents($logFile, $entry, FILE_APPEND | LOCK_EX);
}
function buildAutoSeoDesc(string $content, string $title = ''): string
{
require_once BASE_PATH . '/src/Parsedown.php';
$_pd = new Parsedown();
$_plain = trim((string)preg_replace('/\s+/', ' ',
html_entity_decode(strip_tags($_pd->text($content)), ENT_QUOTES | ENT_HTML5, 'UTF-8')
));
if ($title !== '' && stripos($_plain, $title) === 0) {
$_plain = ltrim(substr($_plain, strlen($title)));
}
return mb_strimwidth($_plain, 0, 155, '…');
}
function slugToSearchQuery(string $rawPath): string
{
return trim((string)preg_replace('/\s{2,}/', ' ', (string)preg_replace(
@@ -653,10 +666,7 @@ switch ($action) {
header('Location: /new');
exit;
}
require_once BASE_PATH . '/src/Parsedown.php';
$_pd = new Parsedown();
$autoSeoDesc = mb_strimwidth(trim((string)preg_replace('/\s+/', ' ', strip_tags($_pd->text((string)($draft['content'] ?? ''))))), 0, 155, '…');
unset($_pd);
$autoSeoDesc = buildAutoSeoDesc((string)($draft['content'] ?? ''), trim($draft['title'] ?? ''));
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$seoTitle = trim($_POST['seo_title'] ?? '');
$seoDesc = trim($_POST['seo_description'] ?? '') ?: $autoSeoDesc;
@@ -1021,10 +1031,7 @@ switch ($action) {
header('Location: /edit/' . rawurlencode($uuid) . '/6');
exit;
}
require_once BASE_PATH . '/src/Parsedown.php';
$_pd = new Parsedown();
$autoSeoDesc = mb_strimwidth(trim((string)preg_replace('/\s+/', ' ', strip_tags($_pd->text((string)($draft['content'] ?? ''))))), 0, 155, '…');
unset($_pd);
$autoSeoDesc = buildAutoSeoDesc((string)($draft['content'] ?? ''), trim($draft['title'] ?? ''));
$title = $draft['title'];
$seoTitle = $draft['seo_title'] ?? '';
$seoDescription = $draft['seo_description'] ?? '';
@@ -1046,10 +1053,7 @@ switch ($action) {
exit;
}
$draftData = $articles->getDraftOverlay($uuid) ?? $article;
require_once BASE_PATH . '/src/Parsedown.php';
$_pd = new Parsedown();
$autoSeoDesc = mb_strimwidth(trim((string)preg_replace('/\s+/', ' ', strip_tags($_pd->text((string)($draftData['content'] ?? ''))))), 0, 155, '…');
unset($_pd);
$autoSeoDesc = buildAutoSeoDesc((string)($draftData['content'] ?? ''), trim($draftData['title'] ?? ''));
$diffLines = lineDiff((string)($article['content'] ?? ''), (string)($draftData['content'] ?? ''));
$titleChanged = ($draftData['title'] ?? '') !== ($article['title'] ?? '');
$postSlug = $draftData['slug'] ?? $article['slug'];
@@ -3491,6 +3495,9 @@ switch ($action) {
$bTitle = trim($_POST['title'] ?? '');
$bDesc = trim($_POST['description'] ?? '');
$bArts = array_values(array_filter(array_map('trim', preg_split('/[\r\n]+/', $_POST['articles'] ?? ''))));
if ($bSlug === '' && $bTitle !== '') {
$bSlug = $books->sanitizeSlug($bTitle);
}
if ($bSlug !== '' && $bTitle !== '') {
$books->save(['slug' => $bSlug, 'title' => $bTitle, 'description' => $bDesc, 'articles' => $bArts]);
}