Cela pourrait être utile si l’élément Voir x nouveaux ou mis à jour sujets était fixé en haut, juste sous l’en-tête, afin que vous le voyiez immédiatement en faisant défiler la liste des sujets. Lorsque vous cliquez sur cette barre, la page devrait remonter en haut pour charger les nouveaux ou mis à jour sujets.
L’autre partie (JavaScript) consisterait en une fonction de clic pour remonter en haut ou faire défiler jusqu’au sommet, mais je ne sais pas comment le faire ni quelle est la meilleure méthode.
J’ai trouvé cette section dans les modèles discovery/topics.hbs et discovery/categories.hbs. Si je modifie le <a href en <a href="/", cela pourrait fonctionner (je ne suis pas sûr, je n’ai pas essayé), mais cela rechargerait la page à chaque fois, comme si je cliquais sur le logo.
Oui, l’ajout d’une URL provoquera une navigation car il n’existe aucune logique pour intercepter l’événement.
Le lien appelle une action Ember. Toutes les actions dans Discourse sont extensibles. Elles agissent donc en quelque sorte comme des points d’extension pour la personnalisation. Alors, comment modifier une action ? Eh bien, vérifions d’abord ce qu’elle fait.
Recherchez sur GitHub ou localement le nom de l’action. Les actions sont toujours définies dans des fichiers JS et référencées dans Handlebars. Nous voulons voir la définition, nous restreignons donc la recherche aux fichiers JS.
Vous obtenez quatre fichiers. Lequel devez-vous examiner ? Vous souhaitez personnaliser le
template discovery/topics.hbs
. Donc, discovery/topics.js
est ce que vous devez examiner.
Ce code est-il utile ? Non, mais nous savons maintenant où l’action est définie. Modifions-la donc.
discovery/topics.js est une classe Ember. Vous pouvez modifier les classes Ember avec une méthode dans l’API des plugins appelée… modifyClass
Nous connaissons déjà la classe que nous voulons modifier. C’est discovery/topics. Nous devons savoir de quel type de classe il s’agit. Vérifions donc le répertoire des fichiers.
discourse/app/controllers/discovery/topics.js
C’est un contrôleur.
Nous savons également que nous voulons modifier l’action showInserted dans cette classe. Commençons donc par ceci.
api.modifyClass("controller:discovery/topics", {
pluginId: 'sticky-new-topics-banner',
actions: {
showInserted() {
// faisons quelques travaux
}
}
});
Vous pouvez ensuite ajouter tout code que vous souhaitez pour faire défiler la fenêtre lorsque l’utilisateur clique sur la bannière « nouveaux sujets ». J’ai opté pour quelque chose comme ceci.
Alors, avons-nous terminé ? Non. Cela brise Discourse car vous remplacez complètement l’action. Cliquer sur le lien fera maintenant défiler vers l’élément list-controls, mais il ne chargera pas les nouveaux sujets. Pourquoi ? Parce que le code principal n’est plus appliqué. Je veux dire, ce genre de chose
Alors, comment corriger cela ? Avec cette ligne simple
this._super(...arguments);
Vous n’avez pas besoin de copier du code depuis le noyau si vous souhaitez simplement y ajouter quelque chose. Faites votre travail, puis ajoutez cette ligne. Tout ce qu’elle fait, c’est s’assurer que le code du noyau est appliqué.
Si vous testez cela, vous verrez que presque tout fonctionne parfaitement, sauf… l’en-tête chevauche list-controls. Pourquoi ? Parce que l’en-tête est défini comme sticky.
Vous pouvez corriger cela de plusieurs façons en JS : calculer la hauteur, obtenir le décalage, importer un helper depuis Discourse, etc. Je n’entrerai pas dans ces détails.
La méthode la plus simple consiste à utiliser CSS avec scroll-margin-top, dont vous pouvez lire la documentation ici.
En français : Lorsque le lien est cliqué, faites défiler jusqu’au haut de list-controls - 2 * la hauteur de l’en-tête, afin qu’il ne chevauche pas et qu’il y ait un peu d’espace en dessous.
#list-area {
// mobile a une mise en page différente
.alert-info,
.show-more.has-topics {
position: sticky;
// safari est parfois capricieux sans le préfixe
position: -webkit-sticky;
top: var(--header-offset);
// la bannière doit être au-dessus du contenu
z-index: z("header");
}
}
.list-controls {
scroll-margin-top: calc(var(--header-offset) * 2);
}
Merci @Johani ! Cela m’a été très utile et je pense avoir enfin compris beaucoup de choses. J’apprécie vraiment tes réponses détaillées car on peut beaucoup apprendre grâce à elles : comment les choses fonctionnent et, bien sûr, que tout fonctionne parfaitement. Merci encore !