feat: improve SEO with podcast JSON-LD, canonical and meta descriptions

This commit is contained in:
2026-07-25 15:12:43 +04:00
parent 576a72a0e1
commit 521ad8c7f1
11 changed files with 246 additions and 59 deletions
+4 -2
View File
@@ -124,7 +124,8 @@ Toutes ces sources sont modifiables dans `includes/config.local.php` (voir <<fr-
==== 🔍 SEO et données structurées
- *JSON-LD* généré automatiquement : `WebSite` (avec `SearchAction`), `VideoObject`, `CollectionPage`, `BreadcrumbList`
- *JSON-LD* généré automatiquement : `WebSite` (avec `SearchAction`), `PodcastSeries` et `PodcastEpisode` (avec `AudioObject`) pour le podcast Castopod, `VideoObject` (avec `embedUrl`), `CollectionPage`, `BreadcrumbList`, `Organization`
- *Meta descriptions* sur toutes les pages et *URL canoniques* (`link rel="canonical"`) ; pages de résultats de recherche en `noindex, follow`
- Balises *Open Graph* et *Twitter Cards*
- `sitemap.xml` et `robots.txt` fournis en exemples
- Prêt pour *Plausible Analytics* (voir <<fr-analytics,Analytics>>) : désactivé par défaut, sans cookies et conforme RGPD
@@ -1051,7 +1052,8 @@ All of these sources can be changed in `includes/config.local.php` (see <<en-con
==== 🔍 SEO and structured data
- Automatically generated *JSON-LD*: `WebSite` (with `SearchAction`), `VideoObject`, `CollectionPage`, `BreadcrumbList`
- Automatically generated *JSON-LD*: `WebSite` (with `SearchAction`), `PodcastSeries` and `PodcastEpisode` (with `AudioObject`) for the Castopod podcast, `VideoObject` (with `embedUrl`), `CollectionPage`, `BreadcrumbList`, `Organization`
- *Meta descriptions* on every page and *canonical URLs* (`link rel="canonical"`); search result pages set to `noindex, follow`
- *Open Graph* and *Twitter Cards* meta tags
- `sitemap.xml` and `robots.txt` provided as samples
- Ready for *Plausible Analytics* (see <<en-analytics,Analytics>>): disabled by default, cookie-free and GDPR-compliant
+4 -2
View File
@@ -43,6 +43,8 @@ if ($categoryId && isset($allCategories[$categoryId])) {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<?php echo generateCSRFToken(); ?>">
<title><?php echo htmlspecialchars($categoryName); ?> - <?php echo SITE_NAME; ?></title>
<meta name="description" content="Découvrez toutes les vidéos de la catégorie <?php echo htmlspecialchars($categoryName); ?> sur <?php echo SITE_NAME; ?>. Contenu multimédia de qualité et exclusif.">
<link rel="canonical" href="<?php echo getBaseUrl() . '/categories.php?id=' . $categoryId; ?>">
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
@@ -52,7 +54,7 @@ if ($categoryId && isset($allCategories[$categoryId])) {
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#FF0000">
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="Catégorie : <?php echo htmlspecialchars($categoryName); ?> - <?php echo SITE_NAME; ?>">
@@ -112,7 +114,7 @@ if ($categoryId && isset($allCategories[$categoryId])) {
<div class="section-logo">
<img src="img/logo.png" alt="<?php echo SITE_NAME; ?>">
</div>
<h2 class="section-title">Catégorie : <?php echo htmlspecialchars($categoryName); ?></h2>
<h1 class="section-title">Catégorie : <?php echo htmlspecialchars($categoryName); ?></h1>
</div>
<?php if (empty($videos)): ?>
+2
View File
@@ -13,6 +13,8 @@ setSecurityHeaders();
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<?php echo generateCSRFToken(); ?>">
<title><?php echo SITE_NAME; ?> - Ouverture prochaine</title>
<meta name="description" content="<?php echo htmlspecialchars(SITE_DESCRIPTION); ?> Ouverture prochaine.">
<link rel="canonical" href="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/countdown.php'; ?>">
<!-- Styles -->
<link rel="stylesheet" href="css/countdown.css?v=<?php echo filemtime('css/countdown.css'); ?>">
+5 -3
View File
@@ -23,6 +23,8 @@ $liveStream = getLiveStream();
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Direct - <?php echo SITE_NAME; ?></title>
<meta name="description" content="Suivez nos diffusions en direct sur <?php echo SITE_NAME; ?>. Contenu en temps réel, discussions et événements exclusifs.">
<link rel="canonical" href="<?php echo getBaseUrl(); ?>/direct.php">
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
@@ -32,7 +34,7 @@ $liveStream = getLiveStream();
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#FF0000">
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="Direct - <?php echo SITE_NAME; ?>">
@@ -191,7 +193,7 @@ $liveStream = getLiveStream();
$dynamicTitle = NEXT_LIVE_TITLE;
}
?>
<h2><?php echo htmlspecialchars($dynamicTitle); ?></h2>
<h1><?php echo htmlspecialchars($dynamicTitle); ?></h1>
<?php
if (!empty(NEXT_LIVE_DATE)) {
$liveHour = $liveDate->format('H\hi');
@@ -260,7 +262,7 @@ $liveStream = getLiveStream();
?>
<div class="no-live-message">
<i class="fas fa-tv"></i>
<h2>Aucun direct en cours</h2>
<h1>Aucun direct en cours</h1>
<p>Revenez plus tard pour découvrir nos prochaines diffusions en direct.</p>
<a href="index.php" class="btn-primary">Retour à l'accueil</a>
</div>
+23 -14
View File
@@ -16,6 +16,7 @@
require_once 'includes/config.php';
require_once 'includes/security.php';
require_once 'includes/structured-data.php';
// Vérifier si les dons sont activés
if (!defined('DONATIONS_ENABLED') || !DONATIONS_ENABLED) {
@@ -59,6 +60,7 @@ $stripeMonthlyLinks = defined('STRIPE_MONTHLY_LINKS') ? STRIPE_MONTHLY_LINKS : [
<!-- PERSONNALISEZ: Titre et description de votre page de dons -->
<title>Soutenir <?php echo ORGANIZATION_NAME; ?> - Dons</title>
<meta name="description" content="Soutenez <?php echo ORGANIZATION_NAME; ?> par un don. Chaque contribution compte pour maintenir le hub multimédia du podcast.">
<link rel="canonical" href="<?php echo getBaseUrl() . '/dons.php'; ?>">
<!-- Styles -->
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
@@ -76,24 +78,31 @@ $stripeMonthlyLinks = defined('STRIPE_MONTHLY_LINKS') ? STRIPE_MONTHLY_LINKS : [
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="Soutenir <?php echo ORGANIZATION_NAME; ?>">
<meta property="og:description" content="Soutenez <?php echo ORGANIZATION_NAME; ?> par un don et aidez-nous à maintenir le hub multimédia du podcast.">
<meta property="og:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/dons.php'; ?>">
<meta property="og:image" content="<?php echo getBaseUrl() . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo getBaseUrl() . '/dons.php'; ?>">
<meta property="og:type" content="website">
<meta property="og:site_name" content="<?php echo SITE_NAME; ?>">
<meta property="og:locale" content="fr_FR">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Soutenir <?php echo ORGANIZATION_NAME; ?>">
<meta name="twitter:description" content="Soutenez <?php echo ORGANIZATION_NAME; ?> par un don et aidez-nous à maintenir le hub multimédia du podcast.">
<meta name="twitter:image" content="<?php echo getBaseUrl() . '/img/logo.png'; ?>">
<!-- Schema.org pour les dons -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "<?php echo SITE_NAME; ?>",
"description": "<?php echo SITE_DESCRIPTION; ?>",
"url": "<?php echo 'https://' . $_SERVER['HTTP_HOST']; ?>",
"potentialAction": {
"@type": "DonateAction"
}
}
</script>
<?php
outputJsonLd(json_encode([
"@context" => "https://schema.org",
"@type" => "Organization",
"name" => SITE_NAME,
"description" => SITE_DESCRIPTION,
"url" => getBaseUrl(),
"potentialAction" => [
"@type" => "DonateAction"
]
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
?>
<!-- Script pour éviter le flash en mode sombre -->
<script>
+1 -1
View File
@@ -94,6 +94,6 @@
</div>
<div class="footer-copyright">
<?php echo LEGAL_COPYRIGHT; ?> <?php echo date('Y'); ?> - Licence libre <a href="<?php echo LEGAL_LICENSE_URL; ?>" target="_blank" rel="noopener noreferrer">GNU AGPL-V3</a>
<?php echo LEGAL_COPYRIGHT; ?> <?php echo date('Y'); ?> - Licence libre <a href="<?php echo LEGAL_LICENSE_URL; ?>" target="_blank" rel="noopener noreferrer"><?php echo LEGAL_LICENSE; ?></a>
</div>
</div>
+144 -1
View File
@@ -29,7 +29,7 @@ function generateWebSiteJsonLd() {
],
"publisher" => [
"@type" => "Organization",
"name" => "OKI",
"name" => ORGANIZATION_NAME,
"url" => $baseUrl,
"logo" => [
"@type" => "ImageObject",
@@ -69,6 +69,8 @@ function generateVideoObjectJsonLd($videoData, $video) {
? truncateText(strip_tags($video['description']), 300)
: "Regardez cette vidéo sur " . SITE_NAME,
"url" => $videoUrl,
"embedUrl" => PEERTUBE_URL . "/videos/embed/" . $video['id'],
"inLanguage" => "fr-FR",
"thumbnailUrl" => $thumbnailUrl,
"uploadDate" => formatDateISO8601($video['date']),
"duration" => $duration,
@@ -159,6 +161,147 @@ function generateVideoObjectJsonLd($videoData, $video) {
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Génère le JSON-LD pour un podcast (PodcastSeries + PodcastEpisode + AudioObject)
*
* @param array $episodes Épisodes formatés par getCastopodEpisodes()
* @return string JSON-LD pour le podcast, chaîne vide si aucun épisode
*/
function generatePodcastJsonLd($episodes) {
if (empty($episodes)) {
return '';
}
$baseUrl = getBaseUrl();
$first = $episodes[0];
// Informations de la série, déduites du flux RSS
$seriesName = !empty($first['podcastTitle']) ? $first['podcastTitle'] : SITE_NAME;
$seriesUrl = !empty($first['podcastLink']) ? $first['podcastLink'] : $baseUrl;
$seriesImage = !empty($first['image']) ? $first['image'] : $baseUrl . '/img/logo.png';
$webFeed = !empty($first['podcastSlug'])
? rtrim(CASTOPOD_URL, '/') . '/@' . $first['podcastSlug'] . '/feed'
: null;
$series = [
"@type" => "PodcastSeries",
"@id" => $seriesUrl . '#podcast',
"name" => $seriesName,
"url" => $seriesUrl,
"image" => $seriesImage,
"inLanguage" => "fr-FR",
"author" => [
"@type" => "Organization",
"name" => ORGANIZATION_NAME,
"url" => $baseUrl
],
"publisher" => [
"@type" => "Organization",
"name" => SITE_NAME,
"url" => $baseUrl,
"logo" => [
"@type" => "ImageObject",
"url" => $baseUrl . "/img/logo.png"
]
]
];
if ($webFeed) {
$series["webFeed"] = $webFeed;
}
$episodeItems = [];
foreach ($episodes as $episode) {
$item = [
"@type" => "PodcastEpisode",
"name" => $episode['title'],
"url" => $episode['link'],
"partOfSeries" => ["@id" => $seriesUrl . '#podcast']
];
if (!empty($episode['pubDate'])) {
$item["datePublished"] = formatDateISO8601($episode['pubDate']);
}
if (!empty($episode['image'])) {
$item["image"] = $episode['image'];
}
if (!empty($episode['description'])) {
$item["description"] = truncateText($episode['description'], 300);
}
$seconds = parseDurationToSeconds($episode['duration'] ?? '');
if ($seconds > 0) {
$item["timeRequired"] = formatDurationISO8601($seconds);
}
if (!empty($episode['audioUrl'])) {
$audio = [
"@type" => "AudioObject",
"contentUrl" => $episode['audioUrl']
];
$format = guessAudioEncodingFormat($episode['audioUrl']);
if ($format !== null) {
$audio["encodingFormat"] = $format;
}
$item["associatedMedia"] = $audio;
}
$episodeItems[] = $item;
}
$data = [
"@context" => "https://schema.org",
"@graph" => array_merge([$series], $episodeItems)
];
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* Convertit une durée iTunes en secondes
* Formats acceptés : "3600", "90", "MM:SS", "HH:MM:SS"
*
* @param string $duration Durée brute issue du flux RSS
* @return int Durée en secondes (0 si non parsable)
*/
function parseDurationToSeconds($duration) {
$duration = trim((string) $duration);
if ($duration === '') {
return 0;
}
if (strpos($duration, ':') !== false) {
$parts = array_map('intval', explode(':', $duration));
$seconds = 0;
foreach ($parts as $part) {
$seconds = $seconds * 60 + $part;
}
return $seconds;
}
return max(0, (int) $duration);
}
/**
* Déduit le type MIME d'un fichier audio depuis son extension
*
* @param string $url URL du fichier audio
* @return string|null Type MIME (audio/mpeg, audio/mp4, audio/ogg) ou null
*/
function guessAudioEncodingFormat($url) {
$extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH) ?? '', PATHINFO_EXTENSION));
$map = [
'mp3' => 'audio/mpeg',
'm4a' => 'audio/mp4',
'mp4' => 'audio/mp4',
'ogg' => 'audio/ogg',
'opus' => 'audio/ogg',
'wav' => 'audio/wav'
];
return $map[$extension] ?? null;
}
/**
* Génère le JSON-LD pour les fils d'Ariane (BreadcrumbList)
*
+26 -13
View File
@@ -13,6 +13,12 @@ if (defined('COUNTDOWN_ENABLED') && COUNTDOWN_ENABLED === true) {
require_once 'includes/structured-data.php';
// Appliquer les en-têtes de sécurité
setSecurityHeaders();
// Récupérer les épisodes Castopod (réutilisés pour le JSON-LD et l'affichage)
$castopodEpisodes = [];
if (defined('CASTOPOD_ENABLED') && CASTOPOD_ENABLED && defined('CASTOPOD_URL') && !empty(CASTOPOD_URL)) {
$castopodEpisodes = getCastopodEpisodes();
}
?>
<!DOCTYPE html>
<html lang="fr">
@@ -21,6 +27,8 @@ setSecurityHeaders();
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<?php echo generateCSRFToken(); ?>">
<title><?php echo SITE_NAME; ?></title>
<meta name="description" content="<?php echo htmlspecialchars(SITE_DESCRIPTION); ?>">
<link rel="canonical" href="<?php echo getBaseUrl() . '/'; ?>">
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
<link rel="stylesheet" href="css/mastodon-timeline.min.css?v=<?php echo filemtime('css/mastodon-timeline.min.css'); ?>">
@@ -54,9 +62,9 @@ setSecurityHeaders();
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="<?php echo SITE_NAME; ?>">
<meta property="og:description" content="Découvrez notre plateforme multimédia avec des vidéos, des shorts et des directs. Tendances, catégories et contenus exclusifs vous attendent.">
<meta property="og:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">
<meta property="og:description" content="<?php echo htmlspecialchars(SITE_DESCRIPTION); ?>">
<meta property="og:image" content="<?php echo getBaseUrl() . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo getBaseUrl() . '/'; ?>">
<meta property="og:type" content="website">
<meta property="og:site_name" content="<?php echo SITE_NAME; ?>">
<meta property="og:locale" content="fr_FR">
@@ -64,8 +72,8 @@ setSecurityHeaders();
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?php echo SITE_NAME; ?>">
<meta name="twitter:description" content="Découvrez notre plateforme multimédia avec des vidéos, des shorts et des directs. Tendances, catégories et contenus exclusifs vous attendent.">
<meta name="twitter:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<meta name="twitter:description" content="<?php echo htmlspecialchars(SITE_DESCRIPTION); ?>">
<meta name="twitter:image" content="<?php echo getBaseUrl() . '/img/logo.png'; ?>">
<!-- Données structurées JSON-LD pour le site web -->
<?php
@@ -78,6 +86,11 @@ setSecurityHeaders();
];
$breadcrumbJsonLd = generateBreadcrumbJsonLd($breadcrumbs);
outputJsonLd($breadcrumbJsonLd);
// Données structurées du podcast (PodcastSeries + PodcastEpisode)
if (!empty($castopodEpisodes)) {
outputJsonLd(generatePodcastJsonLd($castopodEpisodes));
}
?>
<!-- Script pour éviter le flash en mode sombre -->
@@ -105,6 +118,7 @@ setSecurityHeaders();
<?php include 'includes/sidebar.php'; ?>
<!-- Contenu principal -->
<main class="main-content" id="main-content" role="main">
<h1 class="sr-only"><?php echo SITE_NAME . ' — ' . SITE_DESCRIPTION; ?></h1>
<?php include 'includes/header.php'; ?>
<!-- Hero and Mastodon container -->
<div class="hero-mastodon-wrapper">
@@ -130,8 +144,7 @@ setSecurityHeaders();
</div>
<div class="castopod-episodes-list">
<?php
$castopodEpisodes = getCastopodEpisodes();
// $castopodEpisodes a été récupéré en début de page (JSON-LD + affichage)
if (empty($castopodEpisodes)) {
echo '<div class="castopod-no-episodes">Aucun épisode disponible</div>';
} else {
@@ -390,7 +403,7 @@ setSecurityHeaders();
<section class="video-section" aria-labelledby="shorts-heading">
<div class="section-header">
<div class="section-logo">
<img src="img/logo.png" alt="Logo <?php echo SITE_NAME; ?>" aria-hidden="true">
<img src="img/logo.png" alt="" aria-hidden="true">
</div>
<h2 id="shorts-heading" class="section-title">Shorts</h2>
</div>
@@ -446,7 +459,7 @@ setSecurityHeaders();
<section class="video-section" aria-labelledby="recent-videos-heading">
<header class="section-header">
<div class="section-logo">
<img src="img/logo.png" alt="Logo <?php echo SITE_NAME; ?>" aria-hidden="true">
<img src="img/logo.png" alt="" aria-hidden="true">
</div>
<h2 id="recent-videos-heading" class="section-title">Dernières vidéos</h2>
</header>
@@ -508,7 +521,7 @@ setSecurityHeaders();
<section class="video-section" aria-labelledby="trending-videos-heading">
<header class="section-header">
<div class="section-logo">
<img src="img/logo.png" alt="Logo <?php echo SITE_NAME; ?>" aria-hidden="true">
<img src="img/logo.png" alt="" aria-hidden="true">
</div>
<h2 id="trending-videos-heading" class="section-title">Tendances</h2>
</header>
@@ -526,7 +539,7 @@ setSecurityHeaders();
?>
<article class="video-card" data-video-id="<?php echo $video['id']; ?>">
<div class="video-thumbnail">
<img src="<?php echo $video['thumbnail']; ?>" alt="<?php echo $video['title']; ?>">
<img src="<?php echo htmlspecialchars($video['thumbnail']); ?>" alt="<?php echo htmlspecialchars($video['title']); ?>">
<div class="video-play-icon">
<i class="fas fa-play-circle"></i>
</div>
@@ -577,7 +590,7 @@ setSecurityHeaders();
<section class="video-section" data-category-id="<?php echo $category['id']; ?>" aria-labelledby="category-heading-<?php echo $category['id']; ?>">
<header class="section-header">
<div class="section-logo">
<img src="img/logo.png" alt="Logo <?php echo SITE_NAME; ?>" aria-hidden="true">
<img src="img/logo.png" alt="" aria-hidden="true">
</div>
<h2 id="category-heading-<?php echo $category['id']; ?>" class="section-title"><?php echo htmlspecialchars($category['name']); ?></h2>
</header>
@@ -586,7 +599,7 @@ setSecurityHeaders();
<?php foreach ($category['videos'] as $video): ?>
<article class="video-card" data-video-id="<?php echo $video['id']; ?>">
<div class="video-thumbnail">
<img src="<?php echo $video['thumbnail']; ?>" alt="<?php echo $video['title']; ?>">
<img src="<?php echo htmlspecialchars($video['thumbnail']); ?>" alt="<?php echo htmlspecialchars($video['title']); ?>">
<div class="video-play-icon">
<i class="fas fa-play-circle"></i>
</div>
+18 -16
View File
@@ -1,9 +1,17 @@
<?php
// Inclure la configuration
require_once 'includes/config.php';
// Appliquer les en-têtes de sécurité
setSecurityHeaders();
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mentions Légales - ANNU KUTE CED</title>
<title>Mentions Légales - <?php echo SITE_NAME; ?></title>
<meta name="description" content="Consultez les mentions légales de <?php echo SITE_NAME; ?>. Informations légales, conditions d'utilisation et politique de confidentialité.">
<link rel="canonical" href="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/mentions-legales.php'; ?>">
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
@@ -13,25 +21,25 @@
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#FF0000">
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="Mentions Légales - ANNU KUTE CED">
<meta property="og:description" content="Consultez les mentions légales d'ANNU KUTE CED. Informations légales, conditions d'utilisation et politique de confidentialité du hub multimédia du podcast.">
<meta property="og:title" content="Mentions Légales - <?php echo SITE_NAME; ?>">
<meta property="og:description" content="Consultez les mentions légales de <?php echo SITE_NAME; ?>. Informations légales, conditions d'utilisation et politique de confidentialité.">
<meta property="og:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">
<meta property="og:type" content="website">
<meta property="og:site_name" content="ANNU KUTE CED">
<meta property="og:site_name" content="<?php echo SITE_NAME; ?>">
<meta property="og:locale" content="fr_FR">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Mentions Légales - ANNU KUTE CED">
<meta name="twitter:description" content="Consultez les mentions légales d'ANNU KUTE CED. Informations légales, conditions d'utilisation et politique de confidentialité du hub multimédia du podcast.">
<meta name="twitter:title" content="Mentions Légales - <?php echo SITE_NAME; ?>">
<meta name="twitter:description" content="Consultez les mentions légales de <?php echo SITE_NAME; ?>. Informations légales, conditions d'utilisation et politique de confidentialité.">
<meta name="twitter:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<!-- Script pour éviter le flash en mode sombre -->
<script>
<script nonce="<?php echo getCspNonce(); ?>">
(function() {
const savedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
@@ -44,12 +52,6 @@
</script>
</head>
<body>
<?php
// Inclure la configuration
require_once 'includes/config.php';
// Appliquer les en-têtes de sécurité
setSecurityHeaders();
?>
<?php include 'includes/sidebar.php'; ?>
<!-- Contenu principal -->
<div class="main-content">
@@ -58,9 +60,9 @@
<!-- Section Mentions Légales -->
<div class="section-header">
<div class="section-logo">
<img src="img/logo.png" alt="ANNU KUTE CED">
<img src="img/logo.png" alt="<?php echo SITE_NAME; ?>">
</div>
<h2 class="section-title">Mentions Légales</h2>
<h1 class="section-title">Mentions Légales</h1>
</div>
<div class="info-section">
+13 -6
View File
@@ -53,6 +53,13 @@ if ($resultsCount > 0) {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo !empty($query) ? 'Recherche: ' . htmlspecialchars($query) . ' - ' : 'Recherche - '; ?><?php echo SITE_NAME; ?></title>
<meta name="description" content="<?php echo !empty($query) ? 'Résultats de recherche pour « ' . htmlspecialchars($query) . ' » sur ' . SITE_NAME . '. Découvrez des vidéos correspondantes à votre recherche.' : 'Recherchez des vidéos sur ' . SITE_NAME . '. ' . SITE_DESCRIPTION; ?>">
<?php if (!empty($query)): ?>
<meta name="robots" content="noindex, follow">
<link rel="canonical" href="<?php echo getBaseUrl() . '/recherche.php?q=' . urlencode($query); ?>">
<?php else: ?>
<link rel="canonical" href="<?php echo getBaseUrl() . '/recherche.php'; ?>">
<?php endif; ?>
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
@@ -62,11 +69,11 @@ if ($resultsCount > 0) {
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#FF0000">
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="<?php echo !empty($query) ? 'Recherche: ' . htmlspecialchars($query) . ' - ' : 'Recherche - '; ?><?php echo SITE_NAME; ?>">
<meta property="og:description" content="<?php echo !empty($query) ? 'Résultats de recherche pour \"' . htmlspecialchars($query) . '\" sur ' . SITE_NAME . '. Découvrez des vidéos correspondantes à votre recherche.' : 'Recherchez des vidéos sur ' . SITE_NAME . '. Plateforme multimédia avec un contenu de qualité et exclusif.'; ?>">
<meta property="og:description" content="<?php echo !empty($query) ? 'Résultats de recherche pour « ' . htmlspecialchars($query) . ' » sur ' . SITE_NAME . '. Découvrez des vidéos correspondantes à votre recherche.' : 'Recherchez des vidéos sur ' . SITE_NAME . '. ' . SITE_DESCRIPTION; ?>">
<meta property="og:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<meta property="og:url" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">
<meta property="og:type" content="website">
@@ -76,7 +83,7 @@ if ($resultsCount > 0) {
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?php echo !empty($query) ? 'Recherche: ' . htmlspecialchars($query) . ' - ' : 'Recherche - '; ?><?php echo SITE_NAME; ?>">
<meta name="twitter:description" content="<?php echo !empty($query) ? 'Résultats de recherche pour \"' . htmlspecialchars($query) . '\" sur ' . SITE_NAME . '. Découvrez des vidéos correspondantes à votre recherche.' : 'Recherchez des vidéos sur ' . SITE_NAME . '. Plateforme multimédia avec un contenu de qualité et exclusif.'; ?>">
<meta name="twitter:description" content="<?php echo !empty($query) ? 'Résultats de recherche pour « ' . htmlspecialchars($query) . ' » sur ' . SITE_NAME . '. Découvrez des vidéos correspondantes à votre recherche.' : 'Recherchez des vidéos sur ' . SITE_NAME . '. ' . SITE_DESCRIPTION; ?>">
<meta name="twitter:image" content="<?php echo 'https://' . $_SERVER['HTTP_HOST'] . '/img/logo.png'; ?>">
<?php if (!empty($query) && !empty($currentPageVideos)): ?>
@@ -132,12 +139,12 @@ if ($resultsCount > 0) {
</div>
<?php if (!empty($query)): ?>
<?php if ($isTagSearch): ?>
<h2 class="section-title">Vidéos avec le hashtag : "<?php echo htmlspecialchars($searchTag); ?>"</h2>
<h1 class="section-title">Vidéos avec le hashtag : "<?php echo htmlspecialchars($searchTag); ?>"</h1>
<?php else: ?>
<h2 class="section-title">Résultats pour : "<?php echo htmlspecialchars($query); ?>"</h2>
<h1 class="section-title">Résultats pour : "<?php echo htmlspecialchars($query); ?>"</h1>
<?php endif; ?>
<?php else: ?>
<h2 class="section-title">Rechercher des vidéos</h2>
<h1 class="section-title">Rechercher des vidéos</h1>
<?php endif; ?>
</div>
+6 -1
View File
@@ -120,6 +120,10 @@ if (empty($videoData) || isset($videoData['error'])) {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo !empty($video['title']) ? htmlspecialchars($video['title']) . ' - ' : ''; ?><?php echo SITE_NAME; ?></title>
<meta name="description" content="<?php echo !empty($video['description']) ? htmlspecialchars(substr(strip_tags($video['description']), 0, 200)) . '...' : 'Regardez cette vidéo sur ' . SITE_NAME; ?>">
<?php if (!isset($videoNotFound) && !empty($video)): ?>
<link rel="canonical" href="<?php echo getBaseUrl() . '/video.php?id=' . $video['id']; ?>">
<?php endif; ?>
<link rel="stylesheet" href="css/styles.css?v=<?php echo filemtime('css/styles.css'); ?>">
<link rel="stylesheet" href="css/video-page.css?v=<?php echo filemtime('css/video-page.css'); ?>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
@@ -130,7 +134,7 @@ if (empty($videoData) || isset($videoData['error'])) {
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<meta name="theme-color" content="#ffffff">
<meta name="theme-color" content="#FF0000">
<!-- Meta tags pour le partage sur les réseaux sociaux -->
<meta property="og:title" content="<?php echo !empty($video['title']) ? htmlspecialchars($video['title']) : 'Vidéo'; ?> - <?php echo SITE_NAME; ?>">
@@ -141,6 +145,7 @@ if (empty($videoData) || isset($videoData['error'])) {
<meta property="og:url" content="<?php echo (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>">
<meta property="og:type" content="video.other">
<meta property="og:site_name" content="<?php echo SITE_NAME; ?>">
<meta property="og:locale" content="fr_FR">
<!-- Meta tags pour Twitter -->
<meta name="twitter:card" content="summary_large_image">