Me pregunto si podemos usar los filtros para mostrar una categoría usando la vista de documentos y A-Z (alfabéticamente).
Tenemos un glosario que debería mostrar la vista de temas ordenada 
Actualmente, la vista de filtro está separada de los documentos:
Acabé usando un componente de tema personalizado para ello:
// A-Z necesita la categoría completa: el núcleo no puede ordenar una lista de temas por título
// (TopicQuery::SORTABLE_MAPPING no tiene "title"), así que agotamos la lista paginada
// antes de ordenar. Con un límite — las categorías de documentación son pequeñas; cualquier cosa más grande
// vuelve a ordenar lo que esté cargado, lo cual el MutationObserver de abajo mantiene actualizado.
// ponytail: elimina este bucle completo si el núcleo algún día implementa el ordenamiento por título en el servidor.
const MAX_DOC_PAGES = 12; // ~360 temas a 30 por página
let docLoadRun = 0;
async function loadAllDocTopics(api) {
const run = ++docLoadRun;
// `controller:discovery/topics` está deprecado en la versión actual de Discourse
// (id de deprecación: discourse.discovery-topics-controller). El descubrimiento ahora usa un
// controlador dedicado por filtro; las categorías de documentación siempre son la lista de temas
// más recientes, así que buscamos ese controlador directamente. Si falla aquí, simplemente significa que ordenamos
// la primera página, por lo que cada paso usa encadenamiento opcional.
const list = api.container.lookup("controller:discovery/latest")?.model;
if (!list?.loadMore) {
return;
}
for (let page = 0; page < MAX_DOC_PAGES; page++) {
if (!list.more_topics_url) {
return;
}
const before = list.topics?.length ?? 0;
await list.loadMore();
// Navegamos a otra parte durante la carga, o la lista dejó de crecer — en cualquier caso, detenemos.
if (run !== docLoadRun || (list.topics?.length ?? 0) === before) {
return;
}
}
}
// Ordena la lista de temas de Documentación de la A a la Z, colacionando con el propio <html lang> de la página.
let docSortObservers = new Map();
function docSortLocale() {
const lang = document.documentElement.lang;
if (!lang) {
return undefined;
}
try {
Intl.getCanonicalLocales(lang); // lanza RangeError con una etiqueta malformada
return lang;
} catch {
return undefined; // vuelve a la configuración regional predeterminada del navegador
}
}
function sortDocTopicList(body, locale) {
const rows = [...body.querySelectorAll(":scope > .topic-list-item")];
if (rows.length < 2) {
return;
}
const sorted = [...rows].sort((a, b) => {
const titleA = a.querySelector(".title")?.textContent.trim() ?? "";
const titleB = b.querySelector(".title")?.textContent.trim() ?? "";
return titleA.localeCompare(titleB, locale);
});
if (sorted.every((row, i) => rows[i] === row)) {
return; // ya está ordenado — evita que el observador se alimente a sí mismo
}
// Inserta antes de lo que siga a las filas, manteniendo cualquier centinela de carga más al final.
const anchor = rows[rows.length - 1].nextSibling;
// Fija la primera fila visible para que las inserciones por encima no salten el desplazamiento.
const pinned = rows.find((row) => row.getBoundingClientRect().bottom > 0);
const pinnedTop = pinned?.getBoundingClientRect().top;
// Observador pausado para que nuestros propios movimientos no vuelvan a entrar en esta función.
const observer = docSortObservers.get(body);
observer?.disconnect();
sorted.forEach((row) => body.insertBefore(row, anchor));
observer?.observe(body, { childList: true });
if (pinned) {
window.scrollBy(0, pinned.getBoundingClientRect().top - pinnedTop);
}
}
function sortDocCategoryTopicLists() {
docSortObservers.forEach((observer) => observer.disconnect());
docSortObservers = new Map();
const locale = docSortLocale();
// No es un contenedor flex/grid, así que el reordenamiento debe mover nodos DOM — el `order` de CSS se ignora.
document.querySelectorAll(".topic-list.doc-simple-mode .topic-list-body").forEach((body) => {
// try/finally para que la lista siempre se revele incluso si la ordenación lanza una excepción.
try {
sortDocTopicList(body, locale);
} finally {
body.classList.add("docs-sorted");
}
// Ordena solo una vez que la carga se calme — el reordenamiento a mitad de carga detuvo el cargador.
let settleTimer = null;
const observer = new MutationObserver(() => {
window.clearTimeout(settleTimer);
settleTimer = window.setTimeout(() => {
sortDocTopicList(body, locale);
}, 400);
});
observer.observe(body, { childList: true });
docSortObservers.set(body, observer);
});
}
Creo que el código probablemente se puede mejorar con mucha probabilidad, acepto con gusto sugerencias y/o PRs.