Files
varlog/templates/post_list.php
T
Cedric Abonnel 1d2e3d9a24 feat: roles, permissions, grille full-width, SSO display name
- Admin/roles : tableau des roles avec edition par role (/admin/role/<nom>)
- Permissions par role : cases a cocher groupees (Articles, Acces & lecture)
- Nouvelles capacites : propose/validate/publish articles (own/all), view_previews
- Nom technique auto-genere depuis le label (JS + fallback serveur)
- Blocage suppression du dernier administrateur
- user_capabilities table ajoutee en DB
- Navbar : dropdown unique (nom + Mon identite + Administration + Deconnexion)
- SSO callback : preserve le nom personnalise, ne l ecrase plus a la connexion
- Grille articles : CSS Grid auto-fill full-width, hauteur uniforme par ligne
- CSP : add_files.js et post_confirm.js externalises
2026-05-12 15:51:06 +02:00

127 lines
5.3 KiB
PHP

<?php
require_once BASE_PATH . '/src/Parsedown.php';
$Parsedown = new Parsedown();
ob_start();
?>
<div class="post-grid">
<?php foreach ($posts as $i => $post): ?>
<?php
$html = $Parsedown->text($post['content']);
$preview = mb_strimwidth(strip_tags($html), 0, 120, '…');
$category = trim((string)($post['category'] ?? ''));
$gradient = coverGradient($category !== '' ? $category : $post['uuid'], $allCats ?? []);
$postUrl = '/post/' . rawurlencode($post['slug']);
$isDraft = !$post['published'];
$isAvantPremiere = $post['published'] && strtotime((string)($post['published_at'] ?? '')) > time();
$postCat = trim($post['category'] ?? '');
$isPrivate = $postCat !== '' && in_array($postCat, $privateCats ?? [], true);
$isLocked = $isAvantPremiere;
?>
<article class="card">
<?php if ($isDraft): ?>
<div class="draft-ribbon">Brouillon</div>
<?php elseif ($isAvantPremiere): ?>
<div class="premiere-ribbon">Avant-première</div>
<?php elseif ($isPrivate): ?>
<div class="private-ribbon">Privé</div>
<?php endif; ?>
<?php
$coverFile = $post['cover'] ?? '';
$coverStyle = $coverFile !== ''
? 'background-image: url(\'/file?uuid=' . rawurlencode($post['uuid']) . '&name=' . rawurlencode($coverFile) . '\')'
: 'background: ' . $gradient;
?>
<div class="card-cover" style="<?= $coverStyle ?>">
<?php if ($category !== ''): ?>
<span class="cover-category"><?= htmlspecialchars($category) ?></span>
<?php endif; ?>
</div>
<div class="card-body d-flex flex-column">
<h2 class="card-title">
<?php if ($isLocked): ?>
<?= htmlspecialchars($post['title']) ?>
<?php else: ?>
<a href="<?= htmlspecialchars($postUrl) ?>">
<?= htmlspecialchars($post['title']) ?>
</a>
<?php endif; ?>
</h2>
<p class="card-text flex-grow-1"><?= htmlspecialchars($preview) ?></p>
<div class="post-entry-meta mt-auto">
<?php if ($isAvantPremiere): ?>
<span class="text-muted">Disponible le <?= htmlspecialchars(date('d/m/Y \à H\hi', strtotime((string)($post['published_at'] ?? '')))) ?></span>
<?php else: ?>
<span><?= htmlspecialchars(date('d/m/Y', strtotime((string)($post['published_at'] ?? $post['created_at'] ?? '')))) ?></span>
<?php endif; ?>
<?php if (function_exists('isAdmin') && isAdmin()): ?>
<a href="/edit/<?= htmlspecialchars($post['uuid']) ?>" class="post-entry-edit">modifier</a>
<?php endif; ?>
<?php if (!$isLocked): ?>
<a href="<?= htmlspecialchars($postUrl) ?>" class="post-entry-read">→ lire</a>
<?php endif; ?>
</div>
</div>
<?php if (!$isLocked): ?>
<a href="<?= htmlspecialchars($postUrl) ?>" class="stretched-link"></a>
<?php endif; ?>
</article>
<?php endforeach; ?>
</div>
<?php if ($prevCursor !== null || $nextCursor !== null): ?>
<nav class="pagination-nav mt-5" aria-label="Navigation">
<?php
$hasCat = $filterCat !== '';
$catBase = $hasCat ? '/categorie/' . rawurlencode($filterCat) : null;
?>
<?php if ($prevCursor !== null): ?>
<?php
if ($prevCursor === '') {
$prevHref = $hasCat ? $catBase : '/';
} elseif ($hasCat) {
$prevHref = $catBase . '?cursor=' . rawurlencode($prevCursor);
} else {
$prevHref = '/page/' . rawurlencode($prevCursor);
}
?>
<a class="pagination-btn" href="<?= htmlspecialchars($prevHref) ?>">← Plus récents</a>
<?php endif; ?>
<?php if ($nextCursor !== null): ?>
<?php $nextHref = $hasCat ? $catBase . '?cursor=' . rawurlencode($nextCursor) : '/page/' . rawurlencode($nextCursor); ?>
<a class="pagination-btn ms-auto" href="<?= htmlspecialchars($nextHref) ?>">Plus anciens →</a>
<?php endif; ?>
</nav>
<?php endif; ?>
<?php
$content = ob_get_clean();
$title = 'varlog';
// Pages avec curseur = contenu non-canonique → noindex
if (!empty($cursor)) {
$metaRobots = 'noindex, follow';
$canonical = rtrim(APP_URL, '/') . '/';
} elseif ($filterCat !== '') {
$canonical = rtrim(APP_URL, '/') . '/categorie/' . rawurlencode($filterCat);
} else {
$canonical = rtrim(APP_URL, '/') . '/';
}
// JSON-LD WebSite sur la page d'accueil sans filtre
if (empty($cursor) && $filterCat === '') {
$jsonLd = json_encode([
'@context' => 'https://schema.org',
'@type' => 'WebSite',
'name' => 'varlog',
'url' => rtrim(APP_URL, '/') . '/',
'description' => 'Journal personnel de Cédrix. Informatique, hack et loisirs techniques.',
'inLanguage' => 'fr-FR',
'author' => ['@type' => 'Person', 'name' => 'Cédrix'],
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
$mainClass = 'container-fluid';
include __DIR__ . '/layout.php';