diff --git a/CHANGELOG.md b/CHANGELOG.md index e81d91f..04dc137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ Format : [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) — versionnag --- +## [1.6.26] - 2026-05-16 + +### Ajouté +- Page publique `/books` — catalogue de tous les livres avec ≥ 1 article publié, cards cover/titre/description/nombre de pages (#99) +- Accueil : section « Livres » (max 6) après les redécouvertes avec lien « Voir tous → /books » (#100) + +--- + ## [1.6.25] - 2026-05-16 ### Ajouté diff --git a/public/.htaccess b/public/.htaccess index 0699297..0099201 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -15,6 +15,9 @@ RewriteRule ^ - [L] # URL propre pour les articles : /post/ RewriteRule ^post/([a-z0-9][a-z0-9-]*)/?$ /index.php?action=view&slug=$1 [L,QSA] +# Catalogue de tous les livres : /books +RewriteRule ^books/?$ /index.php?action=books_list [L,QSA] + # Livres : /book/ RewriteRule ^book/([a-z0-9][a-z0-9-]*)/?$ /index.php?action=book&book_slug=$1 [L,QSA] diff --git a/public/assets/css/style.css b/public/assets/css/style.css index cd62a6c..e42afdc 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -1844,6 +1844,68 @@ main { transition: max-width .22s ease; } /* ─── Livres ─────────────────────────────────────────────────────── */ +/* Grille catalogue /books + section accueil */ +.book-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 1rem; +} +.book-home-card { + display: flex; + flex-direction: column; + border-radius: var(--vl-radius); + overflow: hidden; + text-decoration: none; + color: inherit; + background: var(--vl-card-bg, var(--bs-body-bg)); + box-shadow: var(--vl-shadow-sm, 0 1px 3px rgba(0,0,0,.08)); + transition: transform .15s, box-shadow .15s; +} +.book-home-card:hover { + transform: translateY(-2px); + box-shadow: var(--vl-shadow-md, 0 4px 12px rgba(0,0,0,.14)); + color: inherit; +} +.book-home-card-cover { + height: 120px; + background-size: cover; + background-position: center; + flex-shrink: 0; +} +.book-home-card-body { + padding: .7rem; + display: flex; + flex-direction: column; + gap: .2rem; + flex: 1; +} +.book-home-card-title { + font-weight: 600; + font-size: .9rem; + line-height: 1.3; +} +.book-home-card-desc { + font-size: .78rem; + color: var(--vl-muted); + line-height: 1.4; +} +.book-home-card-meta { + font-size: .72rem; + color: var(--vl-muted); + margin-top: auto; + padding-top: .3rem; +} +.home-section-more { + font-size: .75rem; + font-weight: 400; + margin-left: .5rem; + color: var(--vl-accent); + text-decoration: none; + letter-spacing: 0; + text-transform: none; +} +.home-section-more:hover { text-decoration: underline; } + /* Bandeau dans un article appartenant à un livre */ .book-article-banner { border-radius: var(--vl-radius); diff --git a/public/index.php b/public/index.php index 51bed50..1895432 100644 --- a/public/index.php +++ b/public/index.php @@ -3530,6 +3530,25 @@ switch ($action) { include BASE_PATH . '/templates/search.php'; break; + case 'books_list': + $allCats = $articles->getCategories(); + $booksData = []; + foreach ($books->getAll() as $_bk) { + $_published = []; + foreach ($_bk['articles'] ?? [] as $_aSlug) { + $_a = $articles->getBySlug($_aSlug); + if ($_a && $_a['published'] && strtotime((string)($_a['published_at'] ?? '')) <= time()) { + $_published[] = $_a; + } + } + if (empty($_published)) continue; + $booksData[] = ['book' => $_bk, 'count' => count($_published), 'first' => $_published[0]]; + } + unset($_bk, $_published, $_aSlug, $_a); + $seoDescription = 'Retrouvez tous les livres et séries d\'articles publiés sur ' . siteTitle() . '.'; + include BASE_PATH . '/templates/books_list.php'; + break; + case 'book': $bookSlug = trim($_GET['book_slug'] ?? ''); $book = $books->getBySlug($bookSlug); @@ -3834,6 +3853,22 @@ switch ($action) { $recentlyUpdated[] = $_a; } unset($_sevenDaysAgo, $_latestUuids, $_popularUuids, $_heroUuid, $_a, $allPostsMap); + + // Books à mettre en avant (max 6, ayant ≥ 1 article publié) + $homeBooks = []; + foreach ($books->getAll() as $_bk) { + $_published = []; + foreach ($_bk['articles'] ?? [] as $_aSlug) { + $_a = $articles->getBySlug($_aSlug); + if ($_a && $_a['published'] && strtotime((string)($_a['published_at'] ?? '')) <= time()) { + $_published[] = $_a; + } + } + if (empty($_published)) continue; + $homeBooks[] = ['book' => $_bk, 'count' => count($_published), 'first' => $_published[0]]; + if (count($homeBooks) >= 6) break; + } + unset($_bk, $_published, $_aSlug, $_a); } // ────────────────────────────────────────────────────────────────── diff --git a/public/version.txt b/public/version.txt index a92834b..757e60b 100644 --- a/public/version.txt +++ b/public/version.txt @@ -1 +1 @@ -1.6.25 +1.6.26 diff --git a/templates/books_list.php b/templates/books_list.php new file mode 100644 index 0000000..54a7f51 --- /dev/null +++ b/templates/books_list.php @@ -0,0 +1,49 @@ + + +
+ +
+

Livres

+ livre 1 ? 's' : '' ?> +
+ + +

Aucun livre disponible pour l'instant.

+ + + + + + +
+ + + +
+

+ Livres + Voir tous → +

+ +
+ +