gilles
27 Agosto , 2026 09:05
1
Percebi que não é possível ordenar uma categoria em ordem alfabética pelos títulos dos tópicos por padrão. Provavelmente me dirão que basta usar os filtros para fazer esse ajuste, mas isso traz dois problemas principais:
Há muitas etapas, o que nem todos conseguem realizar.
Perde-se o visual habitual das tiles.
Seria possível ter um parâmetro por categoria para definir uma ordenação alfabética dos tópicos por padrão? Não sei se isso está previsto no roadmap.
Reitero, é apenas um retorno de experiência prática, mas acho uma pena ficar sem essa opção, que é padrão no Discourse.
2 Curtiram
chapoi
27 Agosto , 2026 10:32
2
Mas por que você gostaria de uma ordenação alfabética? Qual é o caso de uso que você tem em mente?
gilles
27 Agosto , 2026 10:35
3
Na verdade, em algumas categorias, tenho fichas de jogos de tabuleiro e gostaria que, ao entrar nessas categorias específicas, os tópicos fossem ordenados em ordem alfabética. Tentei fazer um pequeno desenvolvimento, mas não estou conseguindo.
2 Curtiram
RGJ
(Richard - Communiteq)
27 Agosto , 2026 10:51
4
Isso é útil para cursos e afins, em que os tópicos são intitulados “Aula 1”, “Aula 2” etc.
Além disso, uma das minhas maiores reclamações em relação ao plugin doc-categories é que ele ainda expõe uma lista de tópicos, especialmente no mobile. Ser possível ordenar em ordem alfabética pelo menos mitigaria parte disso.
4 Curtiram
Estamos forçando uma renderização local de A a Z para manter nosso glossário limpo. Existem casos específicos em que isso é realmente necessário.
Moin
27 Agosto , 2026 11:35
6
gilles:
Você perde o layout de tiles usual.
Não tenho certeza se entendi esse ponto. Quais tiles são perdidos ao olhar para https://meta.discourse.org/filter?q=order%3Atitle-asc ?
1 Curtiu
gilles
27 Agosto , 2026 12:10
7
Talvez eu me tenha expressado mal por e-mail eu achava que manteríamos o mesmo visual dos tiles
categoria sem filtro
categoria com filtro
1 Curtiu
Posso confirmar que o filtro não é útil para aqueles de nós que desejam manter a visualização padrão como está, especialmente se for aplicado a categorias que funcionam como Documentação de Categoria (Glossário, CMS).
É um ponto de partida, mas não atende à necessidade simples — talvez não do ponto de vista técnico, mas certamente do ponto de vista dos nossos usuários — de exibir tópicos organizados em ordem alfabética.
Acho que o filtro atende a outras necessidades de forma abrangente.
Apenas compartilhando uma solução que estava usando há algumas semanas:
satonotdead:
Acabei usando um Componente de Tema personalizado para isso:
// A-Z precisa da categoria inteira: o core não consegue ordenar uma lista de tópicos por título
// (TopicQuery::SORTABLE_MAPPING não tem "title"), então esgotamos a lista paginada
// antes de ordenar. Limitado — as categorias de documentação são pequenas; qualquer coisa maior faz fallback para
// ordenar o que estiver carregado, o que o MutationObserver abaixo mantém atualizado.
// ponytail: descarte este loop inteiro se o core eventualmente implementar ordenação de título no servidor.
const MAX_DOC_PAGES = 12; // ~360 tópicos com 30 por página
let docLoadRun = 0;
async function loadAllDocTopics(api) {
const run = ++docLoadRun;
// `controller:discovery/topics` está obsoleto no Discourse atual
// (id de obsolescência: discourse.discovery-topics-controller). O Discovery agora usa um
// controlador dedicado por filtro; as categorias de documentação são sempre a lista de tópicos mais recentes,
// então buscamos esse controlador diretamente. Falhar aqui significa apenas que ordenamos
// a primeira página, então cada passo usa optional-chaining.
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();
// Navegou para longe durante o carregamento, ou a lista parou de crescer — de qualquer forma, pare.
if (run !== docLoadRun || (list.topics?.length ?? 0) === before) {
return;
}
}
}
// Ordena a lista de tópicos de Documentação de A-Z, colacionando com o próprio <html lang> da página.
let docSortObservers = new Map();
function docSortLocale() {
const lang = document.documentElement.lang;
if (!lang) {
return undefined;
}
try {
Intl.getCanonicalLocales(lang); // lança RangeError para uma tag malformada
return lang;
} catch {
return undefined; // faz fallback para o locale padrão do 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; // já está ordenado — impede que o observer se alimente a si mesmo
}
// Insere antes do que segue as linhas, mantendo qualquer sentinela de "carregar mais" por último.
const anchor = rows[rows.length - 1].nextSibling;
// Fixa a primeira linha visível para que inserções acima dela não pulem o scroll.
const pinned = rows.find((row) => row.getBoundingClientRect().bottom > 0);
const pinnedTop = pinned?.getBoundingClientRect().top;
// Observer pausado para que nossos próprios movimentos não reentrem nesta função.
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();
// Não é um contêiner flex/grid, então a reordenação deve mover nós do DOM — CSS `order` é ignorado.
document.querySelectorAll(".topic-list.doc-simple-mode .topic-list-body").forEach((body) => {
// try/finally para que a lista seja sempre revelada mesmo se a ordenação lançar um erro.
try {
sortDocTopicList(body, locale);
} finally {
body.classList.add("docs-sorted");
}
// Ordene apenas uma vez que o carregamento acalme — a reordenação durante o carregamento travava o loader.
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);
});
}
Acho que o código provavelmente pode ser melhorado, aceito sugestões e/ou PRs com prazer.
1 Curtiu
gilles
14 Setembro , 2026 06:25
10
Boa iniciativa, obrigado @satonotdead
1 Curtiu