Enable tagging only in some categories

This is looking good @neil. One thing that would be good relating to this would be the simple option to ‘enable tags in category’ option in the category modal.

In my use case I only want tags (and specific tags at that) to be able to be used in specific categories. E.g. in those categories where I don’t want tags enabled I wouldn’t want the tag input field to be shown to users. Is this doable?

4 curtidas

It’s probably doable, but I have to focus on completing some other tag features first. Will have to come back around to this one later.

9 curtidas

I would love to only enable tags in certain categories as well - bookmarking this thread to keep an eye on the discussion moving forward

I think this is currently possible in the way that you can define tag-groups and you can configure category setting in order to use that tag-group.

do you mean something else?

3 curtidas

Another feature that would make sense related to this:

If tag filter is enabled, yet only certain categories have tags availble using the ‘Tags that can only be used in this category’ in category settings, I believe the homepage (both the main category, latest and top) pages should have the tag filter disabled by default.

I.e. only when digging down into the categories/sub-categories with tags allowed should the tag filter be shown (showing the respective tags available).

Otherwise from the homepage (whether that be categories or latest), you’ll get a whole bunch of tags in the filter, often without context as they only have context when filtered inside their respective categories.

Does this make sense?

1 curtida

Keen to test this out. Am I able to grab some code somewhere for this? Cheers.

Concordo 100%. No nosso exemplo, temos uma seção de documentários com um grupo de tags dedicado. Quero mostrar o menu suspenso de tags aqui, com apenas as tags dedicadas. Isso está funcionando.

Mas não quero que as mesmas tags estejam disponíveis no menu suspenso no nível superior “mais recentes” e “melhores para todas as categorias”. Isso, na minha opinião, tira a vantagem de dedicar grupos de tags a certas categorias e é confuso no nível superior.

Apenas tags globais que não foram atribuídas a um grupo de tags vinculado a uma categoria devem aparecer no menu suspenso de tags do nível superior.

Nas configurações do grupo de tags, deve haver algo como:

[ ] Limitar este grupo de tags apenas às categorias atribuídas, não exibir nos menus suspensos de nível superior

1 curtida

Isso é algo que eu também gostaria de ver.

No meu primeiro fórum (importado), eu precisava de uma categoria de classificados.

Como no Discourse não existe algo como uma “pasta” contendo categorias, como ocorre em outros motores como vbulletin ou phpBB, eu basicamente tinha três opções:

  1. Uma única categoria de anúncios para ambos os anúncios de “compra” e “venda”, onde os usuários adicionariam [COMPRAR] ou [VENDER] como prefixo do título do tópico por conta própria (então 2000s…)
  2. Uma única categoria de anúncios onde os usuários poderiam usar as tags “comprar” ou “vender”. De longe a mais conveniente, mas não tínhamos nenhum uso de tags em outras categorias, e os usuários veriam o campo de tag no compositor para qualquer categoria, o que seria confuso.
  3. Ter 2 categorias de anúncios no nível superior: “comprar” e “vender”. Essa foi a escolha que fizemos;

Estou importando outro fórum, maior, e tenho exatamente o mesmo “problema”, exceto que precisaria de tags para 2 categorias em vez de 1: uma categoria de classificados e uma categoria “outros idiomas” contendo apenas postagens em idiomas estrangeiros que usariam uma tag específica para o idioma em que estão escritas, como “hebraico”, “dinamarquês”, etc.

E, novamente, não temos a necessidade de tags para nenhuma outra categoria.

Eu precisaria do seletor de tags na barra de navegação da lista de tópicos para ambas essas categorias, mas não para outras categorias.
Eu poderia facilmente escondê-lo quando necessário com um pouco de CSS, mas o principal problema é a entrada de tag no compositor, que não pode ser exibida ou ocultada à vontade…

Acho que, nesta etapa, a melhor maneira seria substituir o método tagValidation do compositor.
Cada vez que uma categoria é selecionada no compositor, ele ocultaria ou mostraria a entrada de tag, com base na categoria selecionada.

Quando os campos de tag estiverem ocultos, ficaria assim, com um espaço vazio:

Além disso, isso poderia potencialmente quebrar o layout se usarmos plugins ou componentes de tema que tenham campos personalizados no compositor, como o plugin de localização.

Estou tentando o método que pensei como uma solução alternativa.

Ocultando o seletor de tags na lista de tópicos com CSS:


(você deve direcionar cada categoria que permite tags com seu seletor CSS)

