最初の投稿の後にGlimmerコンポーネントを挿入してください

Glimmerコンポーネントがあります。動作していますが、トピックの最初の投稿の後に配置する必要があります。そこにはプラグインのアウトレットがありません。

innerHTMLにテキストを挿入する方法はわかりましたが、それはコンポーネントではできないようです。

何か見落としていますか?

広告プラグインが投稿の間に広告を挿入する方法を見ましたが、よく理解できませんでした。

export default {
  name: "initialize-ad-plugin",
  initialize(container) {
    registerWidgetShim(
      "after-post-ad",
      "div.widget-connector",
      hbs`<PostBottomAd @model={{@data}} />`
    );

    withPluginApi("0.1", (api) => {
      api.decorateWidget("post:after", (helper) => {
        return helper.attach("after-post-ad", helper.widget.model);
      });
    });

....

追加しましょう!どこに追加したいですか?

(あなたがやろうとしていることを達成するための古い方法もありますが、トピックビューを最新化する際にそれらは壊れます。プラグインのアウトレットを追加すれば、将来性もずっと高まります)

「いいね!」 2

このアウトレットは、広告プラグインが使用している decorateWidget("post:after の機能に一致します。

「いいね!」 3

素晴らしいですね!文句を言えば、手に入りますよ!

実際、プラグインのアウトレットを追加するのは「簡単」だと「知っています」が、以前それを追加する方法を知っていたのは hbs ファイルでした。

それはすべての投稿の後に来るのですか?ですから、最初の投稿だけに表示されるように、何か魔法を見つけ出す必要がありますか?

article:after は、以前の試みで私が考案したものです。

「いいね!」 1

投稿はアウトレット引数の1つとして渡されるため、post.post_number == 1 を確認できます。

ハハ!このような質問のお手伝いができて、いつも嬉しく思います。ウィジェットの回避策(近い将来廃止される予定です)ではなく、このような標準APIを使用するテーマやプラグインを使用できることは、すべての人にとってずっと良いことです。

はい、それは公平です。ウィジェット内にそれらを追加することは、コア側では頭痛の種です。しかし、テーマ/プラグイン側からは非常にクリーンになるはずです :crossed_fingers:


テストの失敗の原因を突き止め、明日PRをマージします。(余分なHTML要素がqunitテストの壊れやすいセレクターに影響を与えているようです)

「いいね!」 2

なるほど!@outletArgs={{hash post=@data.post}} ですね。どうすればいいか、かなり見当がつきました。:slight_smile:

重ねて感謝します!

「いいね!」 2

ここでは少し楽観的すぎたかもしれません。申し訳ありません、@pfaffman!私が作成したPRは、アウトレットが使用されていなくても、すべての投稿の間に新しいラッパー <div> を導入してしまいます。これは実際には望ましいことではありません。

ラッパーを回避する方法はあるかもしれませんが、すぐにできる簡単なものはありません。

そのため、現時点での最善の解決策は、OPで参照した広告プラグインの実装をコピーすることだと思います。

基本的に:

  1. コンポーネント(Glimmerでもクラシックでもどちらでも構いません)を作成し、必要なものをレンダリングします。

  2. registerWidgetShim を使用して、そのコンポーネントをウィジェットとして利用可能にします。広告プラグインの例では、「after-post-ad」という名前のウィジェットを作成し、PostBottomAd コンポーネントをレンダリングしています。ウィジェット属性(@data)をすべて、コンポーネントの @model 引数に渡しています。

  3. api.decorateWidget を使用して、post:after の位置に新しいウィジェットシムをレンダリングします。あなたの場合は、最初の投稿にのみ表示したいので、次のようなことができます。

    api.decorateWidget("post:after", (helper) => {
      if (helper.widget.model.post_number === 1) {
        return helper.attach("my-widget-shim");
      }
    });
    

トピックページを最終的にGlimmer化する際には、ウィジェットシム/デコレーションを削除し、プラグインアウトレットに置き換える必要があります。これは比較的簡単でしょう。コンポーネント内のすべての表示ロジックは、プラグインアウトレットで再利用可能になります。

どのように進んだか教えてください!フォローアップの質問があれば喜んでお手伝いします。多くの要素が絡み合っていることは承知しています。

「いいね!」 3

もう一歩です!

問題は、コンポーネントに currentUser が必要で、それを渡す方法がわからないことです。うまくいかないのは次のとおりです。

import { hbs } from "ember-cli-htmlbars";
import { withPluginApi } from "discourse/lib/plugin-api";
import Site from "discourse/models/site";
import { registerWidgetShim } from "discourse/widgets/render-glimmer";
import Banner from "../components/banner";

export default {
  name: "initialize-banner-widget",
  initialize(container) {
    registerWidgetShim(
      "geo-banner-widget",
      "div.widget-connector",
      hbs`<Banner @currentUser={{currentUser}} />`
    );

    // withPluginApi("0.1", (api) => {
    //   console.log("doing plugin");
    //   api.decorateWidget("post:after", (helper) => {
    //     return helper.attach("geo-banner-widget", helper.widget.model);
    //   });
    // });

    withPluginApi("0.1", (api) => {
      const currentUser = container.lookup("service:current-user");
      api.decorateWidget("post:after", (helper) => {
        console.log(`decorate widget ${currentUser.username}`, );
        if(helper.widget.model.post_number === 1){
          return helper.attach("geo-banner-widget", { currentUser });
        }
      });
    });
  },
};
「いいね!」 1

Banner コンポーネントでは、currentUser サービスを次のように注入できます。

class Banner extends Component {
  @service currentUser;
}

これにより、ウィジェットから渡す必要がなくなります。

「いいね!」 2

currentUser を渡すのは愚かだとわかっていたが、それを見つけられなかった!

他の部分で、誰かがこれを見つけて役に立つかもしれないという、可能性は低いが、それは

import Service, { inject as service } from "@ember/service";
import { hbs } from "ember-cli-htmlbars";
import { withPluginApi } from "discourse/lib/plugin-api";
import { registerWidgetShim } from "discourse/widgets/render-glimmer";

export default {
  name: "initialize-banner-widget",
  initialize(container) {
    registerWidgetShim(
      "geo-banner-widget",
      "div.widget-connector",
      hbs`<Banner/>`
    );

    withPluginApi("0.1", (api) => {
      api.decorateWidget("post:after", (helper) => {
        const currentUser = container.lookup("service:current-user");
        if (helper.widget.model.post_number === 1) {
          return helper.attach("geo-banner-widget");
        }
      });
    });
  },
};

はい!

この場合、Service クラスをインポートする必要はないと思います。それは、独自のServiceを作成する場合にのみ必要になります。service インジェクションデコレータが必要なだけです。

そして、Discourse/Ember の最新バージョンでは、‘inject as’ エイリアスを必要としないように、さらに簡略化できます。Ember は現在、インジェクションデコレータを service として直接利用できるようにしています。

import { service } from "@ember/service";

(ただし、古い { inject as service } も引き続き機能します。Ember での廃止計画については知りません)

編集:しかし、プラグインのアウトレットの代わりに decorateWidget を使用できるかもしれません。 . .

「いいね!」 1

リンターもそう考えているようです :slight_smile:

こちらの方が良いですね。ハウス広告プラグインはまだ古い方法で行っています。 :slight_smile:

「いいね!」 1

このトピックは、最後の返信から30日後に自動的にクローズされました。新しい返信は許可されていません。