feat: thème WordPress sur mesure Union Locale CGT Foix Haute-Ariège (v1.2.0)
26
.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Système
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Éditeurs & IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.sublime-workspace
|
||||||
|
*.sublime-project
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Logs & temporaires
|
||||||
|
*.log
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# Dépendances locales éventuelles (non requises par le thème)
|
||||||
|
node_modules/
|
||||||
|
vendor/
|
||||||
|
composer.phar
|
||||||
41
404.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit de page d'erreur 404 utile avec recherche et liens directs vers l'UL (404.php).
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="cgt-section cgt-section--white cgt-404">
|
||||||
|
<div class="cgt-container--narrow">
|
||||||
|
<span class="cgt-404__code">404</span>
|
||||||
|
<h1><?php esc_html_e( 'Cette page est introuvable', 'cgt-fha' ); ?></h1>
|
||||||
|
<p style="color:var(--text-muted); max-width:560px; margin-inline:auto;">
|
||||||
|
<?php esc_html_e( 'Le lien que vous avez suivi a peut-être été déplacé ou n\'existe plus. Effectuez une recherche ou accédez directement aux services de l\'Union Locale CGT Foix Haute-Ariège.', 'cgt-fha' ); ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form role="search" method="get" class="cgt-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
|
||||||
|
<label for="cgt-404-search" class="screen-reader-text"><?php esc_html_e( 'Rechercher sur le site', 'cgt-fha' ); ?></label>
|
||||||
|
<input type="search" id="cgt-404-search" name="s" placeholder="<?php esc_attr_e( 'Rechercher une actualité, un droit…', 'cgt-fha' ); ?>" />
|
||||||
|
<button type="submit" class="cgt-btn cgt-btn--primary"><?php esc_html_e( 'Rechercher', 'cgt-fha' ); ?></button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="cgt-network-strip">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="cgt-network-link">Accueil</a>
|
||||||
|
<a href="<?php echo esc_url( cgt_fha_get_local_news_archive_url() ); ?>" class="cgt-network-link">Actualités locales</a>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['calendar_url'] ); ?>" class="cgt-network-link">Calendrier</a>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['contact_url'] ); ?>" class="cgt-network-link">Urgence salarié / Contact</a>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['join_url'] ); ?>" class="cgt-network-link">Rejoindre la CGT</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
211
AGENTS.md
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
# AGENTS.md — CAHIER DES CHARGES COMPLET : THÈME WORDPRESS `cgt-wp-theme`
|
||||||
|
|
||||||
|
**Projet :** Site officiel de l'Union Locale CGT Foix Haute-Ariège (`https://cgt-fha.fr/`)
|
||||||
|
**Dépôt Gitea officiel :** `https://git.cgt-fha.fr/Union_Locale_CGT_Foix_Haute-Ariege/cgt-wp-theme.git`
|
||||||
|
**Chemin de déploiement VPS :** `/var/www/fastuser/data/www/cgt-fha.fr/wp-content/themes/cgt-fha/`
|
||||||
|
**Ressource Skills locale :** `../skills/` (`../skills/wp-performance/SKILL.md` et `../skills/wp-block-themes/SKILL.md`)
|
||||||
|
**Ressource graphique locale :** `../ressources/banniere union locale noir.png` (à copier dans `assets/img/banniere-ul-noir.png` et utiliser comme logo par défaut de l'en-tête)
|
||||||
|
**Maquette de référence visuelle :** L'utilisateur fournit l'image de maquette validée en pièce jointe. Respecte fidèlement sa hiérarchie visuelle, ses proportions, ses espacements et son style graphique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. PHILOSOPHIE TECHNIQUE, SKILLS & RÈGLES D'ARCHITECTURE
|
||||||
|
Tu es l'unique développeur de ce thème WordPress sur mesure. Ce thème remplace un thème généraliste bridé (*Neve*) pour offrir une souveraineté totale, une vitesse de chargement maximale et une ergonomie pensée pour les salariés et militants de Haute-Ariège[cite: 6].
|
||||||
|
|
||||||
|
- **Utilisation des Skills (`../skills/`) :**
|
||||||
|
- Lis et applique les bonnes pratiques définies dans `../skills/wp-performance/SKILL.md` (optimisation des requêtes, cache Transients, WP-Cron) et `../skills/wp-block-themes/SKILL.md` (uniquement pour la structure propre de `theme.json`)[cite: 6].
|
||||||
|
- **Restriction stricte :** Ne génère **jamais** de blocs Gutenberg personnalisés en React (`@wordpress/scripts`, `block.json` compilés) ni de Full Site Editing complet[cite: 6].
|
||||||
|
- **Architecture : Thème PHP Classique / Hybride Moderne :**
|
||||||
|
- Utilise des gabarits PHP 8.x propres, typés et sécurisés (`header.php`, `footer.php`, `front-page.php`, `home.php`, `single.php`, `page.php`, `archive.php`, `404.php`)[cite: 6].
|
||||||
|
- Utilise `theme.json` uniquement pour déclarer la palette de couleurs CGT et les typographies dans l'éditeur d'articles[cite: 6].
|
||||||
|
- **Zéro dépendance externe lourde (RGPD & Performance) :**
|
||||||
|
- CSS moderne natif (`CSS Custom Properties`, `CSS Grid`, `Flexbox`, mobile-first). Aucune bibliothèque CSS externe (pas de Bootstrap ni Tailwind CDN)[cite: 6].
|
||||||
|
- JavaScript *Vanilla* ES6 minimaliste uniquement pour le menu mobile accessible et les onglets de l'admin (pas de jQuery)[cite: 6].
|
||||||
|
- Aucune police Google Fonts chargée via CDN tiers : utilise des polices système modernes (`system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`) ou des fichiers hébergés localement[cite: 6].
|
||||||
|
- **100 % Modifiable sans toucher au code :**
|
||||||
|
- En dehors des articles locaux (publiés dans WordPress) et des actualités confédérales extraites automatiquement depuis `cgt.fr`, **tous les textes, images, icônes, liens, boutons et coordonnées du thème doivent être modifiables depuis l'administration WordPress** (*Apparence > Réglages UL CGT* + *Apparence > Menus* + *Médiathèque*).
|
||||||
|
- **Pré-remplissage obligatoire par défaut :** Toutes les options doivent posséder des valeurs par défaut complètes (définies via `wp_parse_args()`) afin que le site soit immédiatement fonctionnel et complet dès l'activation du thème, sans aucune zone vide.
|
||||||
|
- **Intégration propre avec les extensions sœurs (Gitea) :**
|
||||||
|
- Le thème gère le visuel, le SEO/OpenGraph de base, le bandeau de mobilisation et l'encart d'actualités confédérales[cite: 6].
|
||||||
|
- Il prévoit des hooks/emplacements propres (`do_action(...)` / support de shortcodes) pour accueillir les sorties des extensions `cgt-wp-calendar` (Agenda) et `cgt-wp-forms` (Formulaires Défense, Adhésion, Formation), tout en affichant un rendu cohérent même si ces extensions ne sont pas encore activées[cite: 6].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. IDENTITÉ VISUELLE & CHARTE GRAPHIQUE
|
||||||
|
- **Couleur primaire (Rouge CGT) :** `--cgt-red: #d20012;` (hover : `--cgt-red-dark: #a8000e;`)[cite: 7]
|
||||||
|
- **Couleurs neutres & surfaces :**
|
||||||
|
- Fond principal : `--bg-main: #ffffff;`
|
||||||
|
- Fond alterné (section Confédérale / Formation / Footer) : `--bg-soft: #f1f3f5;`
|
||||||
|
- Barre supérieure contact : `--bg-topbar: #1c1e21;`
|
||||||
|
- Texte principal : `--text-main: #1a1a1a;`
|
||||||
|
- Texte secondaire : `--text-muted: #4a5568;`
|
||||||
|
- Bordures des cartes : `--border-card: #cbd5e1;`
|
||||||
|
- Rayons d'arrondi : `--radius-card: 12px;` à `14px`, boutons pilules `--radius-pill: 999px;`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. EN-TÊTE (`header.php`) & NAVIGATION
|
||||||
|
Respecte exactement le haut de la maquette de référence :
|
||||||
|
1. **Barre supérieure (`topbar`) :**
|
||||||
|
- Fond sombre (`#1c1e21`), texte blanc fin (`13px`).
|
||||||
|
- À gauche : icône téléphone + lien `tel:` (`07 60 49 64 69` par défaut) et icône enveloppe + lien `mailto:` (`union-locale@cgt-fha.fr` par défaut)[cite: 7].
|
||||||
|
- À droite : icônes réseaux sociaux (Facebook officiel de l'UL `https://www.facebook.com/profile.php?id=61552410568856`, etc., éditables dans les réglages)[cite: 7].
|
||||||
|
2. **Bandeau d'Alerte Mobilisation Auto-Expirant :**
|
||||||
|
- Bandeau pleine largeur sur fond rouge CGT (`#d20012`), texte blanc centré en gras (ex. : `MOBILISATION : Grève et manifestation à Foix - Allées de Villote`), cliquable si une URL est renseignée[cite: 6].
|
||||||
|
- **Condition stricte d'affichage :** S'affiche uniquement si la case *Activer le bandeau* est cochée **ET** que l'horodatage actuel (`current_time('timestamp')`) est strictement inférieur à la *Date et heure d'expiration* configurée dans l'admin[cite: 6]. Passé ce délai, le bandeau disparaît automatiquement[cite: 6].
|
||||||
|
3. **Barre de Navigation Principale (`<header>`) :**
|
||||||
|
- Fond blanc, hauteur confortable, ombre légère au défilement.
|
||||||
|
- À gauche : Logo officiel de l'Union Locale CGT Foix Haute-Ariège (modifiable via `custom_logo` dans WordPress, avec fallback SVG/PNG local propre).
|
||||||
|
- À droite : Menu principal horizontal (`wp_nav_menu` : **Accueil**, **Actualités**, **Calendrier**, **Contact**), avec soulignement rouge sur l'élément actif.
|
||||||
|
- **IMPORTANT :** Ne mets **PAS** de bouton rouge « Syndiquez-vous » dans cette barre de navigation (pour éviter la répétition avec le Hero juste en dessous).
|
||||||
|
- Sur mobile (`< 768px`) : bouton menu hamburger accessible (`aria-expanded="false"`, contrôle clavier `Escape`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. PAGE D'ACCUEIL (`front-page.php`) — STRUCTURE COMPLÈTE
|
||||||
|
|
||||||
|
La page d'accueil s'articule en **7 sections verticales** dans cet ordre exact :
|
||||||
|
|
||||||
|
### Section 1 : Bannière Hero Plein Écran (Ancrage Territorial & Action)
|
||||||
|
- **Visuel de fond :** Image panoramique des montagnes d'Ariège / territoire (configurable dans l'admin avec une image par défaut intégrée dans `assets/img/hero-ariege.jpg`), recouverte d'un voile sombre dégradé (`rgba(15, 18, 22, 0.62)`) assurant une lisibilité parfaite du texte blanc.
|
||||||
|
- **Contenu centré verticalement et horizontalement :**
|
||||||
|
- Titre principal (`<h1>`, blanc, grand, gras, 2 lignes) :
|
||||||
|
`Union Locale CGT Foix Haute-Ariège`
|
||||||
|
`Votre syndicat de proximité !`
|
||||||
|
- Citation centrée en dessous (blanc doux, italique, éditable dans l'admin) :
|
||||||
|
`« La régression sociale ne se négocie pas, elle se combat ! » — Henri Krasucki, Secrétaire Général de la CGT de 1982 à 1992`
|
||||||
|
- **Deux boutons d'action centrés côte à côte** (`display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap;`) :
|
||||||
|
1. Bouton gauche (fond blanc `#ffffff`, texte noir `#1a1a1a`, coins arrondis `8px`, gras) : **« J'ai besoin d'aide »** (lien configurable, par défaut vers la page Contact / Urgence salarié)[cite: 6].
|
||||||
|
2. Bouton droit (fond sombre translucide ou rouge foncé, bordure blanche/rouge, texte blanc, coins arrondis `8px`, gras) : **« Rejoindre la CGT »** (lien configurable, par défaut vers la page Syndiquez-vous)[cite: 6].
|
||||||
|
|
||||||
|
### Section 2 : Module « À QUOI NOUS SERVONS ? » (3 Cartes de Mission)
|
||||||
|
Placé **immédiatement sous le Hero et avant les actualités** (fond blanc `#ffffff`) :
|
||||||
|
- **Titre de section :** `À QUOI NOUS SERVONS ?` centré en majuscules (`<h2>`).
|
||||||
|
- **Grille 3 colonnes** (`grid-template-columns: repeat(3, 1fr); gap: 1.5rem;`, 1 colonne sur mobile) :
|
||||||
|
- Chaque carte possède un fond blanc, une bordure fine (`1px solid #cbd5e1`), des coins arrondis (`border-radius: 12px`), un padding généreux (`1.75rem`) et un contenu centré :
|
||||||
|
1. **Carte 1 :** Icône poing levé / collectif (SVG propre) • Titre `S'ORGANISER` • Texte par défaut : *« Construire le syndicat dans votre entreprise, préparer les élections CSE et ne plus rester isolé face à l'employeur. »*
|
||||||
|
2. **Carte 2 :** Icône bouclier (SVG propre) • Titre `SE DÉFENDRE` • Texte par défaut : *« Faire respecter vos droits, vos salaires et vos conditions de travail, avec l'appui de nos conseillers du salarié et juristes. »*
|
||||||
|
3. **Carte 3 :** Icône bulles d'échange / livre (SVG propre) • Titre `S'INFORMER & SE FORMER` • Texte par défaut : *« Connaître les actualités des luttes en Haute-Ariège et bénéficier de vos droits à la formation syndicale (CFESES). »*
|
||||||
|
- *Note :* Les icônes (sélecteur parmi une bibliothèque SVG intégrée), titres et textes de ces 3 cartes sont modifiables dans l'admin WordPress.
|
||||||
|
|
||||||
|
### Section 3 : Vitrine 1 — « SUR LE TERRAIN EN HAUTE-ARIÈGE » (Actualités Locales)
|
||||||
|
- **Priorité éditoriale locale :** Affiche automatiquement les **3 derniers articles publiés** dans le WordPress de l'UL (`WP_Query` sur `post_type => 'post'`, `posts_per_page => 3`)[cite: 6].
|
||||||
|
- **Titre de section :** `SUR LE TERRAIN EN HAUTE-ARIÈGE` centré en majuscules (`<h2>`).
|
||||||
|
- **Mise en page des 3 cartes** (fidèle à la maquette) :
|
||||||
|
- Grille 3 colonnes (`gap: 1.5rem`).
|
||||||
|
- Image à la une en haut avec coins arrondis (`border-radius: 12px; height: 190px; object-fit: cover; width: 100%;`), avec fallback SVG propre si un article n'a pas d'image.
|
||||||
|
- Juste sous l'image : une pilule rouge CGT (`background: #d20012; color: #fff; border-radius: 999px; font-size: 12px; padding: 2px 10px;`) affichant la catégorie principale (ex. *Mobilisation*, *Vie syndicale*) suivie de la date de publication (`d.m.Y`).
|
||||||
|
- Titre de l'article en gras (`18px`) cliquable vers `single.php`.
|
||||||
|
- Extrait nettoyé (`wp_trim_words`, ~20 mots).
|
||||||
|
- **Pied de section :** Bouton lien discret centré *« Voir toutes les actualités locales → »* vers la page des articles (`get_permalink(get_option('page_for_posts'))`), suivi du hook `do_action('cgt_fha_after_local_news');` permettant d'injecter les prochains rendez-vous de `cgt-wp-calendar`[cite: 6].
|
||||||
|
|
||||||
|
### Section 4 : Vitrine 2 — « ACTUALITÉ CONFÉDÉRALE » (Récupération automatique `cgt.fr`)
|
||||||
|
- **Fond de section :** Gris très doux (`#f1f3f5`) pour bien la distinguer des actualités locales.
|
||||||
|
- **Titre de section :** `ACTUALITÉ CONFÉDÉRALE` centré en majuscules (`<h2>`).
|
||||||
|
- **Moteur PHP (`inc/class-cgt-confederal-feed.php`) :**
|
||||||
|
- Interroge `https://www.cgt.fr/` via `wp_remote_get()` (timeout 10s, User-Agent propre) et parse le HTML avec `DOMDocument` + `DOMXPath` (sans polluer `wp_posts`) :
|
||||||
|
- **1 article `featured` (« À la une ») :** extrait depuis la section *"à la une de la cgt"* (`title`, `summary`, `image_url` convertie en URL absolue `https://www.cgt.fr/...`, `category`, `url`).
|
||||||
|
- **3 articles `latest` (`ARTICLE 1`, `ARTICLE 2`, `ARTICLE 3`) :** extraits depuis les 3 premiers articles de la section suivante *"mais aussi..."* (complétés via `https://www.cgt.fr/actualites` si un résumé est manquant).
|
||||||
|
- **Fallback de sécurité :** Si la page d'accueil `cgt.fr` échoue ou change de structure DOM, bascule automatiquement sur les 4 premiers articles de `https://www.cgt.fr/actualites` (le 1er devient `featured`, les 3 suivants deviennent `latest`).
|
||||||
|
- **Cache & WP-Cron :** Stockage dans le transient `cgt_fha_confederal_feed` (expiration 3h) + sauvegarde de secours `cgt_fha_confederal_feed_backup` conservée en cas d'indisponibilité réseau. Événement `WP-Cron` toutes les 2 heures + bouton *"Actualiser les actus confédérales"* dans la barre d'admin WordPress (`admin_bar_menu`).
|
||||||
|
- **Rendu HTML/CSS fidèle à la maquette :**
|
||||||
|
- **Bloc supérieur « À LA UNE » :**
|
||||||
|
- Conteneur centré (`max-width: 880px; margin: 0 auto 2.5rem auto;`), disposition horizontale Flexbox (`align-items: center`).
|
||||||
|
- À gauche (`flex: 0 0 58%`) : Image de l'article (`border-radius: 14px; height: 290px; object-fit: cover;`) avec un badge overlay discret en bas à droite `À LA UNE`.
|
||||||
|
- À droite (`flex: 1; margin-left: -40px; position: relative; z-index: 2;`) : **Boîte blanche arrondie chevauchant le bord droit de l'image** (`background: #fff; border: 1px solid #cbd5e1; border-radius: 14px; padding: 1.75rem; box-shadow: 0 10px 25px rgba(0,0,0,0.06); text-align: center;`) contenant :
|
||||||
|
- Le titre de l'article (ou surtitre `À LA UNE` + titre).
|
||||||
|
- La description / chapô nettoyé.
|
||||||
|
- Le bouton pilule encadré (`border: 1.5px solid #1a1a1a; border-radius: 999px; padding: 6px 28px; font-weight: 700;`) : **« LIRE SUR CGT.FR ↗ »** (`target="_blank" rel="noopener noreferrer"`).
|
||||||
|
- *Responsive mobile (`< 768px`) :* `flex-direction: column`, `margin-left: 0`, `margin-top: -24px`.
|
||||||
|
- **Grille inférieure (3 colonnes : ARTICLE 1, ARTICLE 2, ARTICLE 3) :**
|
||||||
|
- Grille CSS `grid-template-columns: repeat(3, 1fr); gap: 1.5rem;` (1 colonne sous `768px`).
|
||||||
|
- Chaque carte affiche l'image en haut (`height: 190px; width: 100%; object-fit: cover; border-radius: 14px;`), puis une **boîte blanche arrondie qui remonte par-dessus le bas de l'image** (`margin-top: -24px; position: relative; z-index: 2; background: #fff; border: 1px solid #cbd5e1; border-radius: 14px; padding: 1.25rem; box-shadow: 0 6px 18px rgba(0,0,0,0.05); display: flex; flex-direction: column; text-align: center; flex: 1;`) contenant :
|
||||||
|
- Le titre de l'article en gras.
|
||||||
|
- La description courte (~120 caractères).
|
||||||
|
- En bas (`margin-top: auto; padding-top: 1rem;`), le bouton pilule encadré **« LIEN ↗ »** (`target="_blank" rel="noopener noreferrer"`).
|
||||||
|
|
||||||
|
### Section 5 : Parcours « SALARIÉS ISOLÉS & TPE : VOUS N'ÊTES PAS SEULS »
|
||||||
|
- **Fond :** Blanc (`#ffffff`).
|
||||||
|
- **Contenu (entièrement éditable dans l'admin) :**
|
||||||
|
- Bloc pédagogique destiné aux salariés des petites entreprises (< 11 salariés), commerces, artisanat ou chantiers sans CSE[cite: 6].
|
||||||
|
- Met en avant la **confidentialité absolue** de toute démarche vis-à-vis de l'employeur, le rôle du syndicat **Multipros**, et l'accompagnement par les **Conseillers du Salarié** lors des entretiens préalables[cite: 6].
|
||||||
|
- Bouton d'action rouge CGT : *« Contacter l'UL en toute confidentialité »*[cite: 6].
|
||||||
|
|
||||||
|
### Section 6 : Vie Militante, Formation Syndicale (CFESES) & Appli Mobile
|
||||||
|
- **Fond :** Gris doux (`#f1f3f5`).
|
||||||
|
- **Grille 2 colonnes (`grid-template-columns: 1fr 1fr; gap: 2rem;`) :**
|
||||||
|
1. **Colonne gauche — Formation Syndicale (CFESES) :** Rappelle le droit légal de chaque salarié au **Congé de Formation Économique, Sociale, Environnementale et Syndicale** (maintien de salaire, demande à remettre à l'employeur 30 jours avant) et l'aide à la vie syndicale[cite: 6, 8].
|
||||||
|
2. **Colonne droite — L'Application Mobile UL CGT Foix Haute-Ariège :** Présente l'application Android/KMP (actualités locales, alertes mobilisation Push, carte de syndiqué virtuelle & 13 timbres 100 % hors-ligne) avec emplacement pour le lien de téléchargement direct (`.apk` / Play Store) et l'image QR Code (configurables dans l'admin)[cite: 8].
|
||||||
|
|
||||||
|
### Section 7 : Réseau Syndical CGT
|
||||||
|
- **Fond :** Blanc (`#ffffff`).
|
||||||
|
- Bandeau de liens structurés vers l'écosystème confédéral et départemental : **UD CGT 09**, **Confédération CGT (`cgt.fr`)**, **La NVO (`nvo.fr`)**, **IHS CGT**, **INDECOSA-CGT**[cite: 6].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. PIED DE PAGE (`footer.php`) — SOUVERAIN & PRATIQUE
|
||||||
|
- **Aucune mention** *"Propulsé par WordPress"* ou *"Thème..."*[cite: 6].
|
||||||
|
- **Fond sombre (`#1c1e21`), texte blanc/gris clair, grille 3 colonnes :**
|
||||||
|
1. **Union Locale CGT Foix Haute-Ariège :** Logo (version claire/monochrome), courte présentation, et appel militant : *« Une lutte dans votre entreprise, une info à partager ? Contactez l'UL »*.
|
||||||
|
2. **Nos Locaux & Permanences (visible sur 100 % des pages) :**[cite: 6]
|
||||||
|
- Adresse : `Espace Sabart, 10 Av. de l'Ayroule, 09400 Tarascon-sur-Ariège` (modifiable dans l'admin)[cite: 7].
|
||||||
|
- Téléphone cliquable : `07 60 49 64 69`[cite: 7]
|
||||||
|
- Email cliquable : `union-locale@cgt-fha.fr`[cite: 7]
|
||||||
|
- Horaires des permanences d'accueil et juridiques (éditables)[cite: 6].
|
||||||
|
- Lien vers la page Facebook officielle de l'UL[cite: 7].
|
||||||
|
3. **Accès rapides & Mentions :** Liens vers *Actualités*, *Calendrier*, *Se syndiquer*, *Urgence salarié*, *Mentions légales & Confidentialité*.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. PANNEAU D'ADMINISTRATION WORDPRESS (`inc/theme-options.php`)
|
||||||
|
Crée une page de réglages complète et intuitive dans **Apparence > Réglages UL CGT** (organisée en onglets propres sans dépendance JS externe) permettant de modifier sans coder :
|
||||||
|
1. **Onglet 1 — Identité & Coordonnées :** Téléphone, E-mail, Adresse des locaux, Horaires des permanences, URL Facebook, URL page *Syndiquez-vous*, URL page *Besoin d'aide / Contact*.
|
||||||
|
2. **Onglet 2 — Bandeau Mobilisation :** Case *Activer*, Texte du mot d'ordre & lieu, Lien URL optionnel, Champ `datetime-local` d'expiration automatique[cite: 6].
|
||||||
|
3. **Onglet 3 — Page d'accueil (Hero & Blocs statiques) :**
|
||||||
|
- Sélecteur d'image de fond du Hero (via la Médiathèque WP `wp_enqueue_media()`), Titre H1, Citation, Libellés et liens des 2 boutons du Hero.
|
||||||
|
- Champs pour les 3 cartes *« À quoi nous servons ? »* (choix d'icône SVG, titre, description pour chaque carte).
|
||||||
|
- Champs pour les blocs *Salariés isolés / TPE*, *Formation CFESES* et *Application Mobile* (URL APK/Store + sélecteur image QR Code + cases pour afficher/masquer chaque bloc)[cite: 6, 8].
|
||||||
|
4. **Onglet 4 — Flux Confédéral (`cgt.fr`) :** État du cache actuel (date de dernière synchronisation, aperçu de l'article *À la une* en cache) et bouton de rafraîchissement manuel immédiat.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. SEO LOCAL, OPENGRAPH & PERFORMANCE (`inc/seo-performance.php`)
|
||||||
|
1. **Balises `<title>` et `<meta name="description">` :**
|
||||||
|
- Sur la page d'accueil : `Union Locale CGT Foix Haute-Ariège | Défense des salariés et action syndicale`[cite: 6].
|
||||||
|
- Sur les articles et pages : `[Titre] | Union Locale CGT Foix Haute-Ariège` + meta description extraite automatiquement du contenu nettoyé[cite: 6].
|
||||||
|
2. **Balises OpenGraph :** Injection automatique de `og:title`, `og:description`, `og:url`, `og:type`, `og:locale` (`fr_FR`) et `og:image` (image à la une ou image Hero par défaut) pour des aperçus propres sur Facebook, WhatsApp et SMS[cite: 6].
|
||||||
|
3. **Alerte Indexation Admin :** Si `get_option('blog_public') == '0'`, affiche une alerte rouge dans le tableau de bord WordPress invitant à autoriser l'indexation dans *Réglages > Lecture*[cite: 6].
|
||||||
|
4. **Optimisation & Nettoyage :** Suppression de `wp-emoji` et `wp-embed`, ajout de `loading="lazy"` sur les images hors ligne de flottaison, échappement systématique (`esc_html`, `esc_url`, `esc_attr`, `wp_kses_post`)[cite: 6].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. GESTION DE VERSIONS & PUBLICATION GITEA
|
||||||
|
- **Dépôt distant :** `https://git.cgt-fha.fr/Union_Locale_CGT_Foix_Haute-Ariege/cgt-wp-theme.git` (branche principale : `main`).
|
||||||
|
- **Fichier `.gitignore` :** Crée un fichier `.gitignore` propre à la racine pour exclure les fichiers système (`.DS_Store`, `Thumbs.db`), les éditeurs (`.vscode/`, `.idea/`), et d'éventuels dossiers temporaires, tout en conservant le code source du thème et le fichier `AGENTS.md`.
|
||||||
|
- **Compatibilité déploiement VPS :** Assure-toi que tous les chemins dans le thème utilisent exclusivement les fonctions natives WordPress (`get_template_directory()`, `get_template_directory_uri()`) afin que le déploiement automatisé vers `/var/www/fastuser/data/www/cgt-fha.fr/wp-content/themes/cgt-fha/` fonctionne sans aucune dépendance de chemin en dur[cite: 6].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. ARBORESCENCE DES FICHIERS À GÉNÉRER
|
||||||
|
```text
|
||||||
|
/
|
||||||
|
├── AGENTS.md # Ce cahier des charges
|
||||||
|
├── .gitignore # Exclusions propres pour Gitea
|
||||||
|
├── style.css # En-tête thème WP + Variables CSS + Design System complet
|
||||||
|
├── theme.json # Palette couleurs CGT (#d20012) & réglages éditeur
|
||||||
|
├── functions.php # Chargement des modules, supports WP, menus, enqueues
|
||||||
|
├── header.php # Topbar, Bandeau Mobilisation auto-expirant, Nav responsive
|
||||||
|
├── footer.php # Footer 3 colonnes avec coordonnées Espace Sabart & liens CGT
|
||||||
|
├── front-page.php # Page d'accueil complète (7 sections fidèles à la maquette)
|
||||||
|
├── home.php # Liste paginée des actualités locales de l'UL
|
||||||
|
├── single.php # Gabarit d'article local (partage social, catégorie, navigation)
|
||||||
|
├── page.php # Gabarit de page standard (Contact, Calendrier, Syndiquez-vous...)
|
||||||
|
├── archive.php # Archives par catégorie/étiquette locale
|
||||||
|
├── 404.php # Page d'erreur 404 utile avec recherche et liens vers l'UL
|
||||||
|
├── inc/
|
||||||
|
│ ├── class-cgt-confederal-feed.php # Scraper cgt.fr + cache Transients + WP-Cron + rendu wireframe
|
||||||
|
│ ├── theme-options.php # Page d'admin WP : Réglages UL CGT (onglets + médias WP)
|
||||||
|
│ └── seo-performance.php # Titres SEO locaux, OpenGraph, alerte indexation, nettoyage WP
|
||||||
|
└── assets/
|
||||||
|
├── js/main.js # Menu mobile accessible & onglets admin (Vanilla JS)
|
||||||
|
└── img/ # Visuels par défaut (hero-ariege.jpg/svg, logo-ul.svg, placeholder.svg)
|
||||||
61
archive.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit d'archives par catégorie, étiquette, date ou recherche (archive.php).
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="cgt-page-hero">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<nav class="cgt-breadcrumb" aria-label="<?php esc_attr_e( 'Fil d\'Ariane', 'cgt-fha' ); ?>">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Accueil', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<a href="<?php echo esc_url( cgt_fha_get_local_news_archive_url() ); ?>"><?php esc_html_e( 'Actualités', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<span><?php echo esc_html( wp_strip_all_tags( get_the_archive_title() ) ); ?></span>
|
||||||
|
</nav>
|
||||||
|
<h1 class="cgt-page-hero__title"><?php the_archive_title(); ?></h1>
|
||||||
|
<?php if ( get_the_archive_description() ) : ?>
|
||||||
|
<div class="cgt-page-hero__desc"><?php the_archive_description(); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="cgt-section cgt-section--white">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<?php if ( have_posts() ) : ?>
|
||||||
|
<div class="cgt-news-grid">
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
cgt_fha_render_local_post_card();
|
||||||
|
endwhile;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cgt-pagination">
|
||||||
|
<?php
|
||||||
|
the_posts_pagination(
|
||||||
|
array(
|
||||||
|
'mid_size' => 2,
|
||||||
|
'prev_text' => '← Précédent',
|
||||||
|
'next_text' => 'Suivant →',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e( 'Aucun article trouvé dans cette rubrique.', 'cgt-fha' ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
BIN
assets/img/banniere-ul-blanc.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
assets/img/banniere-ul-noir.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
assets/img/hero-ariege.jpg
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
assets/img/logo-cgt-09.jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
assets/img/logo-cgt.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/img/logo-ihs.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/img/logo-indecosa.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
assets/img/logo-nvo.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
7
assets/img/logo-ul-light.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 72" width="360" height="72" role="img" aria-label="Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<rect x="0" y="2" width="68" height="68" rx="4" fill="#d20012"/>
|
||||||
|
<text x="16" y="27" fill="#ffe600" font-family="Georgia, serif" font-style="italic" font-weight="700" font-size="22">la</text>
|
||||||
|
<text x="5" y="61" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="36" letter-spacing="-1.5">cgt</text>
|
||||||
|
<text x="84" y="31" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-weight="800" font-size="21" letter-spacing="0.4">UNION LOCALE</text>
|
||||||
|
<text x="84" y="59" fill="#e2e8f0" font-family="system-ui, -apple-system, sans-serif" font-weight="800" font-size="21" letter-spacing="0.4">FOIX HAUTE-ARIÈGE</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 832 B |
7
assets/img/logo-ul.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 72" width="360" height="72" role="img" aria-label="Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<rect x="0" y="2" width="68" height="68" fill="#d20012"/>
|
||||||
|
<text x="16" y="27" fill="#ffe600" font-family="Georgia, serif" font-style="italic" font-weight="700" font-size="22">la</text>
|
||||||
|
<text x="5" y="61" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="36" letter-spacing="-1.5">cgt</text>
|
||||||
|
<text x="84" y="31" fill="#1a1a1a" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="21" letter-spacing="0.4">UNION LOCALE</text>
|
||||||
|
<text x="84" y="59" fill="#1a1a1a" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="21" letter-spacing="0.4">FOIX HAUTE-ARIÈGE</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 825 B |
19
assets/img/placeholder.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 480" width="800" height="480" role="img" aria-label="Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0%" stop-color="#1c1e21"/>
|
||||||
|
<stop offset="100%" stop-color="#2d333b"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
|
||||||
|
<stop offset="0%" stop-color="#d20012"/>
|
||||||
|
<stop offset="100%" stop-color="#a8000e"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="800" height="480" fill="url(#bg)"/>
|
||||||
|
<path d="M0 360 L140 245 L270 325 L430 190 L585 305 L700 235 L800 315 L800 480 L0 480 Z" fill="#252a30"/>
|
||||||
|
<path d="M0 400 L180 310 L350 375 L540 285 L720 355 L800 330 L800 480 L0 480 Z" fill="#181b1f"/>
|
||||||
|
<rect x="330" y="135" width="140" height="140" rx="12" fill="url(#accent)"/>
|
||||||
|
<text x="400" y="192" text-anchor="middle" fill="#ffe600" font-family="Georgia, serif" font-style="italic" font-weight="700" font-size="34">la</text>
|
||||||
|
<text x="400" y="248" text-anchor="middle" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="60" letter-spacing="-2">cgt</text>
|
||||||
|
<text x="400" y="330" text-anchor="middle" fill="#f1f5f9" font-family="system-ui, -apple-system, sans-serif" font-weight="700" font-size="22" letter-spacing="1.5">UNION LOCALE FOIX HAUTE-ARIÈGE</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
34
assets/img/qr-placeholder.svg
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" width="180" height="180" role="img" aria-label="Emplacement QR Code application mobile CGT">
|
||||||
|
<rect width="180" height="180" rx="12" fill="#ffffff" stroke="#cbd5e1" stroke-width="2"/>
|
||||||
|
<g fill="#1a1a1a">
|
||||||
|
<rect x="18" y="18" width="42" height="42" rx="4"/>
|
||||||
|
<rect x="25" y="25" width="28" height="28" fill="#ffffff"/>
|
||||||
|
<rect x="32" y="32" width="14" height="14"/>
|
||||||
|
<rect x="120" y="18" width="42" height="42" rx="4"/>
|
||||||
|
<rect x="127" y="25" width="28" height="28" fill="#ffffff"/>
|
||||||
|
<rect x="134" y="32" width="14" height="14"/>
|
||||||
|
<rect x="18" y="120" width="42" height="42" rx="4"/>
|
||||||
|
<rect x="25" y="127" width="28" height="28" fill="#ffffff"/>
|
||||||
|
<rect x="32" y="134" width="14" height="14"/>
|
||||||
|
<rect x="72" y="22" width="10" height="10"/>
|
||||||
|
<rect x="94" y="22" width="12" height="10"/>
|
||||||
|
<rect x="72" y="42" width="18" height="10"/>
|
||||||
|
<rect x="98" y="42" width="10" height="18"/>
|
||||||
|
<rect x="22" y="74" width="14" height="10"/>
|
||||||
|
<rect x="44" y="74" width="16" height="12"/>
|
||||||
|
<rect x="22" y="96" width="10" height="14"/>
|
||||||
|
<rect x="40" y="96" width="20" height="10"/>
|
||||||
|
<rect x="72" y="120" width="12" height="12"/>
|
||||||
|
<rect x="96" y="120" width="14" height="10"/>
|
||||||
|
<rect x="122" y="120" width="18" height="12"/>
|
||||||
|
<rect x="148" y="120" width="14" height="18"/>
|
||||||
|
<rect x="72" y="144" width="24" height="14"/>
|
||||||
|
<rect x="108" y="142" width="16" height="16"/>
|
||||||
|
<rect x="134" y="146" width="26" height="12"/>
|
||||||
|
<rect x="124" y="74" width="16" height="14"/>
|
||||||
|
<rect x="148" y="74" width="14" height="26"/>
|
||||||
|
<rect x="120" y="96" width="20" height="14"/>
|
||||||
|
</g>
|
||||||
|
<rect x="68" y="68" width="44" height="44" rx="8" fill="#d20012"/>
|
||||||
|
<text x="90" y="97" text-anchor="middle" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-weight="900" font-size="18">cgt</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
177
assets/js/main.js
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/**
|
||||||
|
* Scripts Vanilla ES6 — Union Locale CGT Foix Haute-Ariège
|
||||||
|
* Menu mobile accessible + ombre header + partage + onglets & médias admin WP.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* 1. Navigation mobile accessible & sticky header
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
const header = document.querySelector('.cgt-header');
|
||||||
|
const navToggle = document.querySelector('.cgt-nav-toggle');
|
||||||
|
const navMenu = document.getElementById('cgt-primary-nav');
|
||||||
|
|
||||||
|
if (header) {
|
||||||
|
const onScroll = () => {
|
||||||
|
header.classList.toggle('is-scrolled', window.scrollY > 10);
|
||||||
|
};
|
||||||
|
onScroll();
|
||||||
|
window.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navToggle && navMenu) {
|
||||||
|
const setOpen = (isOpen) => {
|
||||||
|
navToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||||||
|
navToggle.setAttribute(
|
||||||
|
'aria-label',
|
||||||
|
isOpen ? 'Fermer le menu principal' : 'Ouvrir le menu principal'
|
||||||
|
);
|
||||||
|
navMenu.classList.toggle('is-open', isOpen);
|
||||||
|
};
|
||||||
|
|
||||||
|
navToggle.addEventListener('click', () => {
|
||||||
|
const expanded = navToggle.getAttribute('aria-expanded') === 'true';
|
||||||
|
setOpen(!expanded);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if (event.key === 'Escape' && navMenu.classList.contains('is-open')) {
|
||||||
|
setOpen(false);
|
||||||
|
navToggle.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('click', (event) => {
|
||||||
|
if (
|
||||||
|
navMenu.classList.contains('is-open') &&
|
||||||
|
!navMenu.contains(event.target) &&
|
||||||
|
!navToggle.contains(event.target)
|
||||||
|
) {
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* 2. Bouton copier le lien sur les articles
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
const copyBtns = document.querySelectorAll('[data-cgt-copy-url]');
|
||||||
|
copyBtns.forEach((btn) => {
|
||||||
|
btn.addEventListener('click', async () => {
|
||||||
|
const url = btn.getAttribute('data-cgt-copy-url');
|
||||||
|
if (!url || !navigator.clipboard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
const original = btn.textContent;
|
||||||
|
btn.textContent = 'Lien copié !';
|
||||||
|
setTimeout(() => {
|
||||||
|
btn.textContent = original;
|
||||||
|
}, 2200);
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore silencieusement si l'API clipboard est restreinte
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
* 3. Interface d'administration : onglets + sélecteur média WP
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
const adminWrap = document.querySelector('.cgt-admin-wrap');
|
||||||
|
if (!adminWrap) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabButtons = adminWrap.querySelectorAll('[data-cgt-tab]');
|
||||||
|
const tabPanels = adminWrap.querySelectorAll('[data-cgt-panel]');
|
||||||
|
const activeTabInput = adminWrap.querySelector('input[name="cgt_fha_active_tab"]');
|
||||||
|
const refererInput = adminWrap.querySelector('input[name="_wp_http_referer"]');
|
||||||
|
|
||||||
|
const activateTab = (tabId) => {
|
||||||
|
tabButtons.forEach((btn) => {
|
||||||
|
const match = btn.getAttribute('data-cgt-tab') === tabId;
|
||||||
|
btn.classList.toggle('nav-tab-active', match);
|
||||||
|
btn.setAttribute('aria-selected', match ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
tabPanels.forEach((panel) => {
|
||||||
|
const match = panel.getAttribute('data-cgt-panel') === tabId;
|
||||||
|
panel.hidden = !match;
|
||||||
|
});
|
||||||
|
if (activeTabInput) {
|
||||||
|
activeTabInput.value = tabId;
|
||||||
|
}
|
||||||
|
if (refererInput) {
|
||||||
|
try {
|
||||||
|
const url = new URL(refererInput.value, window.location.origin);
|
||||||
|
url.searchParams.set('tab', tabId);
|
||||||
|
refererInput.value = url.pathname + url.search;
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore si l'URL est invalide
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tabButtons.forEach((btn) => {
|
||||||
|
btn.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
activateTab(btn.getAttribute('data-cgt-tab'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sélecteurs de médias WordPress (wp.media)
|
||||||
|
if (typeof wp !== 'undefined' && wp.media) {
|
||||||
|
adminWrap.querySelectorAll('[data-cgt-media-select]').forEach((selectBtn) => {
|
||||||
|
selectBtn.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const targetId = selectBtn.getAttribute('data-cgt-media-select');
|
||||||
|
const inputEl = document.getElementById(targetId);
|
||||||
|
const previewEl = document.getElementById(targetId + '_preview');
|
||||||
|
|
||||||
|
const frame = wp.media({
|
||||||
|
title: 'Choisir une image',
|
||||||
|
button: { text: 'Utiliser cette image' },
|
||||||
|
library: { type: 'image' },
|
||||||
|
multiple: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.on('select', () => {
|
||||||
|
const attachment = frame.state().get('selection').first().toJSON();
|
||||||
|
if (inputEl && attachment.url) {
|
||||||
|
inputEl.value = attachment.url;
|
||||||
|
}
|
||||||
|
if (previewEl && attachment.url) {
|
||||||
|
previewEl.src = attachment.url;
|
||||||
|
previewEl.hidden = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.open();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
adminWrap.querySelectorAll('[data-cgt-media-clear]').forEach((clearBtn) => {
|
||||||
|
clearBtn.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const targetId = clearBtn.getAttribute('data-cgt-media-clear');
|
||||||
|
const defaultUrl = clearBtn.getAttribute('data-cgt-default-url') || '';
|
||||||
|
const inputEl = document.getElementById(targetId);
|
||||||
|
const previewEl = document.getElementById(targetId + '_preview');
|
||||||
|
|
||||||
|
if (inputEl) {
|
||||||
|
inputEl.value = defaultUrl;
|
||||||
|
}
|
||||||
|
if (previewEl) {
|
||||||
|
if (defaultUrl) {
|
||||||
|
previewEl.src = defaultUrl;
|
||||||
|
previewEl.hidden = false;
|
||||||
|
} else {
|
||||||
|
previewEl.src = '';
|
||||||
|
previewEl.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
112
footer.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pied de page souverain (3 colonnes) — Union Locale CGT Foix Haute-Ariège.
|
||||||
|
* Aucune mention "Propulsé par WordPress".
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$phone_raw = (string) $opts['phone'];
|
||||||
|
$phone_href = preg_replace( '/[^0-9+]/', '', $phone_raw );
|
||||||
|
$email = (string) $opts['email'];
|
||||||
|
$logo_url = cgt_fha_get_footer_logo_url();
|
||||||
|
?>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="cgt-footer" role="contentinfo">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<div class="cgt-footer__grid">
|
||||||
|
<!-- Colonne 1 : Identité & appel militant -->
|
||||||
|
<div>
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" aria-label="<?php esc_attr_e( 'Retour à l\'accueil', 'cgt-fha' ); ?>">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $logo_url ); ?>"
|
||||||
|
alt="Union Locale CGT Foix Haute-Ariège"
|
||||||
|
class="cgt-footer__logo"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<?php if ( ! empty( $opts['footer_desc'] ) ) : ?>
|
||||||
|
<p class="cgt-footer__text"><?php echo esc_html( (string) $opts['footer_desc'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ( ! empty( $opts['footer_call'] ) ) : ?>
|
||||||
|
<p class="cgt-footer__call"><?php echo esc_html( (string) $opts['footer_call'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Colonne 2 : Nos Locaux & Permanences (visible sur 100 % des pages) -->
|
||||||
|
<div>
|
||||||
|
<h2 class="cgt-footer__title"><?php esc_html_e( 'Nos Locaux & Permanences', 'cgt-fha' ); ?></h2>
|
||||||
|
<ul class="cgt-footer__list">
|
||||||
|
<?php if ( ! empty( $opts['address'] ) ) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo cgt_fha_render_icon( 'map-pin', 17 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<span><?php echo esc_html( (string) $opts['address'] ); ?></span>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( '' !== $phone_raw ) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo cgt_fha_render_icon( 'phone', 17 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<a href="<?php echo esc_url( 'tel:' . $phone_href ); ?>"><?php echo esc_html( $phone_raw ); ?></a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( '' !== $email ) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo cgt_fha_render_icon( 'mail', 17 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<a href="<?php echo esc_url( 'mailto:' . $email ); ?>"><?php echo esc_html( $email ); ?></a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( ! empty( $opts['hours'] ) ) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo cgt_fha_render_icon( 'clock', 17 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<span><?php echo esc_html( (string) $opts['hours'] ); ?></span>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( ! empty( $opts['facebook_url'] ) ) : ?>
|
||||||
|
<li>
|
||||||
|
<?php echo cgt_fha_render_icon( 'facebook', 17 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['facebook_url'] ); ?>" target="_blank" rel="noopener noreferrer">
|
||||||
|
<?php esc_html_e( 'Page Facebook officielle de l\'UL', 'cgt-fha' ); ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Colonne 3 : Accès rapides & Mentions -->
|
||||||
|
<div>
|
||||||
|
<h2 class="cgt-footer__title"><?php esc_html_e( 'Accès rapides & Mentions', 'cgt-fha' ); ?></h2>
|
||||||
|
<?php
|
||||||
|
wp_nav_menu(
|
||||||
|
array(
|
||||||
|
'theme_location' => 'footer',
|
||||||
|
'container' => false,
|
||||||
|
'menu_class' => 'cgt-footer__list',
|
||||||
|
'depth' => 1,
|
||||||
|
'fallback_cb' => 'cgt_fha_default_footer_menu',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cgt-footer__bottom">
|
||||||
|
<span>© <?php echo esc_html( wp_date( 'Y' ) ); ?> Union Locale CGT Foix Haute-Ariège — Tous droits réservés.</span>
|
||||||
|
<span><?php esc_html_e( 'Union des syndicats CGT — Foix & Haute-Ariège (09)', 'cgt-fha' ); ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<?php wp_footer(); ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
271
front-page.php
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit de la Page d'Accueil — 7 sections verticales fidèles à la maquette.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 1 : BANNIÈRE HERO PLEIN ÉCRAN
|
||||||
|
========================================================================= -->
|
||||||
|
<section class="cgt-hero" aria-label="<?php esc_attr_e( 'Présentation de l\'Union Locale CGT Foix Haute-Ariège', 'cgt-fha' ); ?>">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( (string) $opts['hero_bg_url'] ); ?>"
|
||||||
|
alt=""
|
||||||
|
class="cgt-hero__bg"
|
||||||
|
fetchpriority="high"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<div class="cgt-hero__overlay" aria-hidden="true"></div>
|
||||||
|
|
||||||
|
<div class="cgt-hero__content">
|
||||||
|
<h1 class="cgt-hero__title">
|
||||||
|
<span><?php echo esc_html( (string) $opts['hero_title_line1'] ); ?></span>
|
||||||
|
<?php if ( '' !== trim( (string) $opts['hero_title_line2'] ) ) : ?>
|
||||||
|
<span><?php echo esc_html( (string) $opts['hero_title_line2'] ); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<?php if ( '' !== trim( (string) $opts['hero_quote'] ) ) : ?>
|
||||||
|
<p class="cgt-hero__quote"><?php echo esc_html( (string) $opts['hero_quote'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="cgt-hero__actions">
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['hero_btn1_url'] ); ?>" class="cgt-btn cgt-btn--white">
|
||||||
|
<?php echo esc_html( (string) $opts['hero_btn1_label'] ); ?>
|
||||||
|
</a>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['hero_btn2_url'] ); ?>" class="cgt-btn cgt-btn--hero-dark">
|
||||||
|
<?php echo esc_html( (string) $opts['hero_btn2_label'] ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 2 : À QUOI NOUS SERVONS ? (3 Cartes de Mission)
|
||||||
|
========================================================================= -->
|
||||||
|
<section class="cgt-section cgt-section--white cgt-missions-section" aria-labelledby="cgt-missions-heading">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<h2 id="cgt-missions-heading" class="cgt-section__title"><?php echo esc_html( (string) $opts['missions_title'] ); ?></h2>
|
||||||
|
<?php if ( ! empty( $opts['missions_subtitle'] ) ) : ?>
|
||||||
|
<p class="cgt-section__subtitle"><?php echo esc_html( (string) $opts['missions_subtitle'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="cgt-missions-grid">
|
||||||
|
<?php for ( $i = 1; $i <= 3; $i++ ) : ?>
|
||||||
|
<article class="cgt-mission-card">
|
||||||
|
<div class="cgt-mission-card__icon" aria-hidden="true">
|
||||||
|
<?php echo cgt_fha_render_icon( (string) $opts[ 'mission_' . $i . '_icon' ], 40 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</div>
|
||||||
|
<h3 class="cgt-mission-card__title"><?php echo esc_html( (string) $opts[ 'mission_' . $i . '_title' ] ); ?></h3>
|
||||||
|
<p class="cgt-mission-card__text"><?php echo esc_html( (string) $opts[ 'mission_' . $i . '_text' ] ); ?></p>
|
||||||
|
</article>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 3 : SUR LE TERRAIN EN HAUTE-ARIÈGE (3 derniers articles locaux)
|
||||||
|
========================================================================= -->
|
||||||
|
<section class="cgt-section cgt-section--white cgt-local-section" aria-labelledby="cgt-local-news-heading">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<h2 id="cgt-local-news-heading" class="cgt-section__title"><?php echo esc_html( (string) $opts['local_news_title'] ); ?></h2>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$local_query = new WP_Query(
|
||||||
|
array(
|
||||||
|
'post_type' => 'post',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'posts_per_page' => 3,
|
||||||
|
'ignore_sticky_posts' => true,
|
||||||
|
'no_found_rows' => true,
|
||||||
|
'update_post_meta_cache' => false,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ( $local_query->have_posts() ) : ?>
|
||||||
|
<div class="cgt-news-grid">
|
||||||
|
<?php
|
||||||
|
while ( $local_query->have_posts() ) :
|
||||||
|
$local_query->the_post();
|
||||||
|
cgt_fha_render_local_post_card();
|
||||||
|
endwhile;
|
||||||
|
wp_reset_postdata();
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<p class="cgt-section__subtitle">
|
||||||
|
<?php esc_html_e( 'Les prochaines actualités locales et comptes-rendus de luttes à Foix et en Haute-Ariège seront publiés ici très prochainement.', 'cgt-fha' ); ?>
|
||||||
|
</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="cgt-section__footer">
|
||||||
|
<a href="<?php echo esc_url( cgt_fha_get_local_news_archive_url() ); ?>" class="cgt-btn cgt-btn--subtle">
|
||||||
|
<?php echo esc_html( (string) $opts['local_news_more'] ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Hook pour injecter les prochains rendez-vous de l'extension cgt-wp-calendar.
|
||||||
|
do_action( 'cgt_fha_after_local_news' );
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 4 : ACTUALITÉ CONFÉDÉRALE (cgt.fr)
|
||||||
|
========================================================================= -->
|
||||||
|
<?php CGT_FHA_Confederal_Feed::render_section( (string) $opts['confederal_title'] ); ?>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 5 : SALARIÉS ISOLÉS & TPE : VOUS N'ÊTES PAS SEULS
|
||||||
|
========================================================================= -->
|
||||||
|
<?php if ( ! empty( $opts['tpe_enabled'] ) ) : ?>
|
||||||
|
<section class="cgt-section cgt-section--white" aria-labelledby="cgt-tpe-heading">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<div class="cgt-tpe-box">
|
||||||
|
<div>
|
||||||
|
<?php if ( ! empty( $opts['tpe_badge'] ) ) : ?>
|
||||||
|
<span class="cgt-tpe-box__badge"><?php echo esc_html( (string) $opts['tpe_badge'] ); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
<h2 id="cgt-tpe-heading" class="cgt-tpe-box__title"><?php echo esc_html( (string) $opts['tpe_title'] ); ?></h2>
|
||||||
|
<p class="cgt-tpe-box__text"><?php echo esc_html( (string) $opts['tpe_text'] ); ?></p>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['tpe_btn_url'] ); ?>" class="cgt-btn cgt-btn--primary">
|
||||||
|
<?php echo esc_html( (string) $opts['tpe_btn_label'] ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="cgt-tpe-points">
|
||||||
|
<?php for ( $p = 1; $p <= 3; $p++ ) : ?>
|
||||||
|
<?php if ( ! empty( $opts[ 'tpe_point_' . $p ] ) ) : ?>
|
||||||
|
<li>
|
||||||
|
<span class="cgt-tpe-points__icon">
|
||||||
|
<?php echo cgt_fha_render_icon( 'check', 18 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</span>
|
||||||
|
<span><?php echo esc_html( (string) $opts[ 'tpe_point_' . $p ] ); ?></span>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<?php do_action( 'cgt_fha_tpe_section_after' ); ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 6 : FORMATION SYNDICALE (CFESES) & APPLICATION MOBILE
|
||||||
|
========================================================================= -->
|
||||||
|
<?php
|
||||||
|
$split_count = ( ! empty( $opts['cfeses_enabled'] ) ? 1 : 0 ) + ( ! empty( $opts['app_enabled'] ) ? 1 : 0 );
|
||||||
|
if ( $split_count > 0 ) :
|
||||||
|
$split_class = 1 === $split_count ? 'cgt-split-grid cgt-split-grid--single' : 'cgt-split-grid';
|
||||||
|
?>
|
||||||
|
<section class="cgt-section cgt-section--soft" aria-label="<?php esc_attr_e( 'Formation syndicale et application mobile', 'cgt-fha' ); ?>">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<div class="<?php echo esc_attr( $split_class ); ?>">
|
||||||
|
<?php if ( ! empty( $opts['cfeses_enabled'] ) ) : ?>
|
||||||
|
<article class="cgt-feature-card">
|
||||||
|
<span class="cgt-feature-card__eyebrow"><?php echo esc_html( (string) $opts['cfeses_eyebrow'] ); ?></span>
|
||||||
|
<h2 class="cgt-feature-card__title"><?php echo esc_html( (string) $opts['cfeses_title'] ); ?></h2>
|
||||||
|
<p class="cgt-feature-card__text"><?php echo esc_html( (string) $opts['cfeses_text'] ); ?></p>
|
||||||
|
<div class="cgt-feature-card__footer">
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['cfeses_btn_url'] ); ?>" class="cgt-btn cgt-btn--primary">
|
||||||
|
<?php echo esc_html( (string) $opts['cfeses_btn_label'] ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( ! empty( $opts['app_enabled'] ) ) : ?>
|
||||||
|
<article class="cgt-feature-card">
|
||||||
|
<span class="cgt-feature-card__eyebrow"><?php echo esc_html( (string) $opts['app_eyebrow'] ); ?></span>
|
||||||
|
<h2 class="cgt-feature-card__title"><?php echo esc_html( (string) $opts['app_title'] ); ?></h2>
|
||||||
|
<div class="cgt-app-layout">
|
||||||
|
<div>
|
||||||
|
<p class="cgt-feature-card__text"><?php echo esc_html( (string) $opts['app_text'] ); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php if ( ! empty( $opts['app_qr_url'] ) ) : ?>
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( (string) $opts['app_qr_url'] ); ?>"
|
||||||
|
alt="<?php esc_attr_e( 'QR Code pour télécharger l\'application mobile UL CGT Foix Haute-Ariège', 'cgt-fha' ); ?>"
|
||||||
|
class="cgt-app-qr"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div class="cgt-feature-card__footer">
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['app_download_url'] ); ?>" class="cgt-btn cgt-btn--outline-dark" target="_blank" rel="noopener noreferrer">
|
||||||
|
<?php echo esc_html( (string) $opts['app_btn_label'] ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- =========================================================================
|
||||||
|
SECTION 7 : RÉSEAU SYNDICAL CGT
|
||||||
|
========================================================================= -->
|
||||||
|
<?php if ( ! empty( $opts['network_enabled'] ) ) : ?>
|
||||||
|
<section class="cgt-section cgt-section--white" aria-labelledby="cgt-network-heading">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<h2 id="cgt-network-heading" class="cgt-section__title"><?php echo esc_html( (string) $opts['network_title'] ); ?></h2>
|
||||||
|
<div class="cgt-network-grid">
|
||||||
|
<?php for ( $n = 1; $n <= 5; $n++ ) : ?>
|
||||||
|
<?php
|
||||||
|
if ( empty( $opts[ 'network_' . $n . '_enabled' ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$n_logo = (string) ( $opts[ 'network_' . $n . '_logo' ] ?? '' );
|
||||||
|
$n_label = (string) ( $opts[ 'network_' . $n . '_label' ] ?? '' );
|
||||||
|
$n_desc = (string) ( $opts[ 'network_' . $n . '_desc' ] ?? '' );
|
||||||
|
$n_btn = (string) ( $opts[ 'network_' . $n . '_btn' ] ?? 'Visiter le site ↗' );
|
||||||
|
$n_url = (string) ( $opts[ 'network_' . $n . '_url' ] ?? '' );
|
||||||
|
if ( '' === $n_label || '' === $n_url ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<article class="cgt-network-card">
|
||||||
|
<?php if ( '' !== $n_logo ) : ?>
|
||||||
|
<div class="cgt-network-card__logo-wrap">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $n_logo ); ?>"
|
||||||
|
alt="<?php echo esc_attr( $n_label ); ?>"
|
||||||
|
class="cgt-network-card__logo"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<h3 class="cgt-network-card__title"><?php echo esc_html( $n_label ); ?></h3>
|
||||||
|
<?php if ( '' !== $n_desc ) : ?>
|
||||||
|
<p class="cgt-network-card__desc"><?php echo esc_html( $n_desc ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="cgt-network-card__cta">
|
||||||
|
<a href="<?php echo esc_url( $n_url ); ?>" class="cgt-network-card__btn" target="_blank" rel="noopener noreferrer">
|
||||||
|
<?php echo esc_html( $n_btn ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
303
functions.php
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Fonctions principales du thème Union Locale CGT Foix Haute-Ariège.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
define( 'CGT_FHA_VERSION', '1.2.0' );
|
||||||
|
define( 'CGT_FHA_DIR', get_template_directory() );
|
||||||
|
define( 'CGT_FHA_URI', get_template_directory_uri() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chargement des modules du thème.
|
||||||
|
*/
|
||||||
|
require_once CGT_FHA_DIR . '/inc/theme-options.php';
|
||||||
|
require_once CGT_FHA_DIR . '/inc/class-cgt-confederal-feed.php';
|
||||||
|
require_once CGT_FHA_DIR . '/inc/seo-performance.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration des supports WordPress et menus.
|
||||||
|
*/
|
||||||
|
add_action( 'after_setup_theme', 'cgt_fha_setup' );
|
||||||
|
function cgt_fha_setup(): void {
|
||||||
|
load_theme_textdomain( 'cgt-fha', CGT_FHA_DIR . '/languages' );
|
||||||
|
|
||||||
|
add_theme_support( 'title-tag' );
|
||||||
|
add_theme_support( 'post-thumbnails' );
|
||||||
|
add_image_size( 'cgt-card', 640, 380, true );
|
||||||
|
add_image_size( 'cgt-featured', 960, 560, true );
|
||||||
|
|
||||||
|
add_theme_support(
|
||||||
|
'custom-logo',
|
||||||
|
array(
|
||||||
|
'height' => 120,
|
||||||
|
'width' => 520,
|
||||||
|
'flex-height' => true,
|
||||||
|
'flex-width' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_theme_support(
|
||||||
|
'html5',
|
||||||
|
array(
|
||||||
|
'search-form',
|
||||||
|
'comment-form',
|
||||||
|
'comment-list',
|
||||||
|
'gallery',
|
||||||
|
'caption',
|
||||||
|
'style',
|
||||||
|
'script',
|
||||||
|
'navigation-widgets',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
add_theme_support( 'responsive-embeds' );
|
||||||
|
add_theme_support( 'align-wide' );
|
||||||
|
|
||||||
|
register_nav_menus(
|
||||||
|
array(
|
||||||
|
'primary' => __( 'Menu principal (En-tête)', 'cgt-fha' ),
|
||||||
|
'footer' => __( 'Accès rapides (Pied de page)', 'cgt-fha' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chargement des styles et scripts frontend (zéro dépendance externe).
|
||||||
|
*/
|
||||||
|
add_action( 'wp_enqueue_scripts', 'cgt_fha_enqueue_assets' );
|
||||||
|
function cgt_fha_enqueue_assets(): void {
|
||||||
|
$style_ver = file_exists( CGT_FHA_DIR . '/style.css' ) ? (string) filemtime( CGT_FHA_DIR . '/style.css' ) : CGT_FHA_VERSION;
|
||||||
|
$js_ver = file_exists( CGT_FHA_DIR . '/assets/js/main.js' ) ? (string) filemtime( CGT_FHA_DIR . '/assets/js/main.js' ) : CGT_FHA_VERSION;
|
||||||
|
|
||||||
|
wp_enqueue_style( 'cgt-fha-style', get_stylesheet_uri(), array(), $style_ver );
|
||||||
|
wp_enqueue_script(
|
||||||
|
'cgt-fha-main',
|
||||||
|
CGT_FHA_URI . '/assets/js/main.js',
|
||||||
|
array(),
|
||||||
|
$js_ver,
|
||||||
|
array(
|
||||||
|
'in_footer' => true,
|
||||||
|
'strategy' => 'defer',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chargement des scripts admin uniquement sur la page de réglages du thème.
|
||||||
|
*/
|
||||||
|
add_action( 'admin_enqueue_scripts', 'cgt_fha_admin_enqueue_assets' );
|
||||||
|
function cgt_fha_admin_enqueue_assets( string $hook_suffix ): void {
|
||||||
|
if ( 'appearance_page_cgt-fha-settings' !== $hook_suffix ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_enqueue_media();
|
||||||
|
$js_ver = file_exists( CGT_FHA_DIR . '/assets/js/main.js' ) ? (string) filemtime( CGT_FHA_DIR . '/assets/js/main.js' ) : CGT_FHA_VERSION;
|
||||||
|
wp_enqueue_script( 'cgt-fha-admin', CGT_FHA_URI . '/assets/js/main.js', array(), $js_ver, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL du logo d'en-tête (Personnaliser > Logo personnalisé ou Réglages UL CGT ou bannière par défaut).
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_header_logo_url(): string {
|
||||||
|
$custom_logo_id = (int) get_theme_mod( 'custom_logo' );
|
||||||
|
if ( $custom_logo_id > 0 ) {
|
||||||
|
$src = wp_get_attachment_image_url( $custom_logo_id, 'full' );
|
||||||
|
if ( $src ) {
|
||||||
|
return $src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
return ! empty( $opts['header_logo_url'] )
|
||||||
|
? (string) $opts['header_logo_url']
|
||||||
|
: CGT_FHA_URI . '/assets/img/banniere-ul-noir.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL du logo clair du pied de page.
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_footer_logo_url(): string {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
return ! empty( $opts['footer_logo_url'] )
|
||||||
|
? (string) $opts['footer_logo_url']
|
||||||
|
: CGT_FHA_URI . '/assets/img/banniere-ul-blanc.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne l'URL de la page listant toutes les actualités locales.
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_local_news_archive_url(): string {
|
||||||
|
$posts_page_id = (int) get_option( 'page_for_posts' );
|
||||||
|
if ( $posts_page_id > 0 ) {
|
||||||
|
$link = get_permalink( $posts_page_id );
|
||||||
|
if ( $link ) {
|
||||||
|
return $link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
return ! empty( $opts['news_url'] ) ? (string) $opts['news_url'] : home_url( '/actualites/' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu de secours pour la navigation principale si aucun menu n'est encore assigné dans Apparence > Menus.
|
||||||
|
*/
|
||||||
|
function cgt_fha_default_primary_menu(): void {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$items = array(
|
||||||
|
array(
|
||||||
|
'label' => 'Accueil',
|
||||||
|
'url' => home_url( '/' ),
|
||||||
|
'active' => is_front_page(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'label' => 'Actualités',
|
||||||
|
'url' => cgt_fha_get_local_news_archive_url(),
|
||||||
|
'active' => is_home() || is_singular( 'post' ) || is_category() || is_tag(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'label' => 'Calendrier',
|
||||||
|
'url' => (string) $opts['calendar_url'],
|
||||||
|
'active' => is_page( 'calendrier' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'label' => 'Contact',
|
||||||
|
'url' => (string) $opts['contact_url'],
|
||||||
|
'active' => is_page( 'contact' ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
echo '<ul class="cgt-nav__list">';
|
||||||
|
foreach ( $items as $item ) {
|
||||||
|
$classes = $item['active'] ? 'menu-item current-menu-item' : 'menu-item';
|
||||||
|
$aria = $item['active'] ? ' aria-current="page"' : '';
|
||||||
|
printf(
|
||||||
|
'<li class="%s"><a href="%s"%s>%s</a></li>',
|
||||||
|
esc_attr( $classes ),
|
||||||
|
esc_url( $item['url'] ),
|
||||||
|
$aria,
|
||||||
|
esc_html( $item['label'] )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
echo '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu de secours pour les accès rapides du pied de page.
|
||||||
|
*/
|
||||||
|
function cgt_fha_default_footer_menu(): void {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$items = array(
|
||||||
|
'Actualités' => cgt_fha_get_local_news_archive_url(),
|
||||||
|
'Calendrier' => (string) $opts['calendar_url'],
|
||||||
|
'Se syndiquer' => (string) $opts['join_url'],
|
||||||
|
'Urgence salarié' => (string) $opts['contact_url'],
|
||||||
|
'Mentions légales & Confidentialité' => (string) $opts['legal_url'],
|
||||||
|
);
|
||||||
|
|
||||||
|
echo '<ul class="cgt-footer__list">';
|
||||||
|
foreach ( $items as $label => $url ) {
|
||||||
|
printf(
|
||||||
|
'<li><a href="%s">%s</a></li>',
|
||||||
|
esc_url( $url ),
|
||||||
|
esc_html( $label )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
echo '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icônes SVG propres intégrées (zéro police d'icônes externe).
|
||||||
|
*/
|
||||||
|
function cgt_fha_render_icon( string $name, int $size = 24 ): string {
|
||||||
|
$s = (int) $size;
|
||||||
|
$icons = array(
|
||||||
|
'phone' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>',
|
||||||
|
'mail' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>',
|
||||||
|
'map-pin' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>',
|
||||||
|
'clock' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
|
||||||
|
'facebook' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M13.5 22v-8h2.7l.4-3h-3.1V9.1c0-.9.3-1.5 1.6-1.5h1.7V4.9c-.3 0-1.3-.1-2.4-.1-2.4 0-4 1.4-4 4.1V11H8v3h2.9v8h2.6Z"/></svg>',
|
||||||
|
'instagram' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>',
|
||||||
|
'youtube' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M21.8 8s-.2-1.4-.8-2c-.8-.8-1.6-.8-2-.9C16.2 5 12 5 12 5h0s-4.2 0-7 .1c-.4.1-1.2.1-2 .9-.6.6-.8 2-.8 2S2 9.6 2 11.2v1.5C2 14.4 2.2 16 2.2 16s.2 1.4.8 2c.8.8 1.8.8 2.2.9 1.6.1 6.8.1 6.8.1s4.2 0 7-.1c.4-.1 1.2-.1 2-.9.6-.6.8-2 .8-2s.2-1.6.2-3.2v-1.5c0-1.7-.2-3.3-.2-3.3ZM9.9 14.6V9.2l5.4 2.7-5.4 2.7Z"/></svg>',
|
||||||
|
'menu' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>',
|
||||||
|
'check' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>',
|
||||||
|
// Icônes des 3 cartes de mission.
|
||||||
|
'fist' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2"/><path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2"/><path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8"/><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"/></svg>',
|
||||||
|
'shield' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>',
|
||||||
|
'chat' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg>',
|
||||||
|
'megaphone' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m3 11 18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/></svg>',
|
||||||
|
'scale' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="M7 21h10"/><path d="M12 3v18"/><path d="M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2"/></svg>',
|
||||||
|
'users' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
|
||||||
|
'book' => '<svg xmlns="http://www.w3.org/2000/svg" width="' . $s . '" height="' . $s . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/></svg>',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $icons[ $name ] ?? $icons['fist'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendu réutilisable d'une carte d'article local (front-page, home, archive).
|
||||||
|
*/
|
||||||
|
function cgt_fha_render_local_post_card(): void {
|
||||||
|
$cats = get_the_category();
|
||||||
|
$cat_name = 'Vie syndicale';
|
||||||
|
if ( ! empty( $cats ) ) {
|
||||||
|
foreach ( $cats as $cat ) {
|
||||||
|
if ( ! in_array( $cat->slug, array( 'uncategorized', 'non-classe' ), true ) && 'Uncategorized' !== $cat->name ) {
|
||||||
|
$cat_name = $cat->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$placeholder = CGT_FHA_URI . '/assets/img/placeholder.svg';
|
||||||
|
?>
|
||||||
|
<article id="post-<?php the_ID(); ?>" <?php post_class( 'cgt-news-card' ); ?>>
|
||||||
|
<a href="<?php the_permalink(); ?>" class="cgt-news-card__thumb-link" aria-hidden="true" tabindex="-1">
|
||||||
|
<?php if ( has_post_thumbnail() ) : ?>
|
||||||
|
<?php
|
||||||
|
the_post_thumbnail(
|
||||||
|
'cgt-card',
|
||||||
|
array(
|
||||||
|
'class' => 'cgt-news-card__thumb',
|
||||||
|
'loading' => 'lazy',
|
||||||
|
'alt' => esc_attr( get_the_title() ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<?php else : ?>
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $placeholder ); ?>"
|
||||||
|
alt="<?php echo esc_attr( get_the_title() ); ?>"
|
||||||
|
class="cgt-news-card__thumb"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<?php endif; ?>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="cgt-news-card__body">
|
||||||
|
<div class="cgt-news-card__meta">
|
||||||
|
<span class="cgt-pill-cat"><?php echo esc_html( $cat_name ); ?></span>
|
||||||
|
<time datetime="<?php echo esc_attr( get_the_date( 'c' ) ); ?>" class="cgt-news-card__date">
|
||||||
|
<?php echo esc_html( get_the_date( 'd.m.Y' ) ); ?>
|
||||||
|
</time>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="cgt-news-card__title">
|
||||||
|
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p class="cgt-news-card__excerpt">
|
||||||
|
<?php echo esc_html( wp_trim_words( get_the_excerpt(), 20, '…' ) ); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
133
header.php
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* En-tête du thème Union Locale CGT Foix Haute-Ariège.
|
||||||
|
*
|
||||||
|
* 1. Topbar sombre (#1c1e21) avec téléphone, e-mail et réseaux sociaux
|
||||||
|
* 2. Bandeau d'alerte mobilisation auto-expirant (#d20012)
|
||||||
|
* 3. Barre de navigation blanche (logo à gauche, menu horizontal à droite)
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$phone_raw = (string) $opts['phone'];
|
||||||
|
$phone_href = preg_replace( '/[^0-9+]/', '', $phone_raw );
|
||||||
|
$email = (string) $opts['email'];
|
||||||
|
$logo_url = cgt_fha_get_header_logo_url();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html <?php language_attributes(); ?>>
|
||||||
|
<head>
|
||||||
|
<meta charset="<?php bloginfo( 'charset' ); ?>" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<?php wp_head(); ?>
|
||||||
|
</head>
|
||||||
|
<body <?php body_class(); ?>>
|
||||||
|
<?php wp_body_open(); ?>
|
||||||
|
<a class="skip-link" href="#cgt-main-content"><?php esc_html_e( 'Aller au contenu principal', 'cgt-fha' ); ?></a>
|
||||||
|
|
||||||
|
<!-- 1. Topbar sombre -->
|
||||||
|
<div class="cgt-topbar" role="region" aria-label="<?php esc_attr_e( 'Coordonnées rapides et réseaux sociaux', 'cgt-fha' ); ?>">
|
||||||
|
<div class="cgt-container cgt-topbar__inner">
|
||||||
|
<div class="cgt-topbar__contacts">
|
||||||
|
<?php if ( '' !== $phone_raw ) : ?>
|
||||||
|
<a href="<?php echo esc_url( 'tel:' . $phone_href ); ?>" class="cgt-topbar__link">
|
||||||
|
<?php echo cgt_fha_render_icon( 'phone', 14 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<span><?php echo esc_html( $phone_raw ); ?></span>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( '' !== $phone_raw && '' !== $email ) : ?>
|
||||||
|
<span class="cgt-topbar__sep" aria-hidden="true">/</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ( '' !== $email ) : ?>
|
||||||
|
<a href="<?php echo esc_url( 'mailto:' . $email ); ?>" class="cgt-topbar__link">
|
||||||
|
<?php echo cgt_fha_render_icon( 'mail', 14 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
<span><?php echo esc_html( $email ); ?></span>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cgt-topbar__socials">
|
||||||
|
<?php if ( ! empty( $opts['facebook_url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['facebook_url'] ); ?>" class="cgt-topbar__social" target="_blank" rel="noopener noreferrer" aria-label="Facebook Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<?php echo cgt_fha_render_icon( 'facebook', 16 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ( ! empty( $opts['instagram_url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['instagram_url'] ); ?>" class="cgt-topbar__social" target="_blank" rel="noopener noreferrer" aria-label="Instagram Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<?php echo cgt_fha_render_icon( 'instagram', 16 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ( ! empty( $opts['youtube_url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['youtube_url'] ); ?>" class="cgt-topbar__social" target="_blank" rel="noopener noreferrer" aria-label="YouTube Union Locale CGT Foix Haute-Ariège">
|
||||||
|
<?php echo cgt_fha_render_icon( 'youtube', 16 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 2. Bandeau d'Alerte Mobilisation Auto-Expirant -->
|
||||||
|
<?php if ( cgt_fha_is_banner_active() ) : ?>
|
||||||
|
<div class="cgt-mob-banner" role="alert">
|
||||||
|
<?php if ( ! empty( $opts['banner_url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( (string) $opts['banner_url'] ); ?>" class="cgt-mob-banner__inner">
|
||||||
|
<span><?php echo esc_html( (string) $opts['banner_text'] ); ?></span>
|
||||||
|
</a>
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="cgt-mob-banner__inner">
|
||||||
|
<span><?php echo esc_html( (string) $opts['banner_text'] ); ?></span>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- 3. Barre de Navigation Principale -->
|
||||||
|
<header class="cgt-header" role="banner">
|
||||||
|
<div class="cgt-container cgt-header__inner">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="cgt-brand" rel="home">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $logo_url ); ?>"
|
||||||
|
alt="<?php echo esc_attr( get_bloginfo( 'name' ) ?: 'Union Locale CGT Foix Haute-Ariège' ); ?>"
|
||||||
|
class="cgt-brand__logo"
|
||||||
|
decoding="async"
|
||||||
|
fetchpriority="high"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="cgt-nav-toggle"
|
||||||
|
aria-controls="cgt-primary-nav"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="<?php esc_attr_e( 'Ouvrir le menu principal', 'cgt-fha' ); ?>"
|
||||||
|
>
|
||||||
|
<?php echo cgt_fha_render_icon( 'menu', 22 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<nav id="cgt-primary-nav" class="cgt-nav" aria-label="<?php esc_attr_e( 'Navigation principale', 'cgt-fha' ); ?>">
|
||||||
|
<?php
|
||||||
|
wp_nav_menu(
|
||||||
|
array(
|
||||||
|
'theme_location' => 'primary',
|
||||||
|
'container' => false,
|
||||||
|
'menu_class' => 'cgt-nav__list',
|
||||||
|
'depth' => 1,
|
||||||
|
'fallback_cb' => 'cgt_fha_default_primary_menu',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main id="cgt-main-content" tabindex="-1">
|
||||||
|
<?php
|
||||||
|
// Hook pour extensions éventuelles juste après l'ouverture du contenu principal.
|
||||||
|
do_action( 'cgt_fha_main_open' );
|
||||||
61
home.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit de la liste paginée des actualités locales de l'UL (home.php).
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
$posts_page_id = (int) get_option( 'page_for_posts' );
|
||||||
|
$page_title = $posts_page_id > 0 ? get_the_title( $posts_page_id ) : 'Actualités locales — Foix & Haute-Ariège';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="cgt-page-hero">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<nav class="cgt-breadcrumb" aria-label="<?php esc_attr_e( 'Fil d\'Ariane', 'cgt-fha' ); ?>">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Accueil', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<span><?php echo esc_html( $page_title ); ?></span>
|
||||||
|
</nav>
|
||||||
|
<h1 class="cgt-page-hero__title"><?php echo esc_html( $page_title ); ?></h1>
|
||||||
|
<p class="cgt-page-hero__desc">
|
||||||
|
<?php esc_html_e( 'Retrouvez les communiqués, mobilisations, tracts et comptes-rendus des syndicats CGT de Foix et de la Haute-Ariège.', 'cgt-fha' ); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="cgt-section cgt-section--white">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<?php if ( have_posts() ) : ?>
|
||||||
|
<div class="cgt-news-grid">
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
cgt_fha_render_local_post_card();
|
||||||
|
endwhile;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cgt-pagination">
|
||||||
|
<?php
|
||||||
|
the_posts_pagination(
|
||||||
|
array(
|
||||||
|
'mid_size' => 2,
|
||||||
|
'prev_text' => '← Précédent',
|
||||||
|
'next_text' => 'Suivant →',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e( 'Aucun article local publié pour le moment.', 'cgt-fha' ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
840
inc/class-cgt-confederal-feed.php
Normal file
@ -0,0 +1,840 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Moteur de récupération et rendu de l'actualité confédérale depuis https://www.cgt.fr/
|
||||||
|
*
|
||||||
|
* - Interroge cgt.fr via wp_remote_get() (timeout 10s, User-Agent propre)
|
||||||
|
* - Parse le HTML Drupal via DOMDocument + DOMXPath sans polluer wp_posts
|
||||||
|
* - Extrait 1 article "À la une" + 3 articles "mais aussi..."
|
||||||
|
* - Enrichit les résumés via https://www.cgt.fr/actualites et, si besoin, depuis la page article
|
||||||
|
* - Cache Transient (3h) + sauvegarde de secours (autoload = false) + WP-Cron (2h)
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CGT_FHA_Confederal_Feed {
|
||||||
|
|
||||||
|
public const TRANSIENT_KEY = 'cgt_fha_confederal_feed';
|
||||||
|
public const BACKUP_OPTION = 'cgt_fha_confederal_feed_backup';
|
||||||
|
public const LOCK_TRANSIENT = 'cgt_fha_confederal_feed_lock';
|
||||||
|
public const CRON_HOOK = 'cgt_fha_refresh_confederal_feed';
|
||||||
|
public const CRON_INTERVAL = 'cgt_fha_two_hours';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enregistre les hooks WP-Cron, Admin Bar et rafraîchissement manuel.
|
||||||
|
*/
|
||||||
|
public static function init(): void {
|
||||||
|
add_filter( 'cron_schedules', array( __CLASS__, 'register_cron_interval' ) );
|
||||||
|
add_action( 'init', array( __CLASS__, 'ensure_cron_scheduled' ) );
|
||||||
|
add_action( self::CRON_HOOK, array( __CLASS__, 'cron_refresh' ) );
|
||||||
|
add_action( 'switch_theme', array( __CLASS__, 'clear_cron' ) );
|
||||||
|
add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_bar_button' ), 95 );
|
||||||
|
add_action( 'admin_post_cgt_fha_refresh_feed', array( __CLASS__, 'handle_manual_refresh' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajoute un intervalle WP-Cron de 2 heures.
|
||||||
|
*
|
||||||
|
* @param array<string, array<string, mixed>> $schedules Planifications existantes.
|
||||||
|
* @return array<string, array<string, mixed>>
|
||||||
|
*/
|
||||||
|
public static function register_cron_interval( array $schedules ): array {
|
||||||
|
if ( ! isset( $schedules[ self::CRON_INTERVAL ] ) ) {
|
||||||
|
$schedules[ self::CRON_INTERVAL ] = array(
|
||||||
|
'interval' => 2 * HOUR_IN_SECONDS,
|
||||||
|
'display' => 'Toutes les 2 heures (Actus Confédérales CGT)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $schedules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Planifie la tâche WP-Cron si elle n'est pas déjà active.
|
||||||
|
*/
|
||||||
|
public static function ensure_cron_scheduled(): void {
|
||||||
|
if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
|
||||||
|
wp_schedule_event( time() + 300, self::CRON_INTERVAL, self::CRON_HOOK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supprime la tâche WP-Cron lors du changement de thème.
|
||||||
|
*/
|
||||||
|
public static function clear_cron(): void {
|
||||||
|
$timestamp = wp_next_scheduled( self::CRON_HOOK );
|
||||||
|
while ( $timestamp ) {
|
||||||
|
wp_unschedule_event( $timestamp, self::CRON_HOOK );
|
||||||
|
$timestamp = wp_next_scheduled( self::CRON_HOOK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback exécuté par WP-Cron toutes les 2 heures.
|
||||||
|
*/
|
||||||
|
public static function cron_refresh(): void {
|
||||||
|
self::get_feed( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bouton « Actualiser les actus confédérales » dans la barre d'admin WordPress.
|
||||||
|
*/
|
||||||
|
public static function add_admin_bar_button( WP_Admin_Bar $wp_admin_bar ): void {
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = wp_nonce_url(
|
||||||
|
admin_url( 'admin-post.php?action=cgt_fha_refresh_feed' ),
|
||||||
|
'cgt_fha_refresh_feed_action',
|
||||||
|
'cgt_fha_refresh_feed_nonce'
|
||||||
|
);
|
||||||
|
|
||||||
|
$wp_admin_bar->add_node(
|
||||||
|
array(
|
||||||
|
'id' => 'cgt-fha-refresh-confederal',
|
||||||
|
'title' => 'Actualiser les actus confédérales',
|
||||||
|
'href' => $url,
|
||||||
|
'meta' => array(
|
||||||
|
'title' => 'Synchroniser immédiatement les actualités depuis cgt.fr',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traitement du rafraîchissement manuel sécurisé par nonce.
|
||||||
|
*/
|
||||||
|
public static function handle_manual_refresh(): void {
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_die( esc_html__( 'Action non autorisée.', 'cgt-fha' ), 403 );
|
||||||
|
}
|
||||||
|
|
||||||
|
check_admin_referer( 'cgt_fha_refresh_feed_action', 'cgt_fha_refresh_feed_nonce' );
|
||||||
|
|
||||||
|
delete_transient( self::LOCK_TRANSIENT );
|
||||||
|
self::get_feed( true );
|
||||||
|
|
||||||
|
$redirect = add_query_arg(
|
||||||
|
array(
|
||||||
|
'page' => 'cgt-fha-settings',
|
||||||
|
'tab' => 'confederal',
|
||||||
|
'cgt_feed_refreshed' => '1',
|
||||||
|
),
|
||||||
|
admin_url( 'themes.php' )
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_safe_redirect( $redirect );
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne les données du flux confédéral (cache -> réseau -> backup -> fallback).
|
||||||
|
*
|
||||||
|
* @param bool $force_refresh Force une requête réseau immédiate.
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public static function get_feed( bool $force_refresh = false ): array {
|
||||||
|
if ( ! $force_refresh ) {
|
||||||
|
$cached = get_transient( self::TRANSIENT_KEY );
|
||||||
|
if ( is_array( $cached ) && ! empty( $cached['featured'] ) ) {
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anti-tempête : évite de relancer des requêtes HTTP bloquantes si cgt.fr vient d'échouer.
|
||||||
|
if ( $force_refresh || false === get_transient( self::LOCK_TRANSIENT ) ) {
|
||||||
|
$fresh = self::fetch_and_parse();
|
||||||
|
if ( ! empty( $fresh['featured']['title'] ) && ! empty( $fresh['latest'] ) ) {
|
||||||
|
set_transient( self::TRANSIENT_KEY, $fresh, 3 * HOUR_IN_SECONDS );
|
||||||
|
update_option( self::BACKUP_OPTION, $fresh, false );
|
||||||
|
delete_transient( self::LOCK_TRANSIENT );
|
||||||
|
return $fresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_transient( self::LOCK_TRANSIENT, 1, 5 * MINUTE_IN_SECONDS );
|
||||||
|
}
|
||||||
|
|
||||||
|
$backup = get_option( self::BACKUP_OPTION, array() );
|
||||||
|
if ( is_array( $backup ) && ! empty( $backup['featured']['title'] ) ) {
|
||||||
|
return $backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::get_static_fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne l'état du cache pour l'onglet d'administration.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public static function get_cache_status(): array {
|
||||||
|
$transient = get_transient( self::TRANSIENT_KEY );
|
||||||
|
$backup = get_option( self::BACKUP_OPTION, array() );
|
||||||
|
$data = is_array( $transient ) && ! empty( $transient ) ? $transient : ( is_array( $backup ) ? $backup : array() );
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'has_transient' => is_array( $transient ) && ! empty( $transient ),
|
||||||
|
'fetched_at' => $data['fetched_at'] ?? 0,
|
||||||
|
'source' => $data['source'] ?? 'Fallback local',
|
||||||
|
'featured' => $data['featured'] ?? array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Télécharge et parse cgt.fr (avec enrichissement sur /actualites puis sur la page article si besoin).
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
private static function fetch_and_parse(): array {
|
||||||
|
$home_html = self::remote_get_html( 'https://www.cgt.fr/' );
|
||||||
|
$featured = array();
|
||||||
|
$latest = array();
|
||||||
|
$source = 'https://www.cgt.fr/';
|
||||||
|
|
||||||
|
if ( '' !== $home_html ) {
|
||||||
|
$parsed = self::parse_homepage_html( $home_html );
|
||||||
|
$featured = $parsed['featured'];
|
||||||
|
$latest = $parsed['latest'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$needs_actualites = empty( $featured['title'] )
|
||||||
|
|| '' === trim( (string) ( $featured['summary'] ?? '' ) )
|
||||||
|
|| empty( $featured['image_url'] )
|
||||||
|
|| count( $latest ) < 3;
|
||||||
|
|
||||||
|
if ( ! $needs_actualites ) {
|
||||||
|
foreach ( $latest as $item ) {
|
||||||
|
if ( '' === trim( (string) ( $item['summary'] ?? '' ) ) || empty( $item['image_url'] ) ) {
|
||||||
|
$needs_actualites = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $needs_actualites ) {
|
||||||
|
$actus_html = self::remote_get_html( 'https://www.cgt.fr/actualites' );
|
||||||
|
if ( '' !== $actus_html ) {
|
||||||
|
$actus_items = self::parse_actualites_html( $actus_html );
|
||||||
|
|
||||||
|
if ( ! empty( $actus_items ) ) {
|
||||||
|
$by_path = array();
|
||||||
|
foreach ( $actus_items as $act ) {
|
||||||
|
$key = self::normalize_url_key( $act['url'] );
|
||||||
|
if ( '' !== $key ) {
|
||||||
|
$by_path[ $key ] = $act;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enrichit "featured" sans écraser une image haute définition déjà extraite.
|
||||||
|
if ( ! empty( $featured['url'] ) ) {
|
||||||
|
$f_key = self::normalize_url_key( $featured['url'] );
|
||||||
|
if ( isset( $by_path[ $f_key ] ) ) {
|
||||||
|
if ( '' === trim( (string) ( $featured['summary'] ?? '' ) ) && ! empty( $by_path[ $f_key ]['summary'] ) ) {
|
||||||
|
$featured['summary'] = $by_path[ $f_key ]['summary'];
|
||||||
|
}
|
||||||
|
if ( empty( $featured['image_url'] ) && ! empty( $by_path[ $f_key ]['image_url'] ) ) {
|
||||||
|
$featured['image_url'] = $by_path[ $f_key ]['image_url'];
|
||||||
|
}
|
||||||
|
if ( ( empty( $featured['category'] ) || 'Confédération CGT' === $featured['category'] ) && ! empty( $by_path[ $f_key ]['category'] ) ) {
|
||||||
|
$featured['category'] = $by_path[ $f_key ]['category'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enrichit les 3 cartes "latest" depuis /actualites sans écraser image_a_la_une.
|
||||||
|
foreach ( $latest as $idx => $item ) {
|
||||||
|
$l_key = self::normalize_url_key( $item['url'] );
|
||||||
|
if ( isset( $by_path[ $l_key ] ) ) {
|
||||||
|
if ( '' === trim( (string) ( $item['summary'] ?? '' ) ) && ! empty( $by_path[ $l_key ]['summary'] ) ) {
|
||||||
|
$latest[ $idx ]['summary'] = $by_path[ $l_key ]['summary'];
|
||||||
|
}
|
||||||
|
if ( empty( $item['image_url'] ) && ! empty( $by_path[ $l_key ]['image_url'] ) ) {
|
||||||
|
$latest[ $idx ]['image_url'] = $by_path[ $l_key ]['image_url'];
|
||||||
|
}
|
||||||
|
if ( ( empty( $item['category'] ) || 'Confédération CGT' === $item['category'] ) && ! empty( $by_path[ $l_key ]['category'] ) ) {
|
||||||
|
$latest[ $idx ]['category'] = $by_path[ $l_key ]['category'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback complet si la page d'accueil a changé de structure.
|
||||||
|
if ( empty( $featured['title'] ) && count( $actus_items ) >= 2 ) {
|
||||||
|
$featured = array_shift( $actus_items );
|
||||||
|
$latest = array_slice( $actus_items, 0, 3 );
|
||||||
|
$source = 'https://www.cgt.fr/actualites (fallback)';
|
||||||
|
} elseif ( count( $latest ) < 3 ) {
|
||||||
|
$seen = array( self::normalize_url_key( (string) ( $featured['url'] ?? '' ) ) );
|
||||||
|
foreach ( $latest as $l ) {
|
||||||
|
$seen[] = self::normalize_url_key( (string) $l['url'] );
|
||||||
|
}
|
||||||
|
foreach ( $actus_items as $act ) {
|
||||||
|
if ( count( $latest ) >= 3 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$act_key = self::normalize_url_key( $act['url'] );
|
||||||
|
if ( '' !== $act_key && ! in_array( $act_key, $seen, true ) ) {
|
||||||
|
$latest[] = $act;
|
||||||
|
$seen[] = $act_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $featured['title'] ) || empty( $latest ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback final : complète un éventuel article épinglé absent de la page 1 d'/actualites.
|
||||||
|
if ( '' === trim( (string) ( $featured['summary'] ?? '' ) ) || empty( $featured['image_url'] ) ) {
|
||||||
|
$featured = self::enrich_from_article_page( $featured );
|
||||||
|
}
|
||||||
|
foreach ( $latest as $idx => $item ) {
|
||||||
|
if ( '' === trim( (string) ( $item['summary'] ?? '' ) ) || empty( $item['image_url'] ) ) {
|
||||||
|
$latest[ $idx ] = self::enrich_from_article_page( $item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'fetched_at' => time(),
|
||||||
|
'source' => $source,
|
||||||
|
'featured' => self::normalize_article( $featured, 240 ),
|
||||||
|
'latest' => array_map(
|
||||||
|
static fn( array $item ): array => self::normalize_article( $item, 190 ),
|
||||||
|
array_slice( $latest, 0, 3 )
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requête HTTP GET sécurisée avec timeout 10s.
|
||||||
|
*/
|
||||||
|
private static function remote_get_html( string $url ): string {
|
||||||
|
$response = wp_remote_get(
|
||||||
|
$url,
|
||||||
|
array(
|
||||||
|
'timeout' => 10,
|
||||||
|
'redirection' => 3,
|
||||||
|
'user-agent' => 'Mozilla/5.0 (compatible; CGT-FHA-Theme/1.1; +https://cgt-fha.fr/)',
|
||||||
|
'headers' => array(
|
||||||
|
'Accept' => 'text/html,application/xhtml+xml',
|
||||||
|
'Accept-Language' => 'fr-FR,fr;q=0.9',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = (int) wp_remote_retrieve_response_code( $response );
|
||||||
|
if ( $code < 200 || $code >= 400 ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) wp_remote_retrieve_body( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse la page d'accueil cgt.fr :
|
||||||
|
* - "À la une de la CGT" (#block-bluedrop-views-block-derniers-ajouts-block-2, .relative-wrapper)
|
||||||
|
* - "mais aussi..." (#block-views-block-derniers-ajouts-block-1, .views-row)
|
||||||
|
*
|
||||||
|
* @return array{featured: array<string, string>, latest: array<int, array<string, string>>}
|
||||||
|
*/
|
||||||
|
private static function parse_homepage_html( string $html ): array {
|
||||||
|
$xpath = self::create_xpath( $html );
|
||||||
|
if ( ! $xpath ) {
|
||||||
|
return array( 'featured' => array(), 'latest' => array() );
|
||||||
|
}
|
||||||
|
|
||||||
|
$featured = array();
|
||||||
|
$latest = array();
|
||||||
|
|
||||||
|
// 1. Bloc « à la une de la cgt » (ID Drupal exact + secours par titre de section).
|
||||||
|
$une_root = null;
|
||||||
|
$une_nodes = $xpath->query( '//section[@id="block-bluedrop-views-block-derniers-ajouts-block-2"]' );
|
||||||
|
if ( $une_nodes instanceof DOMNodeList && $une_nodes->length > 0 ) {
|
||||||
|
$une_root = $une_nodes->item( 0 );
|
||||||
|
} else {
|
||||||
|
$une_root = self::find_section_by_heading_text( $xpath, 'la une de la cgt' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $une_root ) {
|
||||||
|
$wrappers = $xpath->query( './/div[contains(@class,"relative-wrapper")]', $une_root );
|
||||||
|
$card_el = ( $wrappers instanceof DOMNodeList && $wrappers->length > 0 ) ? $wrappers->item( 0 ) : $une_root;
|
||||||
|
$parsed = self::extract_drupal_row( $xpath, $card_el );
|
||||||
|
if ( ! empty( $parsed['title'] ) && ! empty( $parsed['url'] ) ) {
|
||||||
|
$featured = $parsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Bloc « mais aussi... » (ID Drupal exact + secours par titre de section).
|
||||||
|
$mais_root = null;
|
||||||
|
$mais_nodes = $xpath->query( '//section[@id="block-views-block-derniers-ajouts-block-1"]' );
|
||||||
|
if ( $mais_nodes instanceof DOMNodeList && $mais_nodes->length > 0 ) {
|
||||||
|
$mais_root = $mais_nodes->item( 0 );
|
||||||
|
} else {
|
||||||
|
$mais_root = self::find_section_by_heading_text( $xpath, 'mais aussi' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $mais_root ) {
|
||||||
|
$rows = $xpath->query( './/div[contains(@class,"views-row")]', $mais_root );
|
||||||
|
if ( $rows instanceof DOMNodeList ) {
|
||||||
|
$seen = array( self::normalize_url_key( (string) ( $featured['url'] ?? '' ) ) );
|
||||||
|
foreach ( $rows as $row ) {
|
||||||
|
if ( count( $latest ) >= 3 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$item = self::extract_drupal_row( $xpath, $row );
|
||||||
|
$key = self::normalize_url_key( (string) ( $item['url'] ?? '' ) );
|
||||||
|
if ( ! empty( $item['title'] ) && '' !== $key && ! in_array( $key, $seen, true ) ) {
|
||||||
|
$latest[] = $item;
|
||||||
|
$seen[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'featured' => $featured,
|
||||||
|
'latest' => $latest,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse la liste des articles de https://www.cgt.fr/actualites (jusqu'à 25 lignes .views-row).
|
||||||
|
*
|
||||||
|
* @return array<int, array<string, string>>
|
||||||
|
*/
|
||||||
|
private static function parse_actualites_html( string $html ): array {
|
||||||
|
$xpath = self::create_xpath( $html );
|
||||||
|
if ( ! $xpath || ! $xpath->document->documentElement ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $xpath->query( '//main//div[contains(@class,"views-row")]|//div[contains(@class,"view-content")]//div[contains(@class,"views-row")]' );
|
||||||
|
if ( ! ( $rows instanceof DOMNodeList ) || 0 === $rows->length ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$articles = array();
|
||||||
|
$seen = array();
|
||||||
|
foreach ( $rows as $row ) {
|
||||||
|
if ( count( $articles ) >= 25 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$item = self::extract_drupal_row( $xpath, $row );
|
||||||
|
$key = self::normalize_url_key( (string) ( $item['url'] ?? '' ) );
|
||||||
|
if ( ! empty( $item['title'] ) && '' !== $key && ! isset( $seen[ $key ] ) ) {
|
||||||
|
$seen[ $key ] = true;
|
||||||
|
$articles[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $articles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extrait proprement un article depuis un conteneur Drupal (bloc À la une ou .views-row).
|
||||||
|
*
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private static function extract_drupal_row( DOMXPath $xpath, DOMNode $row ): array {
|
||||||
|
$link_el = null;
|
||||||
|
$h_links = $xpath->query( './/h3//a[@href]|.//h2//a[@href]|.//h4//a[@href]', $row );
|
||||||
|
if ( $h_links instanceof DOMNodeList ) {
|
||||||
|
foreach ( $h_links as $cand ) {
|
||||||
|
$href = trim( $cand->getAttribute( 'href' ) );
|
||||||
|
if ( self::is_article_href( $href ) ) {
|
||||||
|
$link_el = $cand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $link_el ) {
|
||||||
|
$fallback_links = $xpath->query( './/a[@href and not(contains(@href,"/terms/")) and not(contains(@href,"/taxonomy/")) and not(contains(@class,"taxonomy-style")) and not(contains(@class,"more-link"))]', $row );
|
||||||
|
if ( $fallback_links instanceof DOMNodeList ) {
|
||||||
|
foreach ( $fallback_links as $cand ) {
|
||||||
|
$href = trim( $cand->getAttribute( 'href' ) );
|
||||||
|
if ( self::is_article_href( $href ) ) {
|
||||||
|
$link_el = $cand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $link_el ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = self::absolutize_url( $link_el->getAttribute( 'href' ) );
|
||||||
|
$title = self::normalize_space( $link_el->textContent );
|
||||||
|
if ( '' === $url || strlen( $title ) < 6 ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catégories (.taxonomy-style hors badge .highlighted).
|
||||||
|
$cats = array();
|
||||||
|
$cat_nodes = $xpath->query( './/*[contains(@class,"taxonomy-style")]', $row );
|
||||||
|
if ( $cat_nodes instanceof DOMNodeList ) {
|
||||||
|
foreach ( $cat_nodes as $cat_node ) {
|
||||||
|
if ( $cat_node instanceof DOMElement && false !== strpos( $cat_node->getAttribute( 'class' ), 'highlighted' ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$cat_txt = self::normalize_space( $cat_node->textContent );
|
||||||
|
if ( '' !== $cat_txt && strlen( $cat_txt ) < 45 && ! in_array( $cat_txt, $cats, true ) ) {
|
||||||
|
$cats[] = $cat_txt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$category = ! empty( $cats ) ? implode( ' | ', array_slice( $cats, 0, 2 ) ) : 'Confédération CGT';
|
||||||
|
|
||||||
|
// Résumé (.field-type-text-long ou paragraphe dans .txt-container).
|
||||||
|
$summary = '';
|
||||||
|
$p_nodes = $xpath->query( './/*[contains(@class,"field-type-text-long")]|.//div[contains(@class,"txt-container")]//p|.//p', $row );
|
||||||
|
if ( $p_nodes instanceof DOMNodeList ) {
|
||||||
|
foreach ( $p_nodes as $p ) {
|
||||||
|
$txt = self::normalize_space( $p->textContent );
|
||||||
|
if ( strlen( $txt ) >= 10 && $txt !== $title ) {
|
||||||
|
$summary = $txt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image (.views-field-field-imagette-media img en priorité, sinon premier img).
|
||||||
|
$image_url = '';
|
||||||
|
$img_nodes = $xpath->query( './/div[contains(@class,"views-field-field-imagette-media")]//img|.//img', $row );
|
||||||
|
if ( $img_nodes instanceof DOMNodeList && $img_nodes->length > 0 ) {
|
||||||
|
$img = $img_nodes->item( 0 );
|
||||||
|
if ( $img instanceof DOMElement ) {
|
||||||
|
$src = $img->getAttribute( 'data-src' ) ?: $img->getAttribute( 'src' );
|
||||||
|
if ( '' === $src && $img->hasAttribute( 'srcset' ) ) {
|
||||||
|
$parts = explode( ',', $img->getAttribute( 'srcset' ) );
|
||||||
|
$first = trim( (string) $parts[0] );
|
||||||
|
$src = strtok( $first, ' ' ) ?: '';
|
||||||
|
}
|
||||||
|
$image_url = self::absolutize_url( $src );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'title' => $title,
|
||||||
|
'summary' => $summary,
|
||||||
|
'image_url' => $image_url,
|
||||||
|
'category' => $category,
|
||||||
|
'url' => $url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enrichit un article directement depuis sa page individuelle sur cgt.fr si résumé ou image manquent.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $item Article partiel.
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private static function enrich_from_article_page( array $item ): array {
|
||||||
|
if ( empty( $item['url'] ) ) {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = self::remote_get_html( $item['url'] );
|
||||||
|
if ( '' === $html ) {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xpath = self::create_xpath( $html );
|
||||||
|
if ( ! $xpath ) {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( '' === trim( (string) ( $item['summary'] ?? '' ) ) ) {
|
||||||
|
$candidates = array(
|
||||||
|
'.//*[contains(@class,"chapo") or contains(@class,"field-name-field-chapo")]',
|
||||||
|
'//meta[@property="og:description"]/@content',
|
||||||
|
'//meta[@name="description"]/@content',
|
||||||
|
'//main//article//p',
|
||||||
|
);
|
||||||
|
foreach ( $candidates as $query ) {
|
||||||
|
$nodes = $xpath->query( $query );
|
||||||
|
if ( $nodes instanceof DOMNodeList && $nodes->length > 0 ) {
|
||||||
|
foreach ( $nodes as $node ) {
|
||||||
|
$txt = self::normalize_space( $node instanceof DOMAttr ? $node->value : $node->textContent );
|
||||||
|
if ( strlen( $txt ) >= 15 && $txt !== ( $item['title'] ?? '' ) ) {
|
||||||
|
$item['summary'] = $txt;
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $item['image_url'] ) ) {
|
||||||
|
$og_img = $xpath->query( '//meta[@property="og:image"]/@content' );
|
||||||
|
if ( $og_img instanceof DOMNodeList && $og_img->length > 0 ) {
|
||||||
|
$src = trim( (string) $og_img->item( 0 )->nodeValue );
|
||||||
|
if ( '' !== $src ) {
|
||||||
|
$item['image_url'] = self::absolutize_url( $src );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Localise la section ancêtre correspondant à un titre textuel donné.
|
||||||
|
*/
|
||||||
|
private static function find_section_by_heading_text( DOMXPath $xpath, string $needle ): ?DOMNode {
|
||||||
|
$headings = $xpath->query( '//h1|//h2|//h3' );
|
||||||
|
if ( ! ( $headings instanceof DOMNodeList ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $headings as $heading ) {
|
||||||
|
$text = self::normalize_space( $heading->textContent );
|
||||||
|
$low = function_exists( 'mb_strtolower' ) ? mb_strtolower( $text, 'UTF-8' ) : strtolower( $text );
|
||||||
|
if ( false !== strpos( $low, $needle ) ) {
|
||||||
|
$cur = $heading->parentNode;
|
||||||
|
while ( $cur && $cur instanceof DOMElement ) {
|
||||||
|
if ( 'section' === strtolower( $cur->tagName ) ) {
|
||||||
|
return $cur;
|
||||||
|
}
|
||||||
|
$cur = $cur->parentNode;
|
||||||
|
}
|
||||||
|
return $heading->parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie qu'un href pointe vers un article (et non une taxonomie ou l'index /actualites).
|
||||||
|
*/
|
||||||
|
private static function is_article_href( string $href ): bool {
|
||||||
|
if ( '' === $href || '#' === $href || 0 === strpos( $href, 'mailto:' ) || 0 === strpos( $href, 'tel:' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( false !== strpos( $href, '/terms/' ) || false !== strpos( $href, '/taxonomy/' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$path = untrailingslashit( (string) wp_parse_url( $href, PHP_URL_PATH ) );
|
||||||
|
return '' !== $path && '/actualites' !== $path && '/' !== $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalise une URL sur son chemin pour la correspondance fiable entre accueil et /actualites.
|
||||||
|
*/
|
||||||
|
private static function normalize_url_key( string $url ): string {
|
||||||
|
$path = (string) wp_parse_url( trim( $url ), PHP_URL_PATH );
|
||||||
|
$path = strtolower( untrailingslashit( $path ) );
|
||||||
|
return '' === $path || '/' === $path ? '' : $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise un DOMXPath UTF-8 fiable sur PHP 8.x sans altérer les accents ni apostrophes typographiques.
|
||||||
|
*/
|
||||||
|
private static function create_xpath( string $html ): ?DOMXPath {
|
||||||
|
if ( '' === trim( $html ) || ! class_exists( 'DOMDocument' ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( function_exists( 'mb_encode_numericentity' ) ) {
|
||||||
|
$prepared = mb_encode_numericentity( $html, array( 0x80, 0x10FFFF, 0, ~0 ), 'UTF-8' );
|
||||||
|
} else {
|
||||||
|
$prepared = preg_replace( '/<head\b[^>]*>/i', '$0<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">', $html, 1 ) ?: $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev = libxml_use_internal_errors( true );
|
||||||
|
$dom = new DOMDocument( '1.0', 'UTF-8' );
|
||||||
|
$dom->loadHTML( $prepared, LIBXML_NONET | LIBXML_NOWARNING | LIBXML_NOERROR );
|
||||||
|
libxml_clear_errors();
|
||||||
|
libxml_use_internal_errors( $prev );
|
||||||
|
|
||||||
|
return new DOMXPath( $dom );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convertit une URL relative cgt.fr en URL absolue.
|
||||||
|
*/
|
||||||
|
private static function absolutize_url( string $raw ): string {
|
||||||
|
$raw = trim( $raw );
|
||||||
|
if ( '' === $raw || 0 === strpos( $raw, 'data:' ) || 0 === strpos( $raw, 'javascript:' ) ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if ( 0 === strpos( $raw, '//' ) ) {
|
||||||
|
return 'https:' . $raw;
|
||||||
|
}
|
||||||
|
if ( preg_match( '#^https?://#i', $raw ) ) {
|
||||||
|
return esc_url_raw( $raw );
|
||||||
|
}
|
||||||
|
if ( '/' === $raw[0] ) {
|
||||||
|
return esc_url_raw( 'https://www.cgt.fr' . $raw );
|
||||||
|
}
|
||||||
|
return esc_url_raw( 'https://www.cgt.fr/' . ltrim( $raw, '/' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalise les espaces blancs et entités HTML.
|
||||||
|
*/
|
||||||
|
private static function normalize_space( string $text ): string {
|
||||||
|
$decoded = html_entity_decode( wp_strip_all_tags( $text ), ENT_QUOTES | ENT_HTML5, 'UTF-8' );
|
||||||
|
return trim( (string) preg_replace( '/\s+/u', ' ', $decoded ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoie et tronque un article pour l'affichage sans phrase générique répétitive.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $item Données brutes de l'article.
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
private static function normalize_article( array $item, int $max_chars = 190 ): array {
|
||||||
|
$placeholder = CGT_FHA_URI . '/assets/img/placeholder.svg';
|
||||||
|
$summary = self::normalize_space( (string) ( $item['summary'] ?? '' ) );
|
||||||
|
if ( '' !== $summary && function_exists( 'mb_strlen' ) && mb_strlen( $summary, 'UTF-8' ) > $max_chars ) {
|
||||||
|
$summary = rtrim( mb_substr( $summary, 0, $max_chars - 1, 'UTF-8' ) ) . '…';
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'title' => self::normalize_space( (string) ( $item['title'] ?? '' ) ),
|
||||||
|
'summary' => $summary,
|
||||||
|
'image_url' => ! empty( $item['image_url'] ) ? esc_url_raw( (string) $item['image_url'] ) : $placeholder,
|
||||||
|
'category' => self::normalize_space( (string) ( $item['category'] ?? 'Confédération CGT' ) ),
|
||||||
|
'url' => ! empty( $item['url'] ) ? esc_url_raw( (string) $item['url'] ) : 'https://www.cgt.fr/actualites',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback statique si cgt.fr est inaccessible lors du premier démarrage.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
private static function get_static_fallback(): array {
|
||||||
|
$placeholder = CGT_FHA_URI . '/assets/img/placeholder.svg';
|
||||||
|
return array(
|
||||||
|
'fetched_at' => 0,
|
||||||
|
'source' => 'Fallback éditorial local',
|
||||||
|
'featured' => array(
|
||||||
|
'title' => 'Salaires, retraites, services publics : toutes et tous mobilisés avec la CGT',
|
||||||
|
'summary' => 'Retrouvez les dossiers nationaux, les revendications confédérales et les appels à l\'action portés par la CGT partout en France.',
|
||||||
|
'image_url' => $placeholder,
|
||||||
|
'category' => 'À la une',
|
||||||
|
'url' => 'https://www.cgt.fr/actualites',
|
||||||
|
),
|
||||||
|
'latest' => array(
|
||||||
|
array(
|
||||||
|
'title' => 'Pouvoir d\'achat : augmenter les salaires et le SMIC',
|
||||||
|
'summary' => 'Les propositions économiques de la CGT pour indexer les salaires sur l\'inflation et revaloriser les grilles.',
|
||||||
|
'image_url' => $placeholder,
|
||||||
|
'category' => 'Salaires',
|
||||||
|
'url' => 'https://www.cgt.fr/actualites',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => 'Conditions de travail & santé au travail',
|
||||||
|
'summary' => 'Prévenir l\'usure professionnelle, renforcer le rôle des élus CSE et défendre les droits des salarié·e·s.',
|
||||||
|
'image_url' => $placeholder,
|
||||||
|
'category' => 'Travail',
|
||||||
|
'url' => 'https://www.cgt.fr/actualites',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => 'Services publics de proximité dans nos territoires',
|
||||||
|
'summary' => 'Défendre l\'hôpital public, l\'école, les transports et les services publics essentiels en milieu rural.',
|
||||||
|
'image_url' => $placeholder,
|
||||||
|
'category' => 'Services publics',
|
||||||
|
'url' => 'https://www.cgt.fr/actualites',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendu HTML/CSS de la Section 4 (fidèle à la maquette).
|
||||||
|
*/
|
||||||
|
public static function render_section( string $section_title = 'ACTUALITÉ CONFÉDÉRALE' ): void {
|
||||||
|
$feed = self::get_feed();
|
||||||
|
$featured = $feed['featured'] ?? array();
|
||||||
|
$latest = $feed['latest'] ?? array();
|
||||||
|
|
||||||
|
if ( empty( $featured ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<section class="cgt-section cgt-section--soft" aria-labelledby="cgt-confederal-heading">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<h2 id="cgt-confederal-heading" class="cgt-section__title"><?php echo esc_html( $section_title ); ?></h2>
|
||||||
|
|
||||||
|
<!-- Bloc supérieur « À LA UNE » -->
|
||||||
|
<article class="cgt-confederal-featured">
|
||||||
|
<div class="cgt-confederal-featured__media">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $featured['image_url'] ); ?>"
|
||||||
|
alt="<?php echo esc_attr( $featured['title'] ); ?>"
|
||||||
|
class="cgt-confederal-featured__img"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<span class="cgt-confederal-featured__badge">À LA UNE</span>
|
||||||
|
</div>
|
||||||
|
<div class="cgt-confederal-featured__box">
|
||||||
|
<span class="cgt-confederal-featured__kicker"><?php echo esc_html( $featured['category'] ?: 'À LA UNE' ); ?></span>
|
||||||
|
<h3 class="cgt-confederal-featured__title"><?php echo esc_html( $featured['title'] ); ?></h3>
|
||||||
|
<?php if ( '' !== trim( (string) ( $featured['summary'] ?? '' ) ) ) : ?>
|
||||||
|
<p class="cgt-confederal-featured__summary"><?php echo esc_html( $featured['summary'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url( $featured['url'] ); ?>"
|
||||||
|
class="cgt-btn cgt-btn--outline-dark"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>LIRE SUR CGT.FR ↗</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<!-- Grille inférieure : 3 articles -->
|
||||||
|
<?php if ( ! empty( $latest ) ) : ?>
|
||||||
|
<div class="cgt-confederal-grid">
|
||||||
|
<?php foreach ( $latest as $item ) : ?>
|
||||||
|
<article class="cgt-confederal-card">
|
||||||
|
<img
|
||||||
|
src="<?php echo esc_url( $item['image_url'] ); ?>"
|
||||||
|
alt="<?php echo esc_attr( $item['title'] ); ?>"
|
||||||
|
class="cgt-confederal-card__img"
|
||||||
|
loading="lazy"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
<div class="cgt-confederal-card__box">
|
||||||
|
<h3 class="cgt-confederal-card__title"><?php echo esc_html( $item['title'] ); ?></h3>
|
||||||
|
<?php if ( '' !== trim( (string) ( $item['summary'] ?? '' ) ) ) : ?>
|
||||||
|
<p class="cgt-confederal-card__summary"><?php echo esc_html( $item['summary'] ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="cgt-confederal-card__cta">
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url( $item['url'] ); ?>"
|
||||||
|
class="cgt-confederal-more"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<span class="cgt-confederal-more__label">Lire la suite</span>
|
||||||
|
<span class="cgt-confederal-more__arrow" aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGT_FHA_Confederal_Feed::init();
|
||||||
180
inc/seo-performance.php
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* SEO local, OpenGraph, Alerte Indexation Admin & Optimisation Performance.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Titre SEO personnalisé.
|
||||||
|
*/
|
||||||
|
add_filter( 'pre_get_document_title', 'cgt_fha_document_title', 20 );
|
||||||
|
function cgt_fha_document_title( string $title ): string {
|
||||||
|
$site_brand = 'Union Locale CGT Foix Haute-Ariège';
|
||||||
|
|
||||||
|
if ( is_front_page() ) {
|
||||||
|
return $site_brand . ' | Défense des salariés et action syndicale';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_singular() ) {
|
||||||
|
return wp_strip_all_tags( get_the_title() ) . ' | ' . $site_brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_home() ) {
|
||||||
|
return 'Actualités locales | ' . $site_brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_archive() ) {
|
||||||
|
return wp_strip_all_tags( get_the_archive_title() ) . ' | ' . $site_brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_404() ) {
|
||||||
|
return 'Page introuvable | ' . $site_brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title ?: $site_brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcule la meta description adaptée au contexte courant.
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_meta_description(): string {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
|
||||||
|
if ( is_front_page() ) {
|
||||||
|
return wp_strip_all_tags(
|
||||||
|
"Union Locale CGT de Foix et de la Haute-Ariège : union des syndicats CGT du territoire, rattachement des salarié·e·s isolé·e·s via le syndicat Multipros et permanences à l'Espace Sabart."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_singular() ) {
|
||||||
|
$post = get_queried_object();
|
||||||
|
if ( $post instanceof WP_Post ) {
|
||||||
|
$raw = has_excerpt( $post ) ? $post->post_excerpt : $post->post_content;
|
||||||
|
$txt = trim( (string) preg_replace( '/\s+/u', ' ', wp_strip_all_tags( strip_shortcodes( $raw ) ) ) );
|
||||||
|
if ( '' !== $txt ) {
|
||||||
|
return wp_html_excerpt( $txt, 158, '…' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_category() || is_tag() ) {
|
||||||
|
$desc = trim( wp_strip_all_tags( term_description() ) );
|
||||||
|
if ( '' !== $desc ) {
|
||||||
|
return wp_html_excerpt( $desc, 158, '…' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_html_excerpt( (string) $opts['footer_desc'], 158, '…' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection automatique des balises <meta name="description"> et OpenGraph.
|
||||||
|
*/
|
||||||
|
add_action( 'wp_head', 'cgt_fha_render_meta_and_og', 2 );
|
||||||
|
function cgt_fha_render_meta_and_og(): void {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$title = cgt_fha_document_title( wp_get_document_title() );
|
||||||
|
$description = cgt_fha_get_meta_description();
|
||||||
|
$og_type = is_single() ? 'article' : 'website';
|
||||||
|
|
||||||
|
if ( is_front_page() ) {
|
||||||
|
$url = home_url( '/' );
|
||||||
|
} elseif ( is_singular() ) {
|
||||||
|
$url = get_permalink() ?: home_url( '/' );
|
||||||
|
} else {
|
||||||
|
global $wp;
|
||||||
|
$url = home_url( add_query_arg( array(), $wp->request ?? '' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$og_image = (string) $opts['hero_bg_url'];
|
||||||
|
if ( is_singular() && has_post_thumbnail() ) {
|
||||||
|
$thumb_url = get_the_post_thumbnail_url( get_queried_object_id(), 'cgt-featured' );
|
||||||
|
if ( $thumb_url ) {
|
||||||
|
$og_image = $thumb_url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<meta name="description" content="<?php echo esc_attr( $description ); ?>" />
|
||||||
|
<meta property="og:locale" content="fr_FR" />
|
||||||
|
<meta property="og:site_name" content="Union Locale CGT Foix Haute-Ariège" />
|
||||||
|
<meta property="og:type" content="<?php echo esc_attr( $og_type ); ?>" />
|
||||||
|
<meta property="og:title" content="<?php echo esc_attr( $title ); ?>" />
|
||||||
|
<meta property="og:description" content="<?php echo esc_attr( $description ); ?>" />
|
||||||
|
<meta property="og:url" content="<?php echo esc_url( $url ); ?>" />
|
||||||
|
<?php if ( '' !== $og_image ) : ?>
|
||||||
|
<meta property="og:image" content="<?php echo esc_url( $og_image ); ?>" />
|
||||||
|
<?php endif; ?>
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alerte rouge dans le tableau de bord si l'indexation des moteurs de recherche est bloquée.
|
||||||
|
*/
|
||||||
|
add_action( 'admin_notices', 'cgt_fha_indexation_warning_notice' );
|
||||||
|
function cgt_fha_indexation_warning_notice(): void {
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( '0' === (string) get_option( 'blog_public' ) ) {
|
||||||
|
$reading_url = admin_url( 'options-reading.php' );
|
||||||
|
?>
|
||||||
|
<div class="notice notice-error" style="border-left-color:#d20012; background:#fff5f5;">
|
||||||
|
<p>
|
||||||
|
<strong style="color:#d20012;">Alerte SEO — Indexation bloquée :</strong>
|
||||||
|
Votre site demande actuellement aux moteurs de recherche de ne pas l'indexer.
|
||||||
|
<a href="<?php echo esc_url( $reading_url ); ?>">Rendez-vous dans Réglages > Lecture</a>
|
||||||
|
et décochez « Demander aux moteurs de recherche de ne pas indexer ce site ».
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoyage du head WordPress et suppression de wp-emoji / wp-embed pour un TTFB et LCP optimaux.
|
||||||
|
*/
|
||||||
|
add_action( 'init', 'cgt_fha_cleanup_wp_bloat' );
|
||||||
|
function cgt_fha_cleanup_wp_bloat(): void {
|
||||||
|
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
|
||||||
|
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
||||||
|
remove_action( 'wp_print_styles', 'print_emoji_styles' );
|
||||||
|
remove_action( 'admin_print_styles', 'print_emoji_styles' );
|
||||||
|
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
|
||||||
|
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
|
||||||
|
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
|
||||||
|
|
||||||
|
remove_action( 'wp_head', 'rsd_link' );
|
||||||
|
remove_action( 'wp_head', 'wlwmanifest_link' );
|
||||||
|
remove_action( 'wp_head', 'wp_generator' );
|
||||||
|
remove_action( 'wp_head', 'wp_shortlink_wp_head' );
|
||||||
|
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'wp_footer', 'cgt_fha_disable_wp_embed' );
|
||||||
|
function cgt_fha_disable_wp_embed(): void {
|
||||||
|
wp_deregister_script( 'wp-embed' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajoute loading="lazy" et decoding="async" sur les images hors ligne de flottaison.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $attr Attributs de la balise img.
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
add_filter( 'wp_get_attachment_image_attributes', 'cgt_fha_lazy_image_attributes', 10, 1 );
|
||||||
|
function cgt_fha_lazy_image_attributes( array $attr ): array {
|
||||||
|
if ( empty( $attr['fetchpriority'] ) && empty( $attr['loading'] ) ) {
|
||||||
|
$attr['loading'] = 'lazy';
|
||||||
|
}
|
||||||
|
if ( empty( $attr['decoding'] ) ) {
|
||||||
|
$attr['decoding'] = 'async';
|
||||||
|
}
|
||||||
|
return $attr;
|
||||||
|
}
|
||||||
776
inc/theme-options.php
Normal file
@ -0,0 +1,776 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Panneau d'administration WordPress : Apparence > Réglages UL CGT
|
||||||
|
*
|
||||||
|
* Toutes les options sont pré-remplies par défaut via wp_parse_args()
|
||||||
|
* afin que le thème soit immédiatement fonctionnel dès son activation.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CGT_FHA_OPTION_KEY = 'cgt_fha_options';
|
||||||
|
const CGT_FHA_SCHEMA_VERSION = '1.2.0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valeurs par défaut complètes de toutes les options du thème.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_defaults(): array {
|
||||||
|
return array(
|
||||||
|
// Onglet 1 : Identité & Coordonnées.
|
||||||
|
'phone' => '07 60 49 64 69',
|
||||||
|
'email' => 'union-locale@cgt-fha.fr',
|
||||||
|
'address' => "Espace Sabart, 10 Av. de l'Ayroule, 09400 Tarascon-sur-Ariège",
|
||||||
|
'hours' => "Permanences d'accueil et juridiques : Mardi et Jeudi de 9h30 à 12h30, et sur rendez-vous.",
|
||||||
|
'facebook_url' => 'https://www.facebook.com/profile.php?id=61552410568856',
|
||||||
|
'instagram_url' => '',
|
||||||
|
'youtube_url' => '',
|
||||||
|
'header_logo_url' => CGT_FHA_URI . '/assets/img/banniere-ul-noir.png',
|
||||||
|
'footer_logo_url' => CGT_FHA_URI . '/assets/img/banniere-ul-blanc.png',
|
||||||
|
'footer_desc' => "L'Union Locale CGT de Foix et de la Haute-Ariège rassemble tous les syndicats CGT de son périmètre et rattache directement les salarié·e·s isolé·e·s au sein de son syndicat multiprofessionnel (Multipros).",
|
||||||
|
'footer_call' => "Une lutte dans votre entreprise, une info à partager ? Contactez l'UL",
|
||||||
|
'news_url' => home_url( '/actualites/' ),
|
||||||
|
'calendar_url' => home_url( '/calendrier/' ),
|
||||||
|
'contact_url' => home_url( '/contact/' ),
|
||||||
|
'join_url' => home_url( '/syndiquez-vous/' ),
|
||||||
|
'legal_url' => home_url( '/mentions-legales/' ),
|
||||||
|
|
||||||
|
// Onglet 2 : Bandeau Mobilisation auto-expirant.
|
||||||
|
'banner_enabled' => 0,
|
||||||
|
'banner_text' => 'MOBILISATION : Grève et manifestation à Foix - Allées de Villote',
|
||||||
|
'banner_url' => '',
|
||||||
|
'banner_expires' => wp_date( 'Y-m-d\TH:i', time() + 7 * DAY_IN_SECONDS ),
|
||||||
|
|
||||||
|
// Onglet 3 : Page d'accueil — Hero.
|
||||||
|
'hero_bg_url' => CGT_FHA_URI . '/assets/img/hero-ariege.jpg',
|
||||||
|
'hero_title_line1' => 'Union Locale CGT Foix Haute-Ariège',
|
||||||
|
'hero_title_line2' => 'Votre syndicat de proximité !',
|
||||||
|
'hero_quote' => '« La régression sociale ne se négocie pas, elle se combat ! » — Henri Krasucki, Secrétaire Général de la CGT de 1982 à 1992',
|
||||||
|
'hero_btn1_label' => "J'ai besoin d'aide",
|
||||||
|
'hero_btn1_url' => home_url( '/contact/' ),
|
||||||
|
'hero_btn2_label' => 'Rejoindre la CGT',
|
||||||
|
'hero_btn2_url' => home_url( '/syndiquez-vous/' ),
|
||||||
|
|
||||||
|
// Onglet 3 : Section 2 — À quoi nous servons ?
|
||||||
|
'missions_title' => 'À QUOI NOUS SERVONS ?',
|
||||||
|
'missions_subtitle' => "L'Union Locale fédère l'ensemble des syndicats CGT du bassin de Foix et de la Haute-Ariège, et accueille directement les salarié·e·s sans syndicat d'entreprise grâce à son syndicat multiprofessionnel (Multipros).",
|
||||||
|
'mission_1_icon' => 'fist',
|
||||||
|
'mission_1_title' => "S'ORGANISER",
|
||||||
|
'mission_1_text' => "Unir tous les syndicats CGT de Foix et de la Haute-Ariège, créer une section dans votre entreprise ou vous syndiquer directement via le syndicat Multipros de l'Union Locale.",
|
||||||
|
'mission_2_icon' => 'shield',
|
||||||
|
'mission_2_title' => 'SE DÉFENDRE',
|
||||||
|
'mission_2_text' => "Faire respecter vos droits, vos salaires et vos conditions de travail à Foix comme en Haute-Ariège, avec l'appui solidaire de nos syndicats, conseillers du salarié et défenseurs.",
|
||||||
|
'mission_3_icon' => 'chat',
|
||||||
|
'mission_3_title' => "S'INFORMER & SE FORMER",
|
||||||
|
'mission_3_text' => "Partager l'actualité des luttes à Foix et en Haute-Ariège et exercer votre droit légal à la formation syndicale (CFESES) pour agir collectivement.",
|
||||||
|
|
||||||
|
// Onglet 3 : Titres Actualités locales & confédérales.
|
||||||
|
'local_news_title' => 'SUR LE TERRAIN À FOIX ET EN HAUTE-ARIÈGE',
|
||||||
|
'local_news_more' => 'Voir toutes les actualités locales →',
|
||||||
|
'confederal_title' => 'ACTUALITÉ CONFÉDÉRALE',
|
||||||
|
|
||||||
|
// Onglet 3 : Section 5 — Salariés isolés & TPE (Multipros).
|
||||||
|
'tpe_enabled' => 1,
|
||||||
|
'tpe_badge' => "Syndicat Multipros de l'UL · TPE, PME & Isolé·e·s",
|
||||||
|
'tpe_title' => "SALARIÉS ISOLÉS & TPE : VOUS N'ÊTES PAS SEULS",
|
||||||
|
'tpe_text' => "À Foix comme en Haute-Ariège, même sans section syndicale ni CSE dans votre entreprise (TPE, commerce, artisanat, chantier, association…), l'Union Locale est votre maison commune : vous êtes rattaché·e directement au syndicat multiprofessionnel (Multipros) de l'UL.",
|
||||||
|
'tpe_point_1' => "Rattachement au syndicat Multipros de l'UL : ne restez plus isolé·e et rejoignez la solidarité de tous les syndicats CGT de Foix et de la Haute-Ariège.",
|
||||||
|
'tpe_point_2' => "Confidentialité absolue : aucune prise de contact ni adhésion n'est portée à la connaissance de votre employeur sans votre accord.",
|
||||||
|
'tpe_point_3' => "Conseillers du Salarié : accompagnement gratuit et défense à vos côtés lors d'un entretien préalable à licenciement ou d'un litige.",
|
||||||
|
'tpe_btn_label' => "Contacter l'UL en toute confidentialité",
|
||||||
|
'tpe_btn_url' => home_url( '/contact/' ),
|
||||||
|
|
||||||
|
// Onglet 3 : Section 6 — Formation Syndicale (CFESES) & Appli Mobile (désactivée par défaut).
|
||||||
|
'cfeses_enabled' => 1,
|
||||||
|
'cfeses_eyebrow' => 'Droit individuel & vie militante',
|
||||||
|
'cfeses_title' => 'Formation Syndicale (CFESES)',
|
||||||
|
'cfeses_text' => "Tout·e salarié·e a droit au Congé de Formation Économique, Sociale, Environnementale et Syndicale : jusqu'à 12 jours par an avec maintien intégral de salaire. Remettez votre demande à l'employeur au moins 30 jours avant le stage.",
|
||||||
|
'cfeses_btn_label' => 'Demander une formation syndicale',
|
||||||
|
'cfeses_btn_url' => home_url( '/contact/' ),
|
||||||
|
|
||||||
|
'app_enabled' => 0,
|
||||||
|
'app_eyebrow' => 'Outil militant 100 % hors-ligne',
|
||||||
|
'app_title' => "L'Application Mobile UL CGT Foix Haute-Ariège",
|
||||||
|
'app_text' => 'Suivez les actualités locales, recevez les alertes mobilisation en temps réel et gardez votre carte de syndiqué virtuelle & vos 13 timbres toujours sur vous (Android / KMP).',
|
||||||
|
'app_btn_label' => "Télécharger l'application (.apk / Store)",
|
||||||
|
'app_download_url' => 'https://cgt-fha.fr/',
|
||||||
|
'app_qr_url' => CGT_FHA_URI . '/assets/img/qr-placeholder.svg',
|
||||||
|
|
||||||
|
// Onglet 3 : Section 7 — Réseau syndical CGT (5 cartes verticales).
|
||||||
|
'network_enabled' => 1,
|
||||||
|
'network_title' => 'RÉSEAU SYNDICAL CGT',
|
||||||
|
|
||||||
|
'network_1_enabled' => 1,
|
||||||
|
'network_1_logo' => CGT_FHA_URI . '/assets/img/logo-cgt-09.jpg',
|
||||||
|
'network_1_label' => 'UD CGT 09',
|
||||||
|
'network_1_desc' => "Union Départementale des syndicats CGT de l'Ariège : coordination départementale des luttes et solidarité interprofessionnelle.",
|
||||||
|
'network_1_btn' => 'Visiter le site ↗',
|
||||||
|
'network_1_url' => 'https://ariege.cgt.fr/',
|
||||||
|
|
||||||
|
'network_2_enabled' => 1,
|
||||||
|
'network_2_logo' => CGT_FHA_URI . '/assets/img/logo-cgt.png',
|
||||||
|
'network_2_label' => 'Confédération CGT',
|
||||||
|
'network_2_desc' => 'Site national de la CGT : actualités confédérales, campagnes interprofessionnelles, analyses et repères revendicatifs.',
|
||||||
|
'network_2_btn' => 'Visiter le site ↗',
|
||||||
|
'network_2_url' => 'https://www.cgt.fr/',
|
||||||
|
|
||||||
|
'network_3_enabled' => 1,
|
||||||
|
'network_3_logo' => CGT_FHA_URI . '/assets/img/logo-nvo.png',
|
||||||
|
'network_3_label' => 'La NVO',
|
||||||
|
'network_3_desc' => "La Nouvelle Vie Ouvrière : le média d'information sociale et syndicale de la CGT au service du monde du travail.",
|
||||||
|
'network_3_btn' => 'Visiter le site ↗',
|
||||||
|
'network_3_url' => 'https://www.nvo.fr/',
|
||||||
|
|
||||||
|
'network_4_enabled' => 1,
|
||||||
|
'network_4_logo' => CGT_FHA_URI . '/assets/img/logo-ihs.jpg',
|
||||||
|
'network_4_label' => 'IHS CGT',
|
||||||
|
'network_4_desc' => "Institut CGT d'Histoire Sociale : mémoire vivante des luttes sociales, archives et recherches sur le mouvement ouvrier.",
|
||||||
|
'network_4_btn' => 'Visiter le site ↗',
|
||||||
|
'network_4_url' => 'https://www.ihs.cgt.fr/',
|
||||||
|
|
||||||
|
'network_5_enabled' => 1,
|
||||||
|
'network_5_logo' => CGT_FHA_URI . '/assets/img/logo-indecosa.png',
|
||||||
|
'network_5_label' => 'INDECOSA-CGT',
|
||||||
|
'network_5_desc' => 'Association de la CGT pour l\'information et la défense des consommateurs salarié·e·s (logement, énergie, consommation).',
|
||||||
|
'network_5_btn' => 'Visiter le site ↗',
|
||||||
|
'network_5_url' => 'https://www.indecosa-cgt.fr/',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne les options fusionnées avec les valeurs par défaut (mise en cache mémoire par requête).
|
||||||
|
*
|
||||||
|
* @param bool $fresh Force la relecture depuis la base de données.
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_options( bool $fresh = false ): array {
|
||||||
|
static $cached = null;
|
||||||
|
if ( null !== $cached && ! $fresh ) {
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
$saved = get_option( CGT_FHA_OPTION_KEY, array() );
|
||||||
|
$saved = is_array( $saved ) ? $saved : array();
|
||||||
|
$merged = wp_parse_args( $saved, cgt_fha_get_defaults() );
|
||||||
|
|
||||||
|
$media_keys = array(
|
||||||
|
'hero_bg_url',
|
||||||
|
'header_logo_url',
|
||||||
|
'footer_logo_url',
|
||||||
|
'app_qr_url',
|
||||||
|
'network_1_logo',
|
||||||
|
'network_2_logo',
|
||||||
|
'network_3_logo',
|
||||||
|
'network_4_logo',
|
||||||
|
'network_5_logo',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Garantit que les visuels critiques vidés par erreur retombent sur le défaut.
|
||||||
|
$defaults = cgt_fha_get_defaults();
|
||||||
|
foreach ( $media_keys as $media_key ) {
|
||||||
|
if ( empty( $merged[ $media_key ] ) ) {
|
||||||
|
$merged[ $media_key ] = $defaults[ $media_key ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cached = $merged;
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migration automatique 1.0.0 -> 1.1.0 pour les sites où le thème est déjà activé.
|
||||||
|
*/
|
||||||
|
add_action( 'init', 'cgt_fha_maybe_upgrade_options', 5 );
|
||||||
|
function cgt_fha_maybe_upgrade_options(): void {
|
||||||
|
if ( CGT_FHA_SCHEMA_VERSION === get_option( 'cgt_fha_schema_version', '1.0.0' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaults = cgt_fha_get_defaults();
|
||||||
|
$saved = get_option( CGT_FHA_OPTION_KEY, array() );
|
||||||
|
|
||||||
|
if ( is_array( $saved ) && ! empty( $saved ) ) {
|
||||||
|
// Bascule du logo de pied de page vers la bannière texte blanc si ancien défaut ou vide.
|
||||||
|
if ( empty( $saved['footer_logo_url'] ) || false !== strpos( (string) $saved['footer_logo_url'], 'logo-ul-light.svg' ) ) {
|
||||||
|
$saved['footer_logo_url'] = $defaults['footer_logo_url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Désactive le bloc Application Mobile par défaut tant que le contenu n'est pas prêt.
|
||||||
|
$saved['app_enabled'] = 0;
|
||||||
|
|
||||||
|
// Remplace les anciennes chaînes par défaut 1.0.0 si elles n'ont pas été personnalisées.
|
||||||
|
$old_v1_defaults = array(
|
||||||
|
'local_news_title' => 'SUR LE TERRAIN EN HAUTE-ARIÈGE',
|
||||||
|
'footer_desc' => "Syndicat interprofessionnel de proximité au service des salarié·e·s, privé·e·s d'emploi et retraité·e·s de Foix et de la Haute-Ariège.",
|
||||||
|
'mission_1_text' => "Construire le syndicat dans votre entreprise, préparer les élections CSE et ne plus rester isolé face à l'employeur.",
|
||||||
|
'mission_2_text' => "Faire respecter vos droits, vos salaires et vos conditions de travail, avec l'appui de nos conseillers du salarié et juristes.",
|
||||||
|
'mission_3_text' => 'Connaître les actualités des luttes en Haute-Ariège et bénéficier de vos droits à la formation syndicale (CFESES).',
|
||||||
|
'tpe_badge' => 'Salariés sans CSE · TPE / PME',
|
||||||
|
'tpe_text' => "Vous travaillez dans une petite entreprise (< 11 salariés), un commerce, l'artisanat ou sur un chantier sans représentant du personnel ? L'Union Locale CGT vous accueille et vous défend.",
|
||||||
|
'tpe_point_1' => "Confidentialité absolue : aucune démarche n'est portée à la connaissance de votre employeur sans votre accord explicite.",
|
||||||
|
'tpe_point_2' => "Syndicat Multipros : adhérez et organisez-vous collectivement même dans une très petite entreprise dépourvue de section syndicale.",
|
||||||
|
'tpe_point_3' => 'Conseillers du Salarié : accompagnement gratuit lors des entretiens préalables à un licenciement ou une rupture.',
|
||||||
|
'network_2_label' => 'Confédération CGT (cgt.fr)',
|
||||||
|
'network_3_label' => 'La NVO (nvo.fr)',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $old_v1_defaults as $key => $old_val ) {
|
||||||
|
if ( isset( $saved[ $key ] ) && $saved[ $key ] === $old_val ) {
|
||||||
|
$saved[ $key ] = $defaults[ $key ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remplace les anciens placeholders SVG du Réseau CGT par les 5 logos officiels (1.2.0).
|
||||||
|
for ( $i = 1; $i <= 5; $i++ ) {
|
||||||
|
$logo_key = 'network_' . $i . '_logo';
|
||||||
|
$cur_logo = (string) ( $saved[ $logo_key ] ?? '' );
|
||||||
|
if ( '' === $cur_logo || ( false !== strpos( $cur_logo, 'network-' ) && false !== strpos( $cur_logo, '.svg' ) ) ) {
|
||||||
|
$saved[ $logo_key ] = $defaults[ $logo_key ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$saved = wp_parse_args( $saved, $defaults );
|
||||||
|
update_option( CGT_FHA_OPTION_KEY, $saved );
|
||||||
|
cgt_fha_get_options( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purge le cache confédéral pour forcer le nouvel extracteur sur la page d'accueil.
|
||||||
|
delete_transient( 'cgt_fha_confederal_feed' );
|
||||||
|
delete_transient( 'cgt_fha_confederal_feed_lock' );
|
||||||
|
delete_option( 'cgt_fha_confederal_feed_backup' );
|
||||||
|
|
||||||
|
update_option( 'cgt_fha_schema_version', CGT_FHA_SCHEMA_VERSION, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si le bandeau d'alerte mobilisation doit être affiché.
|
||||||
|
*/
|
||||||
|
function cgt_fha_is_banner_active(): bool {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
if ( empty( $opts['banner_enabled'] ) || empty( $opts['banner_text'] ) || empty( $opts['banner_expires'] ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tz = wp_timezone();
|
||||||
|
$expire_dt = DateTimeImmutable::createFromFormat( 'Y-m-d\TH:i', (string) $opts['banner_expires'], $tz );
|
||||||
|
if ( ! $expire_dt ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$now_ts = (int) current_time( 'timestamp' );
|
||||||
|
return $now_ts < $expire_dt->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enregistrement du réglage et de la page d'administration.
|
||||||
|
*/
|
||||||
|
add_action( 'admin_menu', 'cgt_fha_register_admin_page' );
|
||||||
|
function cgt_fha_register_admin_page(): void {
|
||||||
|
add_theme_page(
|
||||||
|
'Réglages UL CGT Foix Haute-Ariège',
|
||||||
|
'Réglages UL CGT',
|
||||||
|
'manage_options',
|
||||||
|
'cgt-fha-settings',
|
||||||
|
'cgt_fha_render_admin_page'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action( 'admin_init', 'cgt_fha_register_settings' );
|
||||||
|
function cgt_fha_register_settings(): void {
|
||||||
|
register_setting(
|
||||||
|
'cgt_fha_settings_group',
|
||||||
|
CGT_FHA_OPTION_KEY,
|
||||||
|
array(
|
||||||
|
'type' => 'array',
|
||||||
|
'sanitize_callback' => 'cgt_fha_sanitize_options',
|
||||||
|
'default' => cgt_fha_get_defaults(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pré-remplit l'option en base lors de l'activation du thème (autoload = true, taille ~5 Ko).
|
||||||
|
*/
|
||||||
|
add_action( 'after_switch_theme', 'cgt_fha_seed_default_options' );
|
||||||
|
function cgt_fha_seed_default_options(): void {
|
||||||
|
if ( false === get_option( CGT_FHA_OPTION_KEY, false ) ) {
|
||||||
|
add_option( CGT_FHA_OPTION_KEY, cgt_fha_get_defaults(), '', 'yes' );
|
||||||
|
}
|
||||||
|
update_option( 'cgt_fha_schema_version', CGT_FHA_SCHEMA_VERSION, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoyage et validation de toutes les options soumises dans l'admin.
|
||||||
|
*
|
||||||
|
* @param mixed $input Données brutes du formulaire.
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
function cgt_fha_sanitize_options( $input ): array {
|
||||||
|
$input = is_array( $input ) ? $input : array();
|
||||||
|
$defaults = cgt_fha_get_defaults();
|
||||||
|
$existing = cgt_fha_get_options( true );
|
||||||
|
$clean = array();
|
||||||
|
|
||||||
|
$text_fields = array(
|
||||||
|
'phone',
|
||||||
|
'address',
|
||||||
|
'footer_call',
|
||||||
|
'banner_text',
|
||||||
|
'hero_title_line1',
|
||||||
|
'hero_title_line2',
|
||||||
|
'hero_btn1_label',
|
||||||
|
'hero_btn2_label',
|
||||||
|
'missions_title',
|
||||||
|
'mission_1_title',
|
||||||
|
'mission_2_title',
|
||||||
|
'mission_3_title',
|
||||||
|
'local_news_title',
|
||||||
|
'local_news_more',
|
||||||
|
'confederal_title',
|
||||||
|
'tpe_badge',
|
||||||
|
'tpe_title',
|
||||||
|
'tpe_btn_label',
|
||||||
|
'cfeses_eyebrow',
|
||||||
|
'cfeses_title',
|
||||||
|
'cfeses_btn_label',
|
||||||
|
'app_eyebrow',
|
||||||
|
'app_title',
|
||||||
|
'app_btn_label',
|
||||||
|
'network_title',
|
||||||
|
'network_1_label',
|
||||||
|
'network_1_btn',
|
||||||
|
'network_2_label',
|
||||||
|
'network_2_btn',
|
||||||
|
'network_3_label',
|
||||||
|
'network_3_btn',
|
||||||
|
'network_4_label',
|
||||||
|
'network_4_btn',
|
||||||
|
'network_5_label',
|
||||||
|
'network_5_btn',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $text_fields as $field ) {
|
||||||
|
$val = isset( $input[ $field ] ) ? sanitize_text_field( wp_unslash( (string) $input[ $field ] ) ) : ( $existing[ $field ] ?? $defaults[ $field ] );
|
||||||
|
$clean[ $field ] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
$textarea_fields = array(
|
||||||
|
'hours',
|
||||||
|
'footer_desc',
|
||||||
|
'hero_quote',
|
||||||
|
'missions_subtitle',
|
||||||
|
'mission_1_text',
|
||||||
|
'mission_2_text',
|
||||||
|
'mission_3_text',
|
||||||
|
'tpe_text',
|
||||||
|
'tpe_point_1',
|
||||||
|
'tpe_point_2',
|
||||||
|
'tpe_point_3',
|
||||||
|
'cfeses_text',
|
||||||
|
'app_text',
|
||||||
|
'network_1_desc',
|
||||||
|
'network_2_desc',
|
||||||
|
'network_3_desc',
|
||||||
|
'network_4_desc',
|
||||||
|
'network_5_desc',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $textarea_fields as $field ) {
|
||||||
|
$val = isset( $input[ $field ] ) ? sanitize_textarea_field( wp_unslash( (string) $input[ $field ] ) ) : ( $existing[ $field ] ?? $defaults[ $field ] );
|
||||||
|
$clean[ $field ] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clean['email'] = isset( $input['email'] )
|
||||||
|
? sanitize_email( wp_unslash( (string) $input['email'] ) )
|
||||||
|
: $defaults['email'];
|
||||||
|
|
||||||
|
$url_fields = array(
|
||||||
|
'facebook_url',
|
||||||
|
'instagram_url',
|
||||||
|
'youtube_url',
|
||||||
|
'header_logo_url',
|
||||||
|
'footer_logo_url',
|
||||||
|
'news_url',
|
||||||
|
'calendar_url',
|
||||||
|
'contact_url',
|
||||||
|
'join_url',
|
||||||
|
'legal_url',
|
||||||
|
'banner_url',
|
||||||
|
'hero_bg_url',
|
||||||
|
'hero_btn1_url',
|
||||||
|
'hero_btn2_url',
|
||||||
|
'tpe_btn_url',
|
||||||
|
'cfeses_btn_url',
|
||||||
|
'app_download_url',
|
||||||
|
'app_qr_url',
|
||||||
|
'network_1_logo',
|
||||||
|
'network_1_url',
|
||||||
|
'network_2_logo',
|
||||||
|
'network_2_url',
|
||||||
|
'network_3_logo',
|
||||||
|
'network_3_url',
|
||||||
|
'network_4_logo',
|
||||||
|
'network_4_url',
|
||||||
|
'network_5_logo',
|
||||||
|
'network_5_url',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ( $url_fields as $field ) {
|
||||||
|
$raw = isset( $input[ $field ] ) ? trim( (string) wp_unslash( $input[ $field ] ) ) : ( $existing[ $field ] ?? $defaults[ $field ] );
|
||||||
|
$clean[ $field ] = '' === $raw ? '' : esc_url_raw( $raw );
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkbox_fields = array(
|
||||||
|
'banner_enabled',
|
||||||
|
'tpe_enabled',
|
||||||
|
'cfeses_enabled',
|
||||||
|
'app_enabled',
|
||||||
|
'network_enabled',
|
||||||
|
'network_1_enabled',
|
||||||
|
'network_2_enabled',
|
||||||
|
'network_3_enabled',
|
||||||
|
'network_4_enabled',
|
||||||
|
'network_5_enabled',
|
||||||
|
);
|
||||||
|
foreach ( $checkbox_fields as $field ) {
|
||||||
|
$clean[ $field ] = ! empty( $input[ $field ] ) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation datetime-local (YYYY-MM-DDTHH:MM).
|
||||||
|
$raw_expires = isset( $input['banner_expires'] ) ? sanitize_text_field( wp_unslash( (string) $input['banner_expires'] ) ) : $defaults['banner_expires'];
|
||||||
|
$clean['banner_expires'] = preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/', $raw_expires ) ? $raw_expires : $defaults['banner_expires'];
|
||||||
|
|
||||||
|
// Validation des icônes de mission.
|
||||||
|
$valid_icons = array_keys( cgt_fha_get_mission_icon_choices() );
|
||||||
|
foreach ( array( 'mission_1_icon', 'mission_2_icon', 'mission_3_icon' ) as $icon_key ) {
|
||||||
|
$chosen = isset( $input[ $icon_key ] ) ? sanitize_key( (string) $input[ $icon_key ] ) : $defaults[ $icon_key ];
|
||||||
|
$clean[ $icon_key ] = in_array( $chosen, $valid_icons, true ) ? $chosen : $defaults[ $icon_key ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liste des icônes disponibles dans le sélecteur admin des 3 cartes de mission.
|
||||||
|
*
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
function cgt_fha_get_mission_icon_choices(): array {
|
||||||
|
return array(
|
||||||
|
'fist' => 'Poing levé / Collectif',
|
||||||
|
'shield' => 'Bouclier / Défense des droits',
|
||||||
|
'chat' => 'Bulles d\'échange / Information & Formation',
|
||||||
|
'megaphone' => 'Mégaphone / Mobilisation',
|
||||||
|
'scale' => 'Balance / Prud\'hommes & Juridique',
|
||||||
|
'users' => 'Collectif salarié·e·s',
|
||||||
|
'book' => 'Livre / Formation CFESES',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper d'affichage d'un champ texte/URL/textarea dans l'admin.
|
||||||
|
*/
|
||||||
|
function cgt_fha_admin_field_row( string $key, string $label, string $type = 'text', string $desc = '' ): void {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$val = $opts[ $key ] ?? '';
|
||||||
|
$id = 'cgt_fha_' . $key;
|
||||||
|
$name = CGT_FHA_OPTION_KEY . '[' . $key . ']';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label></th>
|
||||||
|
<td>
|
||||||
|
<?php if ( 'textarea' === $type ) : ?>
|
||||||
|
<textarea id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( $name ); ?>" rows="3" class="large-text"><?php echo esc_textarea( (string) $val ); ?></textarea>
|
||||||
|
<?php elseif ( 'checkbox' === $type ) : ?>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( $name ); ?>" value="1" <?php checked( ! empty( $val ) ); ?> />
|
||||||
|
<span><?php echo esc_html( $desc ); ?></span>
|
||||||
|
</label>
|
||||||
|
<?php else : ?>
|
||||||
|
<input type="<?php echo esc_attr( $type ); ?>" id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( (string) $val ); ?>" class="<?php echo 'datetime-local' === $type ? 'regular-text' : 'large-text'; ?>" />
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ( '' !== $desc && 'checkbox' !== $type ) : ?>
|
||||||
|
<p class="description"><?php echo esc_html( $desc ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper d'affichage d'un sélecteur d'image via la Médiathèque WordPress.
|
||||||
|
*/
|
||||||
|
function cgt_fha_admin_media_row( string $key, string $label, string $default_url, string $desc = '', bool $dark_preview = false ): void {
|
||||||
|
$opts = cgt_fha_get_options();
|
||||||
|
$val = ! empty( $opts[ $key ] ) ? (string) $opts[ $key ] : $default_url;
|
||||||
|
$id = 'cgt_fha_' . $key;
|
||||||
|
$name = CGT_FHA_OPTION_KEY . '[' . $key . ']';
|
||||||
|
$preview_bg = $dark_preview ? '#1c1e21' : '#f8fafc';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label></th>
|
||||||
|
<td>
|
||||||
|
<div style="display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">
|
||||||
|
<input type="url" id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_url( $val ); ?>" class="regular-text" />
|
||||||
|
<button type="button" class="button button-secondary" data-cgt-media-select="<?php echo esc_attr( $id ); ?>">Choisir dans la Médiathèque</button>
|
||||||
|
<button type="button" class="button" data-cgt-media-clear="<?php echo esc_attr( $id ); ?>" data-cgt-default-url="<?php echo esc_url( $default_url ); ?>">Rétablir par défaut</button>
|
||||||
|
</div>
|
||||||
|
<img id="<?php echo esc_attr( $id . '_preview' ); ?>" src="<?php echo esc_url( $val ); ?>" alt="" style="max-width:260px; max-height:110px; border:1px solid #cbd5e1; border-radius:6px; background:<?php echo esc_attr( $preview_bg ); ?>; padding:6px;" />
|
||||||
|
<?php if ( '' !== $desc ) : ?>
|
||||||
|
<p class="description"><?php echo esc_html( $desc ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rendu de la page d'administration Apparence > Réglages UL CGT.
|
||||||
|
*/
|
||||||
|
function cgt_fha_render_admin_page(): void {
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaults = cgt_fha_get_defaults();
|
||||||
|
$opts = cgt_fha_get_options( true );
|
||||||
|
$active_tab = isset( $_GET['tab'] ) ? sanitize_key( (string) $_GET['tab'] ) : 'identity';
|
||||||
|
if ( ! in_array( $active_tab, array( 'identity', 'banner', 'homepage', 'confederal' ), true ) ) {
|
||||||
|
$active_tab = 'identity';
|
||||||
|
}
|
||||||
|
|
||||||
|
$feed_status = class_exists( 'CGT_FHA_Confederal_Feed' ) ? CGT_FHA_Confederal_Feed::get_cache_status() : array();
|
||||||
|
?>
|
||||||
|
<div class="wrap cgt-admin-wrap">
|
||||||
|
<h1 style="display:flex; align-items:center; gap:10px;">
|
||||||
|
<span style="display:inline-block; width:14px; height:14px; background:#d20012; border-radius:3px;"></span>
|
||||||
|
Réglages de l'Union Locale CGT Foix Haute-Ariège
|
||||||
|
</h1>
|
||||||
|
<p>Tous les textes, images, icônes, coordonnées et liens du thème sont modifiables ici sans toucher au code.</p>
|
||||||
|
|
||||||
|
<?php if ( isset( $_GET['cgt_feed_refreshed'] ) ) : ?>
|
||||||
|
<div class="notice notice-success is-dismissible">
|
||||||
|
<p><strong>Actualités confédérales (`cgt.fr`) synchronisées avec succès.</strong></p>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php settings_errors(); ?>
|
||||||
|
|
||||||
|
<nav class="nav-tab-wrapper" role="tablist" aria-label="Onglets de réglages UL CGT">
|
||||||
|
<a href="#identity" class="nav-tab <?php echo 'identity' === $active_tab ? 'nav-tab-active' : ''; ?>" data-cgt-tab="identity" role="tab" aria-selected="<?php echo 'identity' === $active_tab ? 'true' : 'false'; ?>">1. Identité & Coordonnées</a>
|
||||||
|
<a href="#banner" class="nav-tab <?php echo 'banner' === $active_tab ? 'nav-tab-active' : ''; ?>" data-cgt-tab="banner" role="tab" aria-selected="<?php echo 'banner' === $active_tab ? 'true' : 'false'; ?>">2. Bandeau Mobilisation</a>
|
||||||
|
<a href="#homepage" class="nav-tab <?php echo 'homepage' === $active_tab ? 'nav-tab-active' : ''; ?>" data-cgt-tab="homepage" role="tab" aria-selected="<?php echo 'homepage' === $active_tab ? 'true' : 'false'; ?>">3. Page d'accueil & Blocs</a>
|
||||||
|
<a href="#confederal" class="nav-tab <?php echo 'confederal' === $active_tab ? 'nav-tab-active' : ''; ?>" data-cgt-tab="confederal" role="tab" aria-selected="<?php echo 'confederal' === $active_tab ? 'true' : 'false'; ?>">4. Flux Confédéral (cgt.fr)</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<form method="post" action="options.php" style="margin-top:20px;">
|
||||||
|
<?php settings_fields( 'cgt_fha_settings_group' ); ?>
|
||||||
|
<input type="hidden" name="cgt_fha_active_tab" value="<?php echo esc_attr( $active_tab ); ?>" />
|
||||||
|
|
||||||
|
<!-- ONGLET 1 : IDENTITÉ & COORDONNÉES -->
|
||||||
|
<div data-cgt-panel="identity" <?php echo 'identity' !== $active_tab ? 'hidden' : ''; ?>>
|
||||||
|
<h2>Coordonnées & Identité visuelle</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_media_row( 'header_logo_url', 'Logo En-tête', $defaults['header_logo_url'], 'Par défaut : bannière officielle Union Locale CGT Foix Haute-Ariège (assets/img/banniere-ul-noir.png).' );
|
||||||
|
cgt_fha_admin_media_row( 'footer_logo_url', 'Logo Pied de page (version blanche)', $defaults['footer_logo_url'], 'Affiché sur le fond sombre du pied de page (assets/img/banniere-ul-blanc.png par défaut).', true );
|
||||||
|
cgt_fha_admin_field_row( 'phone', 'Téléphone', 'text', 'Affiché dans la barre supérieure et le pied de page.' );
|
||||||
|
cgt_fha_admin_field_row( 'email', 'Adresse e-mail', 'email' );
|
||||||
|
cgt_fha_admin_field_row( 'address', 'Adresse des locaux', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'hours', 'Horaires des permanences', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'facebook_url', 'URL Page Facebook', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'instagram_url', 'URL Instagram (optionnel)', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'youtube_url', 'URL YouTube (optionnel)', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'footer_desc', 'Présentation pied de page', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'footer_call', 'Appel militant pied de page', 'text' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>Pages clés de l'Union Locale</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'news_url', 'URL page Actualités', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'calendar_url', 'URL page Calendrier', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'contact_url', "URL page Besoin d'aide / Contact", 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'join_url', 'URL page Syndiquez-vous', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'legal_url', 'URL Mentions légales & Confidentialité', 'url' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
<?php submit_button( 'Enregistrer les réglages' ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ONGLET 2 : BANDEAU MOBILISATION -->
|
||||||
|
<div data-cgt-panel="banner" <?php echo 'banner' !== $active_tab ? 'hidden' : ''; ?>>
|
||||||
|
<h2>Bandeau d'Alerte Mobilisation Auto-Expirant</h2>
|
||||||
|
<p class="description">
|
||||||
|
Le bandeau rouge CGT s'affiche uniquement si la case <strong>Activer le bandeau</strong> est cochée <strong>ET</strong> que l'heure actuelle du site
|
||||||
|
(<code><?php echo esc_html( current_time( 'd/m/Y H:i' ) ); ?></code>) est antérieure à la date d'expiration.
|
||||||
|
</p>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'banner_enabled', 'Activer le bandeau', 'checkbox', 'Afficher le bandeau rouge de mobilisation sous la barre supérieure.' );
|
||||||
|
cgt_fha_admin_field_row( 'banner_text', 'Mot d\'ordre & lieu', 'text', 'Exemple : MOBILISATION : Grève et manifestation à Foix - Allées de Villote' );
|
||||||
|
cgt_fha_admin_field_row( 'banner_url', 'Lien URL au clic (optionnel)', 'url', 'Laissez vide si le bandeau ne doit pas être cliquable.' );
|
||||||
|
cgt_fha_admin_field_row( 'banner_expires', 'Date et heure d\'expiration automatique', 'datetime-local', 'Passé cet horaire, le bandeau disparaît automatiquement.' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
<?php submit_button( 'Enregistrer les réglages' ); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ONGLET 3 : PAGE D'ACCUEIL -->
|
||||||
|
<div data-cgt-panel="homepage" <?php echo 'homepage' !== $active_tab ? 'hidden' : ''; ?>>
|
||||||
|
<h2>Section 1 — Bannière Hero Plein Écran</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_media_row( 'hero_bg_url', 'Image panoramique de fond', $defaults['hero_bg_url'], 'Image sombre de montagne/Ariège recommandée (1600×720 px).' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_title_line1', 'Titre H1 — Ligne 1', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_title_line2', 'Titre H1 — Ligne 2', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_quote', 'Citation sous le titre', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_btn1_label', 'Bouton gauche — Libellé', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_btn1_url', 'Bouton gauche — Lien URL', 'url' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_btn2_label', 'Bouton droit — Libellé', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'hero_btn2_url', 'Bouton droit — Lien URL', 'url' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Section 2 — « À QUOI NOUS SERVONS ? » (3 Cartes)</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'missions_title', 'Titre de la section', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'missions_subtitle', 'Chapeau de présentation (Union des syndicats & Multipros)', 'textarea' );
|
||||||
|
$icon_choices = cgt_fha_get_mission_icon_choices();
|
||||||
|
for ( $i = 1; $i <= 3; $i++ ) :
|
||||||
|
$icon_key = 'mission_' . $i . '_icon';
|
||||||
|
$title_key = 'mission_' . $i . '_title';
|
||||||
|
$text_key = 'mission_' . $i . '_text';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="<?php echo esc_attr( 'cgt_fha_' . $icon_key ); ?>">Carte <?php echo (int) $i; ?> — Icône SVG</label></th>
|
||||||
|
<td>
|
||||||
|
<select id="<?php echo esc_attr( 'cgt_fha_' . $icon_key ); ?>" name="<?php echo esc_attr( CGT_FHA_OPTION_KEY . '[' . $icon_key . ']' ); ?>">
|
||||||
|
<?php foreach ( $icon_choices as $slug => $label ) : ?>
|
||||||
|
<option value="<?php echo esc_attr( $slug ); ?>" <?php selected( $opts[ $icon_key ], $slug ); ?>><?php echo esc_html( $label ); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( $title_key, 'Carte ' . $i . ' — Titre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( $text_key, 'Carte ' . $i . ' — Description', 'textarea' );
|
||||||
|
endfor;
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Sections 3 & 4 — Titres Actualités</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'local_news_title', 'Titre Actualités locales', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'local_news_more', 'Libellé lien « Voir toutes... »', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'confederal_title', 'Titre Actualité confédérale', 'text' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Section 5 — Salariés isolés & TPE (Syndicat Multipros)</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'tpe_enabled', 'Afficher ce bloc', 'checkbox', 'Afficher la section Salariés isolés & TPE sur la page d\'accueil.' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_badge', 'Surtitre / Badge', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_title', 'Titre du bloc', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_text', 'Paragraphe explicatif', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_point_1', 'Point clé 1 (Rattachement Multipros)', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_point_2', 'Point clé 2 (Confidentialité)', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_point_3', 'Point clé 3 (Conseillers du Salarié)', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_btn_label', 'Libellé du bouton', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'tpe_btn_url', 'Lien URL du bouton', 'url' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Section 6 — Formation Syndicale (CFESES) & Application Mobile</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_enabled', 'Afficher le bloc CFESES', 'checkbox', 'Afficher la colonne Formation Syndicale (CFESES).' );
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_eyebrow', 'CFESES — Surtitre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_title', 'CFESES — Titre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_text', 'CFESES — Texte explicatif', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_btn_label', 'CFESES — Libellé bouton', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'cfeses_btn_url', 'CFESES — Lien URL', 'url' );
|
||||||
|
|
||||||
|
cgt_fha_admin_field_row(
|
||||||
|
'app_enabled',
|
||||||
|
'Afficher le bloc Appli Mobile',
|
||||||
|
'checkbox',
|
||||||
|
'Désactivé par défaut tant que le contenu / fichier de téléchargement n\'est pas prêt. Cochez pour afficher ce bloc sur la page d\'accueil.'
|
||||||
|
);
|
||||||
|
cgt_fha_admin_field_row( 'app_eyebrow', 'Appli — Surtitre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'app_title', 'Appli — Titre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'app_text', 'Appli — Présentation', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'app_btn_label', 'Appli — Libellé bouton téléchargement', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'app_download_url', 'Appli — Lien direct (.apk / Play Store)', 'url' );
|
||||||
|
cgt_fha_admin_media_row( 'app_qr_url', 'Appli — Image QR Code', $defaults['app_qr_url'], 'Téléversez le QR Code pointant vers votre fichier .apk ou fiche Store.' );
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h2>Section 7 — Réseau Syndical CGT (Cartes avec logo, description et bouton)</h2>
|
||||||
|
<table class="form-table" role="presentation">
|
||||||
|
<?php
|
||||||
|
cgt_fha_admin_field_row( 'network_enabled', 'Afficher la section Réseau CGT', 'checkbox', 'Afficher la grille de cartes du réseau syndical CGT en bas de page d\'accueil.' );
|
||||||
|
cgt_fha_admin_field_row( 'network_title', 'Titre de la section', 'text' );
|
||||||
|
for ( $i = 1; $i <= 5; $i++ ) {
|
||||||
|
cgt_fha_admin_field_row( 'network_' . $i . '_enabled', 'Carte ' . $i . ' — Afficher', 'checkbox', 'Afficher cette carte dans le Réseau Syndical CGT.' );
|
||||||
|
cgt_fha_admin_media_row( 'network_' . $i . '_logo', 'Carte ' . $i . ' — Logo', $defaults[ 'network_' . $i . '_logo' ] );
|
||||||
|
cgt_fha_admin_field_row( 'network_' . $i . '_label', 'Carte ' . $i . ' — Titre', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'network_' . $i . '_desc', 'Carte ' . $i . ' — Description courte', 'textarea' );
|
||||||
|
cgt_fha_admin_field_row( 'network_' . $i . '_btn', 'Carte ' . $i . ' — Libellé bouton', 'text' );
|
||||||
|
cgt_fha_admin_field_row( 'network_' . $i . '_url', 'Carte ' . $i . ' — URL du site', 'url' );
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
<?php submit_button( 'Enregistrer les réglages' ); ?>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- ONGLET 4 : FLUX CONFÉDÉRAL (hors formulaire options.php pour le bouton POST dédié) -->
|
||||||
|
<div data-cgt-panel="confederal" <?php echo 'confederal' !== $active_tab ? 'hidden' : ''; ?> style="margin-top:20px;">
|
||||||
|
<h2>État du flux automatique « Actualité Confédérale » (`cgt.fr`)</h2>
|
||||||
|
<div class="card" style="max-width:760px; padding:16px 20px;">
|
||||||
|
<p>
|
||||||
|
<strong>Statut du cache :</strong>
|
||||||
|
<?php echo ! empty( $feed_status['has_transient'] ) ? '<span style="color:#0a7d2b;font-weight:700;">Actif (Transient valide)</span>' : '<span style="color:#b45309;font-weight:700;">Expiré ou en attente de synchronisation</span>'; ?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Dernière synchronisation :</strong>
|
||||||
|
<?php echo ! empty( $feed_status['fetched_at'] ) ? esc_html( wp_date( 'd/m/Y à H:i:s', (int) $feed_status['fetched_at'] ) ) : 'Pas encore effectuée'; ?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Source utilisée :</strong>
|
||||||
|
<?php echo esc_html( (string) ( $feed_status['source'] ?? 'Non définie' ) ); ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<?php if ( ! empty( $feed_status['featured']['title'] ) ) : ?>
|
||||||
|
<div style="margin:14px 0; padding:12px 14px; background:#f8fafc; border:1px solid #cbd5e1; border-radius:8px;">
|
||||||
|
<p style="margin:0 0 4px;"><strong>Article « À la une » en cache :</strong></p>
|
||||||
|
<p style="margin:0 0 4px; font-size:15px;"><strong><?php echo esc_html( $feed_status['featured']['title'] ); ?></strong></p>
|
||||||
|
<p style="margin:0; color:#4a5568;"><?php echo esc_html( $feed_status['featured']['summary'] ?? '' ); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
|
||||||
|
<input type="hidden" name="action" value="cgt_fha_refresh_feed" />
|
||||||
|
<?php wp_nonce_field( 'cgt_fha_refresh_feed_action', 'cgt_fha_refresh_feed_nonce' ); ?>
|
||||||
|
<button type="submit" class="button button-primary">Actualiser les actus confédérales maintenant</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
65
index.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit de secours général (recherche et boucle générique WordPress).
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
|
||||||
|
$heading = is_search()
|
||||||
|
? sprintf( 'Résultats de recherche pour « %s »', get_search_query() )
|
||||||
|
: ( get_bloginfo( 'name' ) ?: 'Union Locale CGT Foix Haute-Ariège' );
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section class="cgt-page-hero">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<nav class="cgt-breadcrumb" aria-label="<?php esc_attr_e( 'Fil d\'Ariane', 'cgt-fha' ); ?>">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Accueil', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<span><?php echo esc_html( $heading ); ?></span>
|
||||||
|
</nav>
|
||||||
|
<h1 class="cgt-page-hero__title"><?php echo esc_html( $heading ); ?></h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="cgt-section cgt-section--white">
|
||||||
|
<div class="cgt-container">
|
||||||
|
<?php if ( have_posts() ) : ?>
|
||||||
|
<div class="cgt-news-grid">
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
cgt_fha_render_local_post_card();
|
||||||
|
endwhile;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cgt-pagination">
|
||||||
|
<?php
|
||||||
|
the_posts_pagination(
|
||||||
|
array(
|
||||||
|
'mid_size' => 2,
|
||||||
|
'prev_text' => '← Précédent',
|
||||||
|
'next_text' => 'Suivant →',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php esc_html_e( 'Aucun résultat ne correspond à votre recherche.', 'cgt-fha' ); ?></p>
|
||||||
|
<form role="search" method="get" class="cgt-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>" style="margin-left:0;">
|
||||||
|
<label for="cgt-index-search" class="screen-reader-text"><?php esc_html_e( 'Rechercher sur le site', 'cgt-fha' ); ?></label>
|
||||||
|
<input type="search" id="cgt-index-search" name="s" value="<?php echo esc_attr( get_search_query() ); ?>" placeholder="<?php esc_attr_e( 'Nouvelle recherche…', 'cgt-fha' ); ?>" />
|
||||||
|
<button type="submit" class="cgt-btn cgt-btn--primary"><?php esc_html_e( 'Rechercher', 'cgt-fha' ); ?></button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
61
page.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit de page standard (page.php) : Contact, Calendrier, Syndiquez-vous, Mentions légales...
|
||||||
|
* Compatible avec les shortcodes et hooks des extensions sœurs cgt-wp-calendar et cgt-wp-forms.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
?>
|
||||||
|
<section class="cgt-page-hero">
|
||||||
|
<div class="cgt-container--narrow">
|
||||||
|
<nav class="cgt-breadcrumb" aria-label="<?php esc_attr_e( 'Fil d\'Ariane', 'cgt-fha' ); ?>">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Accueil', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<span><?php the_title(); ?></span>
|
||||||
|
</nav>
|
||||||
|
<h1 class="cgt-page-hero__title"><?php the_title(); ?></h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<article id="post-<?php the_ID(); ?>" <?php post_class( 'cgt-article-wrap' ); ?>>
|
||||||
|
<div class="cgt-container--narrow">
|
||||||
|
<?php if ( has_post_thumbnail() ) : ?>
|
||||||
|
<div class="cgt-article__featured">
|
||||||
|
<?php the_post_thumbnail( 'cgt-featured', array( 'fetchpriority' => 'high' ) ); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="entry-content">
|
||||||
|
<?php
|
||||||
|
the_content();
|
||||||
|
|
||||||
|
wp_link_pages(
|
||||||
|
array(
|
||||||
|
'before' => '<div class="page-links">' . esc_html__( 'Pages :', 'cgt-fha' ),
|
||||||
|
'after' => '</div>',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Emplacement propre pour accueillir cgt-wp-calendar ou cgt-wp-forms selon le slug de page.
|
||||||
|
do_action( 'cgt_fha_after_page_content', get_post_field( 'post_name', get_the_ID() ) );
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
131
single.php
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Gabarit d'article local (single.php) : catégorie, date, contenu, partage social sans traceur et navigation.
|
||||||
|
*
|
||||||
|
* @package CGT_FHA
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_header();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
while ( have_posts() ) :
|
||||||
|
the_post();
|
||||||
|
$cats = get_the_category();
|
||||||
|
$cat_obj = ! empty( $cats ) ? $cats[0] : null;
|
||||||
|
$share_url = get_permalink();
|
||||||
|
$share_txt = get_the_title();
|
||||||
|
?>
|
||||||
|
<section class="cgt-page-hero">
|
||||||
|
<div class="cgt-container--narrow">
|
||||||
|
<nav class="cgt-breadcrumb" aria-label="<?php esc_attr_e( 'Fil d\'Ariane', 'cgt-fha' ); ?>">
|
||||||
|
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Accueil', 'cgt-fha' ); ?></a>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<a href="<?php echo esc_url( cgt_fha_get_local_news_archive_url() ); ?>"><?php esc_html_e( 'Actualités', 'cgt-fha' ); ?></a>
|
||||||
|
<?php if ( $cat_obj ) : ?>
|
||||||
|
<span aria-hidden="true">/</span>
|
||||||
|
<a href="<?php echo esc_url( get_category_link( $cat_obj->term_id ) ); ?>"><?php echo esc_html( $cat_obj->name ); ?></a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</nav>
|
||||||
|
<h1 class="cgt-page-hero__title"><?php the_title(); ?></h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<article id="post-<?php the_ID(); ?>" <?php post_class( 'cgt-article-wrap' ); ?>>
|
||||||
|
<div class="cgt-container--narrow">
|
||||||
|
<header class="cgt-article__header">
|
||||||
|
<div class="cgt-article__meta">
|
||||||
|
<?php if ( $cat_obj ) : ?>
|
||||||
|
<a href="<?php echo esc_url( get_category_link( $cat_obj->term_id ) ); ?>" class="cgt-pill-cat">
|
||||||
|
<?php echo esc_html( $cat_obj->name ); ?>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<time datetime="<?php echo esc_attr( get_the_date( 'c' ) ); ?>">
|
||||||
|
<?php echo esc_html( get_the_date( 'j F Y' ) ); ?>
|
||||||
|
</time>
|
||||||
|
<span aria-hidden="true">•</span>
|
||||||
|
<span><?php esc_html_e( 'Union Locale CGT Foix Haute-Ariège', 'cgt-fha' ); ?></span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<?php if ( has_post_thumbnail() ) : ?>
|
||||||
|
<div class="cgt-article__featured">
|
||||||
|
<?php the_post_thumbnail( 'cgt-featured', array( 'fetchpriority' => 'high' ) ); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="entry-content">
|
||||||
|
<?php
|
||||||
|
the_content();
|
||||||
|
|
||||||
|
wp_link_pages(
|
||||||
|
array(
|
||||||
|
'before' => '<div class="page-links">' . esc_html__( 'Pages :', 'cgt-fha' ),
|
||||||
|
'after' => '</div>',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Partage social souverain (liens directs sans script traceur) -->
|
||||||
|
<aside class="cgt-share-box" aria-label="<?php esc_attr_e( 'Partager cet article', 'cgt-fha' ); ?>">
|
||||||
|
<span class="cgt-share-box__label"><?php esc_html_e( 'Partager cette information :', 'cgt-fha' ); ?></span>
|
||||||
|
<div class="cgt-share-box__actions">
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url( 'https://www.facebook.com/sharer/sharer.php?u=' . rawurlencode( $share_url ) ); ?>"
|
||||||
|
class="cgt-share-btn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>Facebook</a>
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url( 'https://wa.me/?text=' . rawurlencode( $share_txt . ' — ' . $share_url ) ); ?>"
|
||||||
|
class="cgt-share-btn"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>WhatsApp</a>
|
||||||
|
<a
|
||||||
|
href="<?php echo esc_url( 'mailto:?subject=' . rawurlencode( $share_txt ) . '&body=' . rawurlencode( $share_url ) ); ?>"
|
||||||
|
class="cgt-share-btn"
|
||||||
|
>E-mail</a>
|
||||||
|
<button type="button" class="cgt-share-btn" data-cgt-copy-url="<?php echo esc_url( $share_url ); ?>">
|
||||||
|
<?php esc_html_e( 'Copier le lien', 'cgt-fha' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$prev_post = get_previous_post();
|
||||||
|
$next_post = get_next_post();
|
||||||
|
if ( $prev_post || $next_post ) :
|
||||||
|
?>
|
||||||
|
<nav class="cgt-post-nav" aria-label="<?php esc_attr_e( 'Navigation entre articles', 'cgt-fha' ); ?>">
|
||||||
|
<div>
|
||||||
|
<?php if ( $prev_post ) : ?>
|
||||||
|
<a href="<?php echo esc_url( get_permalink( $prev_post ) ); ?>" class="cgt-post-nav__item">
|
||||||
|
<span class="cgt-post-nav__dir">← <?php esc_html_e( 'Article précédent', 'cgt-fha' ); ?></span>
|
||||||
|
<strong><?php echo esc_html( get_the_title( $prev_post ) ); ?></strong>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<?php if ( $next_post ) : ?>
|
||||||
|
<a href="<?php echo esc_url( get_permalink( $next_post ) ); ?>" class="cgt-post-nav__item" style="text-align:right;">
|
||||||
|
<span class="cgt-post-nav__dir"><?php esc_html_e( 'Article suivant', 'cgt-fha' ); ?> →</span>
|
||||||
|
<strong><?php echo esc_html( get_the_title( $next_post ) ); ?></strong>
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php do_action( 'cgt_fha_after_single_post', get_the_ID() ); ?>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endwhile; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
get_footer();
|
||||||
158
theme.json
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://schemas.wp.org/trunk/theme.json",
|
||||||
|
"version": 3,
|
||||||
|
"settings": {
|
||||||
|
"appearanceTools": false,
|
||||||
|
"color": {
|
||||||
|
"custom": false,
|
||||||
|
"customGradient": false,
|
||||||
|
"defaultPalette": false,
|
||||||
|
"defaultGradients": false,
|
||||||
|
"palette": [
|
||||||
|
{
|
||||||
|
"name": "Rouge CGT",
|
||||||
|
"slug": "cgt-red",
|
||||||
|
"color": "#d20012"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rouge CGT Foncé",
|
||||||
|
"slug": "cgt-red-dark",
|
||||||
|
"color": "#a8000e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Fond Principal",
|
||||||
|
"slug": "bg-main",
|
||||||
|
"color": "#ffffff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Fond Doux",
|
||||||
|
"slug": "bg-soft",
|
||||||
|
"color": "#f1f3f5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sombre Topbar & Footer",
|
||||||
|
"slug": "bg-topbar",
|
||||||
|
"color": "#1c1e21"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Texte Principal",
|
||||||
|
"slug": "text-main",
|
||||||
|
"color": "#1a1a1a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Texte Secondaire",
|
||||||
|
"slug": "text-muted",
|
||||||
|
"color": "#4a5568"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bordure Carte",
|
||||||
|
"slug": "border-card",
|
||||||
|
"color": "#cbd5e1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typography": {
|
||||||
|
"customFontSize": true,
|
||||||
|
"defaultFontSizes": false,
|
||||||
|
"fontFamilies": [
|
||||||
|
{
|
||||||
|
"name": "Système Moderne",
|
||||||
|
"slug": "system-sans",
|
||||||
|
"fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fontSizes": [
|
||||||
|
{
|
||||||
|
"name": "Petit",
|
||||||
|
"slug": "small",
|
||||||
|
"size": "0.875rem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Normal",
|
||||||
|
"slug": "medium",
|
||||||
|
"size": "1rem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Grand",
|
||||||
|
"slug": "large",
|
||||||
|
"size": "1.25rem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Très grand",
|
||||||
|
"slug": "xlarge",
|
||||||
|
"size": "1.75rem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Titre Principal",
|
||||||
|
"slug": "xxlarge",
|
||||||
|
"size": "2.5rem"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"border": {
|
||||||
|
"radiusSizes": [
|
||||||
|
{
|
||||||
|
"name": "Bouton",
|
||||||
|
"slug": "button",
|
||||||
|
"size": "8px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Carte",
|
||||||
|
"slug": "card",
|
||||||
|
"size": "12px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Encart",
|
||||||
|
"slug": "panel",
|
||||||
|
"size": "14px"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pilule",
|
||||||
|
"slug": "pill",
|
||||||
|
"size": "999px"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"layout": {
|
||||||
|
"contentSize": "820px",
|
||||||
|
"wideSize": "1160px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"styles": {
|
||||||
|
"color": {
|
||||||
|
"background": "var(--wp--preset--color--bg-main)",
|
||||||
|
"text": "var(--wp--preset--color--text-main)"
|
||||||
|
},
|
||||||
|
"typography": {
|
||||||
|
"fontFamily": "var(--wp--preset--font-family--system-sans)",
|
||||||
|
"fontSize": "var(--wp--preset--font-size--medium)",
|
||||||
|
"lineHeight": "1.65"
|
||||||
|
},
|
||||||
|
"elements": {
|
||||||
|
"link": {
|
||||||
|
"color": {
|
||||||
|
"text": "var(--wp--preset--color--cgt-red)"
|
||||||
|
},
|
||||||
|
":hover": {
|
||||||
|
"color": {
|
||||||
|
"text": "var(--wp--preset--color--cgt-red-dark)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"color": {
|
||||||
|
"background": "var(--wp--preset--color--cgt-red)",
|
||||||
|
"text": "#ffffff"
|
||||||
|
},
|
||||||
|
"border": {
|
||||||
|
"radius": "8px"
|
||||||
|
},
|
||||||
|
":hover": {
|
||||||
|
"color": {
|
||||||
|
"background": "var(--wp--preset--color--cgt-red-dark)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||