cd /chemin/vers/dokuwiki/lib/plugins/
mkdir namespacelogo
cd namespacelogo
touch plugin.info.txt action.php helper.php style.less
chmod 644 *.php *.less
chmod 755 ../namespacelogo
base namespacelogo
author Votrenom
email votre@email.com
date 2026-03-16
name Namespace Logo
desc Affiche un logo spécifique par namespace avec fallback hiérarchique
register_hook('TPL_HEADER_OUTPUT', 'BEFORE', $this, '_injectNamespaceLogo');
}
/**
* Injecter le logo du namespace dans l'en-tête
*/
public function _injectNamespaceLogo(Doku_Event $event, $param) {
global $ID;
// Récupérer le namespace actuel
$ns = getNS($ID);
// Trouver le chemin du logo (avec fallback hiérarchique)
$logoPath = $this->_findLogoPath($ns);
if ($logoPath) {
// Générer l'URL de l'image
$imgUrl = ml($logoPath);
// Créer le HTML du logo
$logoHtml = '' .
'
_extractNamespaceFromPath($logoPath)) . '" ' .
'class="ns-logo" ' .
'id="namespace-logo" />' .
'';
// Ajouter à la variable globale que le template pourra utiliser
$GLOBALS['NS_LOGO_HTML'] = $logoHtml;
}
}
/**
* Trouver le chemin du logo avec fallback hiérarchique
* @param string $ns Namespace de départ
* @return string|null Chemin du logo ou null si aucun trouvé
*/
protected function _findLogoPath($ns) {
// Liste des namespaces à vérifier (du plus spécifique au plus général)
$namespacesToCheck = $this->_buildNamespaceHierarchy($ns);
// Vérifier chaque namespace dans l'ordre
foreach ($namespacesToCheck as $checkNs) {
foreach ($this->supportedFormats as $format) {
$path = ':' . $checkNs . ':' . $format;
if (@media_exists($path)) {
return $path;
}
}
}
return null;
}
/**
* Construire la hiérarchie des namespaces pour le fallback
* Ex: 'a:b:c' -> ['a:b:c', 'a:b', 'a', '']
* @param string $ns Namespace de départ
* @return array Liste des namespaces à vérifier
*/
protected function _buildNamespaceHierarchy($ns) {
$hierarchy = [];
// Ajouter le namespace actuel
if (!empty($ns)) {
$hierarchy[] = $ns;
}
// Remonter dans la hiérarchie
$parts = explode(':', $ns);
while (count($parts) > 1) {
array_pop($parts);
$parentNs = implode(':', $parts);
if (!empty($parentNs)) {
$hierarchy[] = $parentNs;
}
}
// Ajouter la racine (vide) pour le fallback global
$hierarchy[] = '';
return $hierarchy;
}
/**
* Extraire le namespace du chemin du logo pour l'attribut alt
* @param string $path Chemin du logo (ex: ':a:b:logo.png')
* @return string Nom du namespace
*/
protected function _extractNamespaceFromPath($path) {
// Supprimer les deux-points initiaux et le nom du fichier
$cleanPath = trim($path, ':');
$parts = explode(':', $cleanPath);
// Retirer le dernier élément (logo.png, etc.)
array_pop($parts);
return implode(' : ', $parts);
}
}
?>
_findLogoPath($ns);
if ($logoPath) {
$imgUrl = ml($logoPath);
$nsName = $this->_extractNamespaceFromPath($logoPath);
return '
';
}
return null;
}
/**
* Vérifier si un logo existe pour un namespace donné
* @param string $ns Namespace à vérifier
* @return bool
*/
public function hasLogo($ns) {
return $this->_findLogoPath($ns) !== null;
}
/**
* Obtenir le chemin du logo pour un namespace spécifique
* @param string $ns Namespace
* @return string|null
*/
public function getLogoPath($ns) {
return $this->_findLogoPath($ns);
}
/**
* Trouver le chemin du logo avec fallback hiérarchique
* @param string $ns Namespace de départ
* @return string|null
*/
protected function _findLogoPath($ns) {
$hierarchy = $this->_buildNamespaceHierarchy($ns);
foreach ($hierarchy as $checkNs) {
foreach ($this->supportedFormats as $format) {
$path = ':' . $checkNs . ':' . $format;
if (@media_exists($path)) {
return $path;
}
}
}
return null;
}
/**
* Construire la hiérarchie des namespaces
* @param string $ns
* @return array
*/
protected function _buildNamespaceHierarchy($ns) {
$hierarchy = [];
if (!empty($ns)) {
$hierarchy[] = $ns;
}
$parts = explode(':', $ns);
while (count($parts) > 1) {
array_pop($parts);
$parentNs = implode(':', $parts);
if (!empty($parentNs)) {
$hierarchy[] = $parentNs;
}
}
$hierarchy[] = '';
return $hierarchy;
}
/**
* Extraire le namespace du chemin
* @param string $path
* @return string
*/
protected function _extractNamespaceFromPath($path) {
$cleanPath = trim($path, ':');
$parts = explode(':', $cleanPath);
array_pop($parts);
return implode(' : ', $parts);
}
}
?>
/* Container du logo namespace */
.ns-logo-container {
margin: 1em 0;
text-align: center;
padding: 0.5em;
}
/* Image du logo */
.ns-logo {
max-width: 200px;
max-height: 100px;
height: auto;
width: auto;
display: inline-block;
}
/* Responsive */
@media screen and (max-width: 768px) {
.ns-logo {
max-width: 150px;
max-height: 80px;
}
}
/* Indicateur visuel du fallback (optionnel) */
.ns-logo-container.fallback-parent {
border-left: 3px solid #ccc;
padding-left: 1em;
}