api.createWidgetでapi.onPageChangeを使用する方法

こんにちは。すべてのページに画像バナーを追加しようとしていますが、2つのランダムな画像からランダムに選択されるようにしたいです。テーマのHeadセクションに追加してホームページをハードリロードすると機能します。

***編集:***ソリューションに最も近い私の試みはここにあります:

何が間違っているか、何かアイデアはありますか?よろしくお願いします!

これはより適切な試みです。api.onPageChange(() 関数なしで実行すると機能しますが、ハードページを更新するまで画像はランダム化されません。api.onPageChange(() 関数を追加すると、画像はまったく表示されません。私が間違っている点について何かヒントはありますか?

<script type="text/discourse-plugin" version="0.8">

api.onPageChange(() => {
        doStuff();
});

function doStuff() {

const h = require("virtual-dom").h;

let banners = new Array();
banners[0]="https://example.com/uploads/default/original/1X/9d9762a4129c78c478d14ff857c3bd1f2be0322a.jpg";
banners[1]="https://example.com/uploads/default/original/1X/04ede2abd9ac117c64988a5b0bcf033474381527.jpg";

let GoTo = new Array();
GoTo[0]="https://google.com";
GoTo[1]="https://brave.com";

let Number = Math.round(1 * Math.random());
let TheLink = GoTo[Number];
let TheImage = banners[Number];

  api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",
    html() {
    return h("div#top-banner", [
      h(
        "a.custom-ad-link",
        { href: TheLink },
        h("img", { src: TheImage })
      )
    ]);
    }
  });
}
</script>

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/inject-widget">
  {{mount-widget widget="top-banner-widget"}}
</script>
「いいね!」 1

ウィジェットの再レンダリングをトリガーすることが欠けていた部分だと思います…ウィジェットは操作時に再レンダリングされると記憶しているので、ページ変更時に再レンダリングされるように this.scheduleRerender(); を追加しました。

これはローカルで動作します。

api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",

    html() {
        let Number = Math.round(1 * Math.random());

        let banners = new Array();
        banners[0]="https://placekitten.com/500/500";
        banners[1]="https://placekitten.com/500/300";

        let GoTo = new Array();
        GoTo[0]="https://google.com";
        GoTo[1]="https://brave.com";

        let TheLink = GoTo[Number];
        let TheImage = banners[Number];

        api.onPageChange(() => {
            this.scheduleRerender();
        });

        return h("div#top-banner", [
          h(
            "a.custom-ad-link",
            { href: TheLink },
            h("img", { src: TheImage })
          )
        ]);
    }
});
「いいね!」 5

素晴らしい!本当にありがとうございます。自分で見つけることは決してできませんでした!

テーマコンポーネントの完全なHeadコードはこちらです。

<script type="text/discourse-plugin" version="0.8">

const h = require("virtual-dom").h;

api.createWidget("top-banner-widget", {
    tagName: "div.top-banner",

    html() {
        let Number = Math.round(1 * Math.random());
        
        let banners = new Array();
        banners[0]="https://example.com/uploads/default/original/1X/9d9762a4129c78c478d14ff857c3bd1f2be0322a.jpg";
        banners[1]="https://example.com/uploads/default/original/1X/04ede2abd9ac117c64988a5b0bcf033474381527.jpg";

        let GoTo = new Array();
        GoTo[0]="https://google.com";
        GoTo[1]="https://brave.com";
  
        let TheLink = GoTo[Number];
        let TheImage = banners[Number];
        
        api.onPageChange(() => {
            this.scheduleRerender();
        });
  
        return h("div#top-banner", [
          h(
            "a.custom-ad-link",
            { href: TheLink },
            h("img", { src: TheImage })
          )
        ]);
    }
});

</script>

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/inject-widget">
  {{mount-widget widget="top-banner-widget"}}
</script>
「いいね!」 1

また、これがEmberコンポーネントである可能性も言及する価値があります。長期的には、カスタムウィジェットシステムよりもEmberに依存するようになります。Emberのアップデート作業はまだ進行中であるため、Discourseのカスタマイズに関するドキュメントはこの点において少し遅れています。

これがEmberコンポーネントとしてどのように機能するかを示すテーマコンポーネントをまとめました。GitHub - awesomerobot/discourse-component-example

ここには3つの重要なファイルがあります。

  1. コネクタ (/javascripts/discourse/connectors/custom-header-banner-connector.hbs)

  2. コンポーネント (/javascripts/discourse/components/custom-header-banner.js)

  3. コンポーネントのテンプレート (/javascripts/discourse/templates/components/custom-header-banner.hbs)

コネクタはコンポーネントが追加される場所なので、これには<CustomHeaderBanner />のみが含まれている必要があります。コンポーネントは、ページ変更(ルート変更)を検出し、どの画像/リンクがランダムに表示されるかのロジックを設定する場所です。コンポーネントのテンプレートは、データがHTMLでどのように提示されるかです。

「いいね!」 3

なるほど、参考になりました。リポジトリからテーマコンポーネントとしてインストールした場合、サイトで機能することを確認しました。

または、カスタマイズ > インストール > 新規作成 インターフェースから Ember テーマコンポーネントとして手動で追加し、その後 CSS / HTML の編集 を行うことはできますか?そうすれば、必要に応じて画像やリンクを素早く変更するのが容易になります。custom-header-banner.js の内容は Head に、そして \u003cCustomHeaderBanner /\u003eAfter Header または Body に追加し、custom-header-banner.hbs の内容はどこに追加すればよいか分かりません。

「いいね!」 1

ローカルにインストールされたテーマコンポーネントに翻訳するには、もう少し複雑ですが、リモートテーマに柔軟性を加える1つの方法は、テーマ設定を使用することです(https://meta.discourse.org/t/add-settings-to-your-discourse-theme/82557)。

これには、settings.yml ファイルを追加し、コンポーネントおよび/またはテンプレートのいくつかの値を更新することが含まれます。その後、テーマコンポーネントの管理ページで次のような設定を取得できます。

上記のウィジェット実装にとどまり、管理パネルから更新することも問題ありませんが、可能な場合はgitの使用をお勧めします。トラブルシューティングが必要な場合に共有しやすく、変更を追跡しやすくなります。

「いいね!」 1

素晴らしい、忍耐強く明確なご説明、本当にありがとうございます。そのオプションも素晴らしいですね。

「いいね!」 1

こんにちは、またお会いできて嬉しいです。ウィジェットをホームページのような特定のURLにのみ表示させる最善の方法を調べています。

簡単な方法は、ホームページにのみ存在するプラグインのアウトレットを使用することです。これは現時点では私のニーズに合っています(具体的には discovery-navigation-bar-above)。しかし、特定のページのURLに対応したプログラム的な方法についてもまだ興味があります。

@awesomerobot さんによる、この非常に役立つトピックを見つけました:

これを、この投稿の前半のソリューションに適応させようとしました:

        api.onPageChange((url) => {
            if (url === "/" || url === homeRoute) {
               this.scheduleRerender();
            }
        });

しかし、これはまだすべてのページに画像を表示させてしまいます。また、if句の中に変数やランダム選択コードを入れようとしましたが、まったく機能しません。

また、例の <script type="text/x-handlebars" ... セクションもありますが、HTMLしか許可されていないようで、前のスクリプトから変数にどうやって渡すのかわかりません。

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.