Files
thalim-plugin-newsletter/README.md

7.4 KiB

thalim-newsletter

Plugin WordPress qui compose les newsletters mensuelles du laboratoire THALIM à partir du contenu déjà publié sur le site, et les exporte en HTML prêt pour un envoi email.

  • Version : 1.0.0
  • Auteur : THALIM Dev
  • Licence : GPL v2 or later

Installation

cd wp-content/plugins
git clone gitea@figureslibres.io:valentin_le_moign/thalim-plugin-newsletter.git thalim-newsletter

Puis activer depuis l'admin WordPress. Dans le cadre du projet THALIM, le clonage est automatisé par bootstrap.sh du repo thalim-stack.

Utilisation

Une fois activé, le plugin ajoute une page d'administration : Outils → Newsletter (capacité requise : edit_others_posts).

Le workflow :

  1. Sélection d'un mois (sélecteur année-mois)
  2. Chargement AJAX (thalim_nl_load_month) des contenus éligibles, regroupés par catégorie parente
  3. Cases à cocher pour inclure ou exclure chaque publication / séance. Tout est coché par défaut pour un mois sans newsletter existante (à l'ouverture d'une newsletter déjà enregistrée, c'est la sélection sauvegardée qui est restaurée)
  4. Réordonnancement par glisser-déposer : chaque item porte une poignée (). Pour les catégories normales, on réordonne les annonces dans leur liste. Pour les séminaires, la poignée est sur le titre du séminaire : on réordonne les séminaires entre eux (les séances, elles, restent toujours triées par ordre chronologique). L'ordre choisi est repris tel quel dans le rendu HTML après sauvegarde — l'ordre de soumission des cases suit l'ordre du DOM, et l'export rend chaque section dans l'ordre stocké
  5. Champs intro, conclusion, URL d'inscription, URL de désinscription
  6. Sauvegarde : crée un post WordPress dans la catégorie Newsletter (20) avec le HTML email complet en post_content
  7. Bouton Exporter en HTML (thalim_nl_export_html) → téléchargement du fichier newsletter-THALIM-{mois}.html

Une liste des newsletters déjà sauvegardées permet de revenir éditer un mois passé.

Les catégories Vie du labo (intranet) (9), Séance de séminaire (12), Newsletter (20) et Non classé (31) sont exclues de l'UI (EXCLUDED_CATS dans includes/class-post-query.php). Les séances (cat 12) restent listées, mais imbriquées sous leur séminaire — voir plus bas.

Fenêtres d'éligibilité par catégorie

Les contenus pertinents d'un mois donné ne sont pas seulement « les posts publiés ce mois-ci » — chaque catégorie a sa propre logique de fenêtre temporelle (cf. WINDOW_TYPES dans includes/class-post-query.php) :

Catégorie Fenêtre
Appels (8), Soutenances (14) datetime_to_fin (du datetime à date_de_fin)
Colloques (10), Communications (13) debut_minus35_to_fin (de date_de_debut - 35j à date_de_fin)
Ouvrages (15), Articles (16) datetime_plus3m (du datetime à datetime + 3 mois)
Toutes les autres datetime_plus35d (du datetime à datetime + 35 jours)

Quand datetime (ou date_de_debut) est vide, le post_date sert de fallback. Cette logique permet par ex. à un appel à communication d'apparaître dans toutes les newsletters jusqu'à sa date de fin.

Cas particulier : Séminaires (11) → sélection par séance

Le séminaire n'est pas sélectionnable en tant que tel. À la place, le plugin liste ses séances (cat 12) individuellement, chacune avec sa propre case à cocher, regroupées sous le titre (non cliquable) de leur séminaire parent.

  • Éligibilité : une séance apparaît si sa date_de_debut tombe dans [1er du mois, dernier jour du mois + 5 jours] (marge SEANCE_WINDOW_MARGIN_DAYS dans class-post-query.php). Un séminaire sans séance dans cette fenêtre n'apparaît pas.
  • Découverte : on parcourt les séminaires publiés (cat 11) et on lit leur meta seances (tableau d'IDs de séances). Le lien parent→séance vit donc sur le séminaire.
  • Sélection stockée : _newsletter_sections[11] contient des IDs de séances, plus des IDs de séminaires.
  • Rendu HTML (class-html-exporter.php) : les séances cochées sont regroupées par séminaire parent (lookup inverse via Thalim_NL_Post_Query::get_seminar_id_for_seance(), même requête que la redirection #seance-{ID} du thème). Le titre du séminaire est affiché une seule fois, suivi de la liste des séances sélectionnées (date · heure · lieu, lien vers #seance-{id}).
  • Ordre : les séminaires sont réordonnables entre eux par glisser-déposer (poignée sur le titre) — leur ordre de premier appartenance dans la sélection stockée donne l'ordre de rendu. Les séances d'un séminaire sont toujours triées par date_de_debut croissante, dans l'UI comme à l'export.

Catégories couvertes

La liste des catégories éligibles n'est pas codée en dur dans le plugin — elle est calculée dynamiquement via Thalim_NL_Post_Query::get_eligible_categories() (toutes les catégories WordPress, groupées par parent). Les constantes en haut de thalim-newsletter.php (THALIM_NL_CAT_APPELS = 8, etc.) ne servent qu'à associer les fenêtres temporelles spéciales aux catégories concernées :

Constante ID Description
THALIM_NL_CAT_APPELS 8 Appels
THALIM_NL_CAT_COLLOQUES 10 Colloques
THALIM_NL_CAT_SEMINAIRES 11 Séminaires
THALIM_NL_CAT_COMMS 13 Communications
THALIM_NL_CAT_SOUTENANCES 14 Soutenances
THALIM_NL_CAT_OUVRAGES 15 Ouvrages
THALIM_NL_CAT_ARTICLES 16 Articles
THALIM_NL_CAT_NEWSLETTER 20 Newsletter (catégorie où sont sauvegardés les digests)

IDs vérifiés en DB le 2026-03-20. À mettre à jour en cas de migration ou de réorganisation des taxonomies.

Format HTML email

includes/class-html-exporter.php génère un HTML compatible clients mail :

  • Layout table-based, largeur 600 px
  • Styles inline sur tous les éléments
  • Polices : Gelasio (Google Fonts @import, fallback Georgia) pour les titres, Arial/Helvetica pour le corps
  • Media queries pour le rendu mobile
  • Preheader caché (texte d'aperçu dans les boîtes mail)

Le HTML complet est généré à la sauvegarde et stocké tel quel dans post_content — l'export se contente de le renvoyer.

Prérequis

  • WordPress 6.0+
  • PHP 7.4+
  • Plugin Pods (le pod post et son champ catégorie pour la triple écriture)

Structure

.
├── thalim-newsletter.php       # point d'entrée, constantes, bootstrap
├── assets/
│   ├── admin.css                 # styles de la page admin
│   └── admin.js                  # interactions (sélecteur mois, cases, export)
└── includes/
    ├── class-post-query.php      # requêtes SQL custom + fenêtres temporelles par catégorie
    ├── class-html-exporter.php   # génération du HTML email (tables, inline styles)
    └── class-admin-page.php      # UI Tools > Newsletter + handlers AJAX + sauvegarde