Ajout mode présentation

This commit is contained in:
Esteban committed 2026-08-28 00:04:48 +02:00
1 parent 4862d61ccd
commit 08875d3b5a
18 files changed
+1781 -270

No files matched your search

+77 -49
View File
@@ -87,58 +87,78 @@ if (!empty($element['tags'])) {
<article class="details-card">
<?php if (!empty($image)): ?>
<div class="details-banner project-banner">
<img src="<?php echo $image; ?>" alt="Image : <?php echo $titre; ?>">
<?php if (!empty($status)): ?>
<div class="project-state"><?php echo $status; ?></div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php
// Bandeau d'image, seulement si une image est renseignée pour cet élément
if (!empty($image)) {
echo '<div class="details-banner project-banner">';
echo '<img src="' . $image . '" alt="Image : ' . $titre . '">';
// Pastille d'état (En cours, Terminé...) posée par-dessus l'image
if (!empty($status)) {
echo '<div class="project-state">' . $status . '</div>';
}
echo '</div>';
}
?>
<div class="details-content">
<span class="details-type"><?php echo $infos['label']; ?></span>
<h1><?php echo $titre; ?></h1>
<!-- Métadonnées : type / durée si renseignés -->
<?php if (!empty($xptype) || !empty($duration)): ?>
<p class="details-meta">
<?php if (!empty($xptype)): ?><span><i class="fa-solid fa-tag"></i> <?php echo $xptype; ?></span><?php endif; ?>
<?php if (!empty($duration)): ?><span><i class="fa-solid fa-clock"></i> <?php echo $duration; ?></span><?php endif; ?>
</p>
<?php endif; ?>
<?php
// Métadonnées : type d'expérience et durée, affichés seulement si renseignés
if (!empty($xptype) || !empty($duration)) {
echo '<p class="details-meta">';
<?php if (!empty($tags)): ?>
<div class="project-tags">
<?php foreach ($tags as $tag): ?>
<span class="tag"><?php echo htmlspecialchars($tag); ?></span>
<?php endforeach; ?>
</div>
<?php endif; ?>
if (!empty($xptype)) {
echo '<span><i class="fa-solid fa-tag"></i> ' . $xptype . '</span>';
}
<?php if ($hasMarkdown): ?>
<!-- Le markdown brut est placé ici (échappé), puis rendu en HTML par le script plus bas -->
<div id="markdown-source" hidden><?php echo htmlspecialchars($element['markdown']); ?></div>
<div class="markdown-content" id="markdown-target">
<p>Chargement du contenu...</p>
</div>
<?php elseif ($hasPdf): ?>
<!-- Mini lecteur PDF : le fichier est servi par viewPdf.php depuis la base de données -->
<div class="pdf-viewer-wrap">
<div class="pdf-viewer-toolbar">
<span><i class="fa-solid fa-file-pdf"></i> <?php echo htmlspecialchars($element['pdf_filename']); ?></span>
<a class="btn btn-ghost pdf-download-btn" href="../scripts/viewPdf.php?type=<?php echo $type; ?>&id=<?php echo (int) $id; ?>&download=1" download>
<i class="fa-solid fa-download"></i> Télécharger
</a>
</div>
<iframe
class="pdf-viewer"
src="../scripts/viewPdf.php?type=<?php echo $type; ?>&id=<?php echo (int) $id; ?>"
title="Aperçu PDF : <?php echo $titre; ?>"
></iframe>
</div>
<?php endif; ?>
if (!empty($duration)) {
echo '<span><i class="fa-solid fa-clock"></i> ' . $duration . '</span>';
}
echo '</p>';
}
// Étiquettes (technologies, mots-clés), une par tag séparé par une virgule en BDD
if (!empty($tags)) {
echo '<div class="project-tags">';
foreach ($tags as $tag) {
echo '<span class="tag">' . htmlspecialchars($tag) . '</span>';
}
echo '</div>';
}
?>
<?php
// Deux contenus possibles, jamais les deux en même temps : soit un texte en
// markdown, soit un PDF. Le markdown est prioritaire quand les deux existent.
if ($hasMarkdown) {
// Le markdown brut est placé ici (échappé), puis rendu en HTML par le script plus bas
echo '<div id="markdown-source" hidden>' . htmlspecialchars($element['markdown']) . '</div>';
echo '<div class="markdown-content" id="markdown-target">';
echo '<p>Chargement du contenu...</p>';
echo '</div>';
} elseif ($hasPdf) {
// Mini lecteur PDF : le fichier est servi par viewPdf.php depuis la base de données
$lienPdf = '../scripts/viewPdf.php?type=' . $type . '&id=' . (int) $id;
echo '<div class="pdf-viewer-wrap">';
echo '<div class="pdf-viewer-toolbar">';
echo '<span><i class="fa-solid fa-file-pdf"></i> ' . htmlspecialchars($element['pdf_filename']) . '</span>';
echo '<a class="btn btn-ghost pdf-download-btn" href="' . $lienPdf . '&download=1" download>';
echo '<i class="fa-solid fa-download"></i> Télécharger';
echo '</a>';
echo '</div>';
echo '<iframe class="pdf-viewer" src="' . $lienPdf . '" title="Aperçu PDF : ' . $titre . '"></iframe>';
echo '</div>';
}
?>
</div>
@@ -146,10 +166,16 @@ if (!empty($element['tags'])) {
</div>
<?php if ($hasMarkdown): ?>
<!-- marked.js : convertit le markdown en HTML / DOMPurify : nettoie le HTML généré (sécurité) -->
<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>
<?php
// Ces deux librairies ne sont chargées que sur les pages qui ont réellement du markdown :
// marked.js convertit le markdown en HTML, DOMPurify nettoie le HTML généré (sécurité XSS)
if ($hasMarkdown) {
echo '<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script>';
echo '<script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>';
// <<<'JS' ... JS; = "nowdoc" : un bloc de texte sur plusieurs lignes, recopié tel quel.
// Pratique ici pour ne pas avoir à échapper les guillemets du JavaScript.
echo <<<'JS'
<script>
(function () {
var source = document.getElementById('markdown-source');
@@ -159,7 +185,9 @@ if (!empty($element['tags'])) {
cible.innerHTML = DOMPurify.sanitize(marked.parse(markdown, { breaks: true }));
})();
</script>
<?php endif; ?>
JS;
}
?>
<?php
// Ajout du footer