body:not(.category-other-languages):not(.category-trading-post) {
    .category-breadcrumb .tag-drop {
        display: none;
    }
}

Mostrando e ocultando o seletor de tags no compositor com JS:

<script type="text/discourse-plugin" version="0.8.23">
    // mostrar o seletor de tags no compositor apenas quando necessário
    const discourseComputed = require("discourse-common/utils/decorators").default;
    const EmberObject = require("@ember/object").default;
    function toggleTagChooser(display = "hide") {
        if (display == "show") {
            document.getElementsByClassName("mini-tag-chooser")[0].style.display = "block";
            document.getElementsByClassName("reply-area")[0].classList.add("with-tags");
            return;
        }
        // Verificar a existência do seletor de tags
        let tagChoser = document.getElementsByClassName("mini-tag-chooser");
        if(tagChoser.length > 0) {
            tagChoser[0].style.display = "none";
            document.getElementsByClassName("reply-area")[0].classList.remove("with-tags");
        }
        return;
    }
    api.modifyClass('controller:composer', {
        @discourseComputed("model.category", "model.tags", "lastValidatedAt")
        tagValidation(category, tags, lastValidatedAt) {
            // código personalizado para alternar o seletor de tags
            toggleTagChooser("hide");
            if(category != null) {
                if (
                    category.allow_global_tags == true ||
                    category.allowed_tag_groups.length > 0 ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("show");
                }
            }
            // fim do código personalizado
            const tagsArray = tags || [];
            if (this.site.can_tag_topics && !this.currentUser.staff && category) {
                // category.minimumRequiredTags incorpora tanto minimum_required_tags quanto required_tag_groups
                if (category.minimumRequiredTags > tagsArray.length) {
                    return EmberObject.create({
                        failed: true,
                        reason: I18n.t("composer.error.tags_missing", {
                            count: category.minimumRequiredTags,
                        }),
                        lastShownAt: lastValidatedAt,
                    });
                }
            }
        }
    });
</script>
1 curtida

Exatamente o que eu estava procurando. Ótimo.

No código atual do núcleo, é especialmente inadequado mostrar a caixa de seleção de tags quando não há tags disponíveis para o usuário selecionar em uma categoria. O último código resolve esse problema de UX. Isso deveria estar no núcleo dessa forma @team

Além disso, deve haver dois textos padrão para o menu suspenso de seleção de tags:

“tags opcionais”

e um caso em que as tags são obrigatórias (e disponíveis para o usuário) em uma categoria:

“selecione pelo menos X tags”

1 curtida

Ao criar um grupo de tags, você pode tornar obrigatório o uso de uma das tags de um conjunto (“buy” ou “sell”) em todas as postagens de uma categoria.

1 curtida

Ainda assim, a caixa de seleção de tags aparece com a indicação “tags opcionais” no editor para uma categoria que possui um grupo de tags obrigatórias, e também aparece em categorias onde não há tags disponíveis para o usuário em outra categoria. Isso é bastante confuso do ponto de vista da experiência do usuário (UX). O usuário precisa clicar no pop-up de erro para entender o que é necessário.

1 curtida

Eu sei, eu só quero, de alguma forma, ocultar o recurso de tags para as categorias em que as tags não estão disponíveis, como @Terrapop explica.

Quando as tags estão desativadas nas configurações do site, o seletor de categorias fica na mesma linha que o título do tópico:

Com minha solução alternativa, há um pouco de desperdício de espaço, já que o seletor de categorias sempre fica abaixo do título do tópico:

Por um lado, mudar a posição do seletor de categorias ao selecionar uma categoria, dependendo se ela requer tags, poderia ser algo errado em termos de UX. Por outro lado, raramente usamos o seletor de categorias mais de uma vez.

1 curtida

Não estou tão preocupado com o desperdício de espaço, mas encontrei outro “problema” no seu código JS, que de resto é muito bom. Talvez você possa dar uma olhada nisso?

Temos grupos de tags que são “apenas para equipe” (por exemplo, tags ocultas e tags do sistema) e grupos de tags obrigatórios para usuários por categoria. Ambos estão vinculados por meio de “Restringir estes grupos de tags a esta categoria”.

Agora, este código verifica apenas se uma categoria permite tags ou se tag_groups.length > 0 ou allowed_tags > 0, mas, infelizmente, isso sempre ocorre, pois temos esses grupos de tags apenas para equipe nos grupos de tags restritos também.

