サイドバーのカスタム変更をプログラムで行う

これは素晴らしい機能ですが、カスタムサイドバーセクションの内容をプログラムで作成する必要がある場合はどうでしょうか? @Olya_Fursova の上記の方法に似た方法でこれを実現しましたが、内容はAPIをクエリしてリンクをレンダリングすることで生成され、一部はカテゴリに、一部は特定のトピックに直接リンクされます。遭遇した問題は2つあります。

  • ページが最初にレンダリングされたときにサイドバーが非表示になっている場合、サイドバーコンテナが存在しないため、動的なコンテンツは表示されません。また、サイドバーが最初に表示されてから折りたたまれ、再度表示されると、カスタムロジックが実行されずにサイドバーコンテナが再レンダリングされるため、動的なコンテンツが失われます。質問:サイドバーが表示されるたびにカスタムコードを実行するために、サイドバーのレンダリングプロセスにフックする方法はありますか?
  • プログラムで追加したサイドバーのリンクをクリックすると、ページ全体が更新されます。質問:サイドバーのカスタムリンクのいずれかをクリックしたときに、ページ全体の更新を防ぐ方法はありますか?

サイドバーをプログラムで変更できる方法があれば、本当に素晴らしいでしょう!

「いいね!」 2

カスタムサイドバーセクションを追加するためのAPIも構築しました。

ここにいくつかの例があります:discourse/app/assets/javascripts/discourse/app/lib/plugin-api.js at 00ab94bf53b784478d0aa7744bf3bb2d5b527580 · discourse/discourse · GitHub

これは実験的なものとしてマークされていますが、使用しても安全なはずです(例えば、有効になっている場合にチャットコンテンツをサイドバーに追加するために使用しています)。

「いいね!」 6

これは面白そうですね、ありがとうございます!しかし、理解するには時間がかかりそうです。例えば、ルーティングの仕組みがまだよくわかりません。また、セクション内のリンクはフラットなリストしかできないように見えますか?現在達成しようとしているのは、例えばこのような、1レベルのインデントです。

カスタムサイドバーセクション用の新しいAPIでこれが達成できますか?

「いいね!」 1

いいえ、サイドバーにデフォルトでインデントを組み込んだことはありませんが、APIでセクションを希望の順序に並べることができれば、インデントはCSSのスタイリングで処理できると思います。

もう少し詳しく調べてみたのですが、これならうまくいくと確信しています。私の今の課題は、リンクのリストが動的であり、ページが変わるたびに変更される可能性があることです。api.onPageChange内でapi.addSidebarSectionを呼び出すという私の単純なアプローチは機能しません。なぜなら、(a)サイドバーは非表示にして再度表示するときにのみ再レンダリングされるため、(b)api.addSidebarSectionは名前キーが再利用されても気にしないため、セクションが繰り返されるからです。

新しいAPIで、ページ遷移ごとに更新されるサイドバーセクションを実現する方法はありますか?

「いいね!」 1

チャットプラグインがサイドバーにどのように統合されているかを確認できます。

この場合、リンクの状態はサービスオブジェクトに保持され、状態が変更されるたびにサイドバーが更新されます。

考えられる解決策は、ページ変更イベントを購読してリンクを更新することです。疑似コードは次のようになります。

import { tracked } from "@glimmer/tracking";

api.addSidebarSection(
  (BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
    const TestSectionLink = class extends BaseCustomSidebarSectionLink {
      // カスタムリンクのプロパティをここに定義します
    };

    const SidebarTestSection = class extends BaseCustomSidebarSection {
      @tracked links = [];

      constructor() {
        super(...arguments);

        this.#updateLinks();
        this.onAppEvent("page:changed", () => this.#updateLinks());
      }

      get newLinksArray() {
        // 現在のURLに基づいたリンクのリスト
      }

      #updateLinks() {
        this.links = this.newLinksArray.map(
          (link) =>
            new TestSectionLink({
              link,
            })
        );
      }

      get sectionLinks() {
        return this.links;
      }
    };
    return SidebarTestSection;
  }
);
「いいね!」 6