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 :
- Sélection d'un mois (sélecteur année-mois)
- Chargement AJAX (
thalim_nl_load_month) des contenus éligibles, regroupés par catégorie parente - 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)
- 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é - Champs intro, conclusion, URL d'inscription, URL de désinscription
- Sauvegarde : crée un post WordPress dans la catégorie Newsletter (
20) avec le HTML email complet enpost_content - Bouton Exporter en HTML (
thalim_nl_export_html) → téléchargement du fichiernewsletter-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_CATSdansincludes/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_debuttombe dans[1er du mois, dernier jour du mois + 5 jours](margeSEANCE_WINDOW_MARGIN_DAYSdansclass-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 viaThalim_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_debutcroissante, 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
postet 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