Seria possível alterar o código para levar em conta o contexto do usuário e verificar se realmente há tags disponíveis para esse usuário específico?

 if(category != null) {
                if (
                    category.allow_global_tags == true ||
                    category.allowed_tag_groups.length > 0 ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("visible");
                }
            }

Deveria ser possível contar apenas os públicos no array category.allowed_tag_groups.length para usuários que não são da equipe (ou estão disponíveis no array apenas os nomes e não os estados?) :

public_category.allowed_tag_groups = [public_tag_group.name, staff_only_tag_group.name]
private_category.allowed_tag_groups = [private_tag_group.name, staff_only_tag_group.name]

Ok, atualização:

No nosso caso, vamos inspecionar os nomes em allowed_tag_groups e excluí-los do array se currentUser não for da equipe. Mas isso é uma solução alternativa suja, pois não sei como adicionar o contexto do usuário aqui (ou se isso é até possível dado o código principal atual, acho que não).

             var non_staff_tag_groups = category.allowed_tag_groups.filter(filterHidden);
                function filterHidden(value) {
                  if(value.toLowerCase().indexOf("hidden") === -1 && value.toLowerCase().indexOf("system") === -1) return value;
                }
                if (
                    category.allow_global_tags == true ||
                    (category.allowed_tag_groups.length > 0 && this.currentUser.staff) ||
                    (non_staff_tag_groups.length > 0 && !this.currentUser.staff) ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("visible");
                }
            }

Mas isso é um truque sujo; todo o menu suspenso de tags no compositor deveria ser mais contextual via núcleo e deveria considerar todos os casos acima.

2 curtidas

Desculpe, parece que não vi sua mensagem em 2020!

De qualquer forma, meu código quebrou após uma atualização recente do Discourse. Aqui está uma atualização funcional (o CSS não muda, no entanto):

Selecione as classes de categoria nas quais você deseja ocultar o seletor de tags:

body:not(.category-other-languages):not(.category-trading-post) {
    .category-breadcrumb .tag-drop {
        display: none;
    }
}

O script que alternará dinamicamente o seletor de tags:


    // mostra o seletor de tags no composer apenas quando necessário
    const discourseComputed = require("discourse-common/utils/decorators").default;
    const EmberObject = require("@ember/object").default;
    function toggleTagChooser(display = "hide") {
        if (display == "show") {
            document.getElementsByClassName("mini-tag-chooser")[0].style.display = "block";
            document.getElementsByClassName("reply-area")[0].classList.add("with-tags");
            return;
        }
        // Verifica a existência do seletor de tags
        let tagChoser = document.getElementsByClassName("mini-tag-chooser");
        if(tagChoser.length > 0) {
            tagChoser[0].style.display = "none";
            document.getElementsByClassName("reply-area")[0].classList.remove("with-tags");
        }
        return;
    }
    api.modifyClass('controller:composer', {
        @discourseComputed("model.category", "model.tags", "lastValidatedAt")
        tagValidation(category, tags, lastValidatedAt) {
            // código personalizado para alternar o seletor de tags
            toggleTagChooser("hide");
            if(category != null) {
                if (
                    category.allow_global_tags == true ||
                    category.allowed_tag_groups.length > 0 ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("show");
                }
            }
            // fim do código personalizado
            const tagsArray = tags || [];
            if (this.site.can_tag_topics && !this.currentUser.staff && category) {
                // category.minimumRequiredTags incorpora tanto minimum_required_tags quanto required_tag_groups
                if (category.minimumRequiredTags > tagsArray.length) {
                    return EmberObject.create({
                        failed: true,
                        reason: I18n.t("composer.error.tags_missing", {
                            count: category.minimumRequiredTags,
                        }),
                        lastShownAt: lastValidatedAt,
                    });
                }
            }
        }
    });

sobre isso… já se passaram 6 anos, cara :sweat_smile:

Eu acho que a funcionalidade de grupos de tags hoje em dia, te dá uma experiência próxima.
Você associaria um grupo de tags a um monte de categorias e então proibiria a criação de novas tags.
Não tenho certeza sobre pr-welcome aqui, removendo-o, a mudança desejada precisa ser especificada adequadamente. Isso, eu acho, está pedindo uma caixa de seleção nas configurações da categoria, mas mesmo isso precisa de um monte de reflexão, está marcada por padrão, a configuração extra é simplesmente confusa para muitas pessoas?