Dans le cadre de notre effort continu pour améliorer la base de code de Discourse, nous supprimons l’utilisation de l’ancien système de rendu « widget » et le remplaçons par des composants Glimmer.
Récemment, nous avons modernisé le menu des publications, qui est désormais disponible dans Discourse via le paramètre glimmer_post_menu_mode.
Ce paramètre accepte trois valeurs possibles :
disabled: utilise l’ancien système « widget »auto: détecte la compatibilité de vos plugins et thèmes actuels. Si l’un d’eux est incompatible, il utilisera l’ancien système ; sinon, il utilisera le nouveau menu.enabled: utilise le nouveau menu. Si vous avez un plugin ou un thème incompatible, votre site peut être endommagé.
Nous avons déjà mis à jour nos plugins officiels pour qu’ils soient compatibles avec le nouveau menu, mais si vous avez toujours des plugins, thèmes ou composants de thème tiers incompatibles avec le nouveau menu, leur mise à jour sera nécessaire.
Des avertissements seront affichés dans la console du navigateur pour identifier la source de l’incompatibilité.
Calendrier de déploiement
Ces estimations sont approximatives et sujettes à modification
T4 2024 :
implémentation principale terminée
plugins officiels mis à jour
activé sur Meta
glimmer_post_menu_modedéfini par défaut surauto; messages de dépréciation dans la console activés
conseils de mise à niveau publiés
T1 2025 :
les plugins et thèmes tiers doivent être mis à jour
les messages de dépréciation commencent, déclenchant une bannière d’avertissement pour l’administrateur pour tout problème restant
le nouveau menu des publications activé par défaut
T2 2025
1er avril - suppression du paramètre de feature flag et du code legacy
Qu’est-ce que cela signifie pour moi ?
Si votre plugin ou thème utilise des API « widget » pour personnaliser le menu des publications, celles-ci devront être mises à jour pour être compatibles avec la nouvelle version.
Comment essayer le nouveau menu des publications ?
Dans la dernière version de Discourse, le nouveau menu des publications sera activé si vous n’avez aucun plugin ou thème incompatible.
Si vous avez des extensions incompatibles installées, en tant qu’administrateur, vous pouvez toujours changer le paramètre sur enabled pour forcer l’utilisation du nouveau menu. Utilisez cette option avec prudence car votre site peut être endommagé en fonction des personnalisations installées.
Dans le cas peu probable où ce système automatique ne fonctionne pas comme prévu, vous pouvez temporairement outrepasser ce « feature flag automatique » en utilisant le paramètre ci-dessus. Si vous devez le faire, veuillez nous en informer dans ce sujet.
Dois-je mettre à jour mon plugin ou mon thème ?
Vous devrez mettre à jour vos plugins ou thèmes s’ils effectuent l’une des personnalisations suivantes :
-
Utiliser
decorateWidget,changeWidgetSetting,reopenWidgetouattachWidgetActionsur ces widgets :post-menupost-user-tip-shimsmall-user-list
-
Utiliser l’une des méthodes API suivantes :
addPostMenuButtonremovePostMenuButtonreplacePostMenuButton
Si vous avez des extensions qui effectuent l’une des personnalisations ci-dessus, un avertissement sera affiché dans la console pour identifier le plugin ou le composant qui doit être mis à jour lorsque vous accédez à une page de sujet.
L’ID de dépréciation est :
discourse.post-menu-widget-overrides
Si vous utilisez plusieurs thèmes sur votre instance, assurez-vous de vérifier tous car les avertissements ne seront affichés que pour les plugins actifs et les thèmes et composants de thème actuellement utilisés.
Quelles sont les alternatives ?
Nous avons introduit le transformateur de valeur post-menu-buttons comme nouvelle API pour personnaliser le menu des publications.
Le transformateur de valeur fournit un objet DAG qui permet d’ajouter, remplacer, supprimer ou réorganiser les boutons. Il fournit également des informations contextuelles telles que la publication associée au menu, l’état de la publication affichée et les clés de bouton pour faciliter le placement des éléments.
Les API DAG s’attendent à recevoir des composants Ember si l’API nécessite une nouvelle définition de bouton comme .add et .replace.
Chaque personnalisation est différente, mais voici quelques conseils pour les cas d’utilisation les plus courants :
addPostMenuButton
Avant :
withPluginApi("1.34.0", (api) => {
api.addPostMenuButton("solved", (attrs) => {
if (attrs.can_accept_answer) {
const isOp = currentUser?.id === attrs.topicCreatedById;
return {
action: "acceptAnswer",
icon: "far-check-square",
className: "unaccepted",
title: "solved.accept_answer",
label: isOp ? "solved.solution" : null,
position: attrs.topic_accepted_answer ? "second-last-hidden" : "first",
};
}
});
});
Après :
Les exemples ci-dessous utilisent le format de balise de modèle d’Ember (gjs)
// components/solved-accept-answer-button.gjs
import Component from "@glimmer/component";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import DButton from "discourse/components/d_button";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default class SolvedAcceptAnswerButton extends Component {
// indique si le bouton sera affiché immédiatement ou caché derrière le bouton "voir plus"
static hidden(args) {
return args.post.topic_accepted_answer;
}
...
<template>
<DButton
class="post-action-menu__solved-unaccepted unaccepted"
...attributes
@action={{this.acceptAnswer}}
@icon="far-check-square"
@label={{if this.showLabel "solved.solution"}}
@title="solved.accept_answer"
/>
</template>
}
// initializer.js
import SolvedAcceptAnswerButton from "../components/solved-accept-answer-button";
...
withPluginApi("1.34.0", (api) => {
api.registerValueTransformer(
"post-menu-buttons",
({
value: dag,
context: {
post,
firstButtonKey, // clé du premier bouton
secondLastHiddenButtonKey, // clé du deuxième dernier bouton caché
lastHiddenButtonKey, // clé du dernier bouton caché
},
}) => {
dag.add(
"solved",
SolvedAcceptAnswerButton,
post.topic_accepted_answer
? {
before: lastHiddenButtonKey,
after: secondLastHiddenButtonKey,
}
: {
before: [
"assign", // bouton ajouté par le plugin assign
firstButtonKey,
],
}
);
}
);
});
Style de vos boutons
Il est recommandé d’inclure
...attributescomme montré dans l’exemple ci-dessus dans votre composant.Combiné à l’utilisation des composants
DButtonouDMenu, cela gérera les classes de base et assurera que votre bouton suit le formatage des autres boutons du menu des publications.Un formatage supplémentaire peut être spécifié en utilisant vos classes personnalisées.
replacePostMenuButton
- Avant :
withPluginApi("1.34.0", (api) => {
api.replacePostMenuButton("like", {
name: "discourse-reactions-actions",
buildAttrs: (widget) => {
return { post: widget.findAncestorModel() };
},
shouldRender: (widget) => {
const post = widget.findAncestorModel();
return post && !post.deleted_at;
},
});
});
- Après :
import ReactionsActionButton from "../components/discourse-reactions-actions-button";
...
withPluginApi("1.34.0", (api) => {
api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context: { buttonKeys } }) => {
// ReactionsActionButton est le nouveau composant de bouton
dag.replace(buttonKeys.LIKE, ReactionsActionButton);
}
);
});
removePostMenuButton
- Avant :
withPluginApi("1.34.0", (api) => {
api.removePostMenuButton('like', (attrs, state, siteSettings, settings, currentUser) => {
if (attrs.post_number === 1) {
return true;
}
});
});
- Après :
withPluginApi("1.34.0", (api) => {
api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context: { post, buttonKeys } }) => {
if (post.post_number === 1) {
dag.delete(buttonKeys.LIKE);
}
}
);
});
Et pour les autres personnalisations ?
Si votre personnalisation ne peut pas être réalisée avec la nouvelle API que nous avons introduite, veuillez nous en informer en créant un nouveau sujet de développement pour en discuter.
Je suis l’auteur d’un plugin/thème. Comment mettre à jour un thème/plugin pour prendre en charge à la fois l’ancien et le nouveau menu des publications pendant la transition ?
Nous avons utilisé le modèle ci-dessous pour prendre en charge à la fois l’ancienne et la nouvelle version du menu des publications dans nos plugins :
function customizePostMenu(api) {
const transformerRegistered = api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context }) => {
// nouvelles personnalisations du menu des publications
...
}
);
const silencedKey =
transformerRegistered && "discourse.post-menu-widget-overrides";
withSilencedDeprecations(silencedKey, () => customizeWidgetPostMenu(api));
}
function customizeWidgetPostMenu(api) {
// ancienne personnalisation du code "widget" ici
...
}
export default {
name: "my-plugin",
initialize(container) {
withPluginApi("1.34.0", customizePostMenu);
}
};
Plus d’exemples
Vous pouvez consulter nos plugins officiels pour des exemples sur l’utilisation de la nouvelle API :