Come parte del nostro continuo sforzo per migliorare il codice di Discourse, stiamo rimuovendo l’uso del sistema di rendering “widget” legacy e lo stiamo sostituendo con i componenti Glimmer.
Recentemente, abbiamo modernizzato il menu dei post, ed è ora disponibile in Discourse dietro l’impostazione glimmer_post_menu_mode.
Questa impostazione accetta tre valori possibili:
disabled: utilizza il sistema legacy “widget”auto: rileverà la compatibilità dei tuoi plugin e temi attuali. Se alcuni non sono compatibili, userà il sistema legacy; altrimenti userà il nuovo menu.enabled: userà il nuovo menu. Se hai plugin o temi incompatibili, il tuo sito potrebbe non funzionare correttamente.
Abbiamo già aggiornato i nostri plugin ufficiali per renderli compatibili con il nuovo menu, ma se hai ancora plugin, temi o componenti di tema di terze parti incompatibili con il nuovo menu, sarà necessario aggiornarli.
Verranno visualizzati avvisi nella console del browser che identificano la fonte dell’incompatibilità.
Cronologia di implementazione
Queste sono stime approssimative soggette a modifiche
Q4 2024:
implementazione core completata
plugin ufficiali aggiornati
abilitato su Meta
glimmer_post_menu_modeimpostato suautodi default; messaggi di deprecazione nella console abilitati
pubblicati consigli per l’aggiornamento
Q1 2025:
plugin e temi di terze parti dovrebbero essere aggiornati
iniziano i messaggi di deprecazione, attivando un banner di avviso per l’amministratore per eventuali problemi residui
abilitato di default il nuovo menu dei post
Q2 2025
1° aprile - rimozione dell’impostazione del feature flag e del codice legacy
Cosa significa per me?
Se il tuo plugin o tema utilizza le API “widget” per personalizzare il menu dei post, dovrà essere aggiornato per essere compatibile con la nuova versione.
Come posso provare il nuovo menu dei post?
Nell’ultima versione di Discourse, il nuovo menu dei post sarà abilitato se non hai plugin o temi incompatibili.
Se hai installato estensioni incompatibili, come amministratore puoi comunque cambiare l’impostazione su enabled per forzare l’uso del nuovo menu. Usalo con cautela, poiché il tuo sito potrebbe non funzionare correttamente a seconda delle personalizzazioni installate.
Nel raro caso in cui questo sistema automatico non funzioni come previsto, puoi temporaneamente sovrascrivere questo “feature flag automatico” utilizzando l’impostazione sopra. Se devi farlo, faccelo sapere in questo argomento.
Devo aggiornare il mio plugin o tema?
Dovrai aggiornare i tuoi plugin o temi se eseguono una delle personalizzazioni seguenti:
-
Utilizzano
decorateWidget,changeWidgetSetting,reopenWidgetoattachWidgetActionsu questi widget:post-menupost-user-tip-shimsmall-user-list
-
Utilizzano uno dei seguenti metodi API:
addPostMenuButtonremovePostMenuButtonreplacePostMenuButton
Se hai estensioni che eseguono una delle personalizzazioni sopra, verrà visualizzato un avviso nella console che identifica il plugin o il componente che deve essere aggiornato quando accedi a una pagina di argomento.
L’ID di deprecazione è:
discourse.post-menu-widget-overrides
Se utilizzi più di un tema nella tua istanza, assicurati di controllarli tutti, poiché gli avvisi verranno visualizzati solo per i plugin attivi e i temi e i componenti di tema attualmente in uso.
Quali sono le sostituzioni?
Abbiamo introdotto il value transformer post-menu-buttons come nuova API per personalizzare il menu dei post.
Il value transformer fornisce un oggetto DAG che consente di aggiungere, sostituire, rimuovere o riordinare i pulsanti. Fornisce anche informazioni sul contesto, come il post associato al menu, lo stato del post visualizzato e le chiavi dei pulsanti per facilitare il posizionamento degli elementi.
Le API DAG si aspettano di ricevere componenti Ember se l’API richiede una nuova definizione di pulsante, come .add e .replace.
Ogni personalizzazione è diversa, ma ecco alcune indicazioni per i casi d’uso più comuni:
addPostMenuButton
Prima:
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",
};
}
});
});
Dopo:
Gli esempi seguenti utilizzano il Template Tag Format (gjs) di Ember.
// 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 {
// indica se il pulsante verrà visualizzato immediatamente o nascosto dietro il pulsante "mostra altro"
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, // chiave del primo pulsante
secondLastHiddenButtonKey, // chiave del penultimo pulsante nascosto
lastHiddenButtonKey, // chiave dell'ultimo pulsante nascosto
},
}) => {
dag.add(
"solved",
SolvedAcceptAnswerButton,
post.topic_accepted_answer
? {
before: lastHiddenButtonKey,
after: secondLastHiddenButtonKey,
}
: {
before: [
"assign", // pulsante aggiunto dal plugin assign
firstButtonKey,
],
}
);
}
);
});
Stile dei tuoi pulsanti
Si consiglia di includere
...attributescome mostrato nell’esempio sopra nel tuo componente.Se combinato con l’uso dei componenti
DButtonoDMenu, questo gestirà le classi di base e garantirà che il tuo pulsante segua il formato degli altri pulsanti nel menu dei post.È possibile specificare ulteriori formattazioni utilizzando le tue classi personalizzate.
replacePostMenuButton
- prima:
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;
},
});
});
- dopo:
import ReactionsActionButton from "../components/discourse-reactions-actions-button";
...
withPluginApi("1.34.0", (api) => {
api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context: { buttonKeys } }) => {
// ReactionsActionButton è il nuovo componente del pulsante
dag.replace(buttonKeys.LIKE, ReactionsActionButton);
}
);
});
removePostMenuButton
- prima:
withPluginApi("1.34.0", (api) => {
api.removePostMenuButton('like', (attrs, state, siteSettings, settings, currentUser) => {
if (attrs.post_number === 1) {
return true;
}
});
});
- dopo:
withPluginApi("1.34.0", (api) => {
api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context: { post, buttonKeys } }) => {
if (post.post_number === 1) {
dag.delete(buttonKeys.LIKE);
}
}
);
});
E le altre personalizzazioni?
Se la tua personalizzazione non può essere realizzata utilizzando la nuova API che abbiamo introdotto, faccelo sapere creando un nuovo argomento di sviluppo per discuterne.
Sono autore di plugin/temi. Come posso aggiornare un tema/plugin per supportare sia il vecchio che il nuovo menu dei post durante la transizione?
Abbiamo utilizzato il modello sottostante per supportare sia la vecchia che la nuova versione del menu dei post nei nostri plugin:
function customizePostMenu(api) {
const transformerRegistered = api.registerValueTransformer(
"post-menu-buttons",
({ value: dag, context }) => {
// nuove personalizzazioni del menu dei post
...
}
);
const silencedKey =
transformerRegistered && "discourse.post-menu-widget-overrides";
withSilencedDeprecations(silencedKey, () => customizeWidgetPostMenu(api));
}
function customizeWidgetPostMenu(api) {
// vecchia personalizzazione del codice "widget" qui
...
}
export default {
name: "my-plugin",
initialize(container) {
withPluginApi("1.34.0", customizePostMenu);
}
};
Altri esempi
Puoi consultare i nostri plugin ufficiali per esempi su come utilizzare la nuova API: