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

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

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

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

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

100% 同意です。私たちの例では、専用タググループを持つドキュメントセクションがあります。ここでは、専用タグのみを含むタグドロップダウンを表示したいと考えています。これは機能しています。

しかし、トップレベルの「最新」や「すべてのカテゴリのトップ」のドロップダウンに同じタグが表示されるのは避けたいです。これは、特定のカテゴリにタググループを割り当てる利点を損ない、トップレベルでは混乱を招くと思います。

トップレベルのタグドロップダウンに表示されるのは、カテゴリに割り当てられたタググループに属さないグローバルタグのみとするべきです。

タググループ設定には、以下のような項目があるはずです:

[ ] このタググループを割り当てられたカテゴリのみに制限し、トップレベルのドロップダウンには表示しない

「いいね!」 1

これも見たいですね。

最初の(インポートした)フォーラムでは、分類広告のカテゴリーが必要でした。

Discourse では、vBulletin や phpBB などの他のエンジンにあるような、カテゴリーを格納する「フォルダ」という概念が存在しないため、基本的に 3 つの選択肢がありました。

  1. 「購入」と「売却」の両方の広告を扱う単一の広告カテゴリーを作成し、ユーザー自身がトピックのタイトルに [BUY] または [SELL] というプレフィックスを追加する方法(2000 件以上…)
  2. 「購入」または「売却」のタグを使用できる単一の広告カテゴリー。これは最も便利でしたが、他のカテゴリーではタグを使用していなかったため、すべてのカテゴリーのコンポーザーでタグフィールドが表示され、ユーザーが混乱する可能性があります。
  3. 最上位に「購入」と「売却」の 2 つの広告カテゴリーを配置する。これが私たちが選んだ方法です。

現在、より大きなフォーラムをインポートしており、同じ「問題」に直面していますが、今回は 1 つではなく 2 つのカテゴリーにタグが必要になります。1 つは分類広告のカテゴリー、もう 1 つは「その他の言語」カテゴリーです。このカテゴリーには、ヘブライ語やデンマーク語など、特定の言語で書かれた投稿のみが含まれ、その言語に応じたタグを使用します。

そして、他のカテゴリーではタグを必要としません。

トピックリストのナビゲーションバーに、この 2 つのカテゴリーに対してのみタグセレクターを表示したいと考えています。
CSS を少し使うことで、必要に応じて簡単に非表示にすることはできますが、大きな問題はコンポーザー内のタグ入力フィールドです。これは自由に表示・非表示にすることができません。

現時点では、composer の tagValidation メソッドを上書きするのが最善の方法だと思われます。
コンポーザーでカテゴリーが選択されるたびに、選択されたカテゴリーに基づいてタグ入力を表示または非表示にします。

タグフィールドが非表示になった場合、以下のように空白スペースが表示されます。

また、カスタムコンポーザーフィールドを持つプラグインやテーマコンポーネント(例:location plugin)を使用している場合、レイアウトが崩れる可能性があります。

ワークアラウンドとして考えた方法を試しています。

トピック一覧でタグセレクターを CSS で非表示にする:


(各タグ付け可能なカテゴリに対して CSS セレターを指定する必要があります)

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

JS でコンポーザー内のタグセレクターの表示・非表示を切り替える:

<script type="text/discourse-plugin" version="0.8.23">
    // 必要に応じてのみコンポーザー内でタグ選択器を表示する
    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;
        }
        // タグ選択器の存在を確認
        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) {
            // タグ選択器の表示切り替えを行うカスタムコード
            toggleTagChooser("hide");
            if(category != null) {
                if (
                    category.allow_global_tags == true ||
                    category.allowed_tag_groups.length > 0 ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("show");
                }
            }
            // カスタムコードの終了
            const tagsArray = tags || [];
            if (this.site.can_tag_topics && !this.currentUser.staff && category) {
                // category.minimumRequiredTags は minimum_required_tags と 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

まさに探していたものです。素晴らしいです。

現在のコアコードでは、カテゴリに対してユーザーが選択できるタグが存在しない場合に、タグ選択ボックスを表示するのは特に問題です。直前のコードはこの UX 上の問題を解決します。これはコアにこの形で組み込むべきです @team

さらに、タグ選択ドロップダウンには、以下の 2 つの標準テキストを用意すべきです。

「オプションのタグ」

そして、カテゴリに対してタグが必須であり、かつユーザーが選択可能な場合のテキスト

「少なくとも X 個のタグを選択してください」

「いいね!」 1

タググループを作成すると、カテゴリ内のすべての投稿で、特定のタグ(「購入」または「売却」など)のいずれかを使用することを必須にできます。

「いいね!」 1

それでも、必須タググループを持つカテゴリのコンポーザーでは「任意のタグ」というラベル付きのタグ選択ボックスが表示され、ユーザーにタグが利用できない別のカテゴリでも表示されてしまいます。これはユーザー体験(UX)の観点から非常に混乱を招きます。ユーザーはエラーポップアップが表示されるまで、何が必要なのかを理解できないからです。

「いいね!」 1

はい、@Terrapop が説明しているように、タグが利用できないカテゴリではタグ機能を非表示にしたいと考えています。

サイト設定でタグが無効になっている場合、カテゴリセレクターはトピックタイトルと同じ行に表示されます:

私の回避策では、カテゴリセレクターが常にトピックタイトルの下に表示されるため、スペースが少し無駄になっています:

一方、カテゴリを選択する際に、タグが必要かどうかによってカテゴリセレクターの位置を変更するのは、UX として誤ったアプローチかもしれません。他方では、カテゴリセレクターを 1 回以上使うことはほとんどありません。

「いいね!」 1

スペースの無駄についてはそれほど心配していませんが、それ以外に非常に優れた JS コードにおいて別の「問題」を見つけました。これについて確認していただけますか?

カテゴリごとに「スタッフのみ」のタググループ(例:非表示タグやシステムタグ)と必須のタググループがあります。これらは「これらのタググループをこのカテゴリに制限する」でリンクされています。

現在、このコードはカテゴリがタグを許可しているか、tag_groups.length > 0、あるいは allowed_tags > 0 かどうかのみをチェックしていますが、制限されたタググループにもスタッフ専用のタググループが含まれているため、残念ながら常に真となってしまいます。

コードを変更して、ユーザーのコンテキストを考慮し、その特定のユーザーに対して実際に利用可能なタグがあるかどうかを確認することは可能でしょうか?

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

非スタッフユーザーに対して category.allowed_tag_groups.length の配列内のパブリックなタグのみをカウントすることは可能でしょうか(配列には状態ではなく名前しか含まれていないのでしょうか):

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]

更新情報:

私たちの場合allowed_tag_groups の名前を検査し、currentUser がスタッフでない場合は配列から除外します。しかし、これは不純な回避策です。ここではユーザーのコンテキストをどのように追加すればよいかわからないからです(あるいは現在のコアコードから見てこれが可能かどうかはわかりません。おそらく不可能だと思われます)。

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");
}

しかし、これは不純なハックです。コンポーザー内のタグドロップダウン全体がコア経由でより文脈的になり、上記のすべてのケースを考慮すべきです。

「いいね!」 2

申し訳ありません、2020年のメッセージを見逃していたようです!

いずれにせよ、最近のDiscourseのアップデート後にコードが壊れてしまいました。以下は動作するアップデートです(CSSは変更されません):

タグセレクターを非表示にしたいカテゴリクラスをターゲットにします:

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

タグセレクターを動的に切り替えるスクリプト:


    // show tag chooser in the composer only when necessary
    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;
        }
        // Verify the existence of the tag choser
        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) {
            // custom code to toggle the tag choser
            toggleTagChooser("hide");
            if(category != null) {
                if (
                    category.allow_global_tags == true ||
                    category.allowed_tag_groups.length > 0 ||
                    category.allowed_tags.length > 0
                ) {
                    toggleTagChooser("show");
                }
            }
            // end of the custom code
            const tagsArray = tags || [];
            if (this.site.can_tag_topics && !this.currentUser.staff && category) {
                // category.minimumRequiredTags incorporates both minimum_required_tags, and 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,
                    });
                }
            }
        }
    });

それについて…もう6年経ちますよ :sweat_smile:

現在では、タググループ機能がそれに近い体験を提供してくれると思います。

タググループをいくつかのカテゴリに紐付け、新しいタグの作成を禁止します。

ここでは「#pr-welcome」についてはよくわかりません。削除します。希望する変更は適切に指定する必要があります。これはカテゴリ設定にチェックボックスを設けることを求めているのだと思いますが、それにも多くの検討が必要です。デフォルトでチェックが入っているのか、追加の設定は多くの人にとって単に紛らわしいだけなのか?