pfaffman
(Jay Pfaffman)
1
我有一个 Glimmer 组件。它能正常工作。但我需要它出现在主题的第一个帖子之后。那里没有插件出口。
我确实找到了在 <article> 标签的 innerHTML 中插入一些文本的方法,这能将文本放在我想要的位置,但似乎没有办法用组件做到这一点。
我是否遗漏了什么?
我查看了 adplugin 在帖子之间插入广告的方式,但没能完全理解。
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);
});
});
....
david
(David Taylor)
2
我们来添加一个!您希望放在哪里?
(有遗留的方法可以完成您正在做的事情,但当我们现代化主题视图时,它们会中断。如果我们添加一个插件出口,它将更具未来性)
2 个赞
david
(David Taylor)
3
此插件将匹配 decorateWidget("post:after 的功能,这也是 adplugin 使用的功能:
3 个赞
pfaffman
(Jay Pfaffman)
4
太棒了!抱怨一下,你就能得到!
实际上,我知道添加插件插座很容易,但当我曾经知道如何添加它们时,是在一个 hbs 文件中。
这会出现在每篇帖子之后吗?所以我需要想办法让它只出现在第一篇之后?
article:after 是我之前尝试中想出的办法。
1 个赞
david
(David Taylor)
5
帖子作为 outlet 参数之一传递,因此您可以检查 post.post_number == 1
哈哈!很高兴能回答这类问题。主题和插件使用标准 API 而不是 widget 变通方法(这些方法将在不久的将来被弃用)对每个人来说都更好。
是的,这很公平。在核心方面,在 widget 中添加它们很麻烦。但从主题/插件方面来看,它应该非常干净 
我会尝试弄清楚那些测试失败的原因,并在明天合并 PR。(看起来额外的 html 元素会干扰 qunit 测试中一些脆弱的选择器)
2 个赞
pfaffman
(Jay Pfaffman)
6
啊哈!@outletArgs={{hash post=@data.post}}。我很有可能能弄清楚怎么做。
再次感谢!
2 个赞
david
(David Taylor)
7
恐怕我在这里有点过于乐观了,@pfaffman,抱歉!我提交的 PR 会在每个帖子之间引入一个新的包装器 <div>,即使该插槽未被使用。这并不是我们真正想要做的。
或许有办法避免这个包装器……但没有什么简单的方法可以立即做到。
所以,我认为对你来说,最好的直接解决方案是复制你在 OP 中引用的 adplugin 实现。
基本上:
-
创建一个组件(Glimmer 或经典,无所谓),它渲染你想要的任何内容
-
使用 registerWidgetShim 使该组件可用作一个小部件。adplugin 示例正在创建一个名为“after-post-ad”的小部件,它渲染 PostBottomAd 组件。它将所有小部件属性 (@data) 传递到组件的 @model 参数中。
-
使用 api.decorateWidget 在 post:after 位置渲染你的新小部件 shim。在你的例子中,如果你只想在第一个帖子显示,你可以这样做:
api.decorateWidget("post:after", (helper) => {
if (helper.widget.model.post_number === 1) {
return helper.attach("my-widget-shim");
}
});
当我们最终将主题页面 Glimmer 化时,你需要移除小部件 shim/装饰,并用插件插槽替换它。这应该相当容易,因为你在组件中的所有显示逻辑都可以在插件插槽中重用。
让我们知道你的进展!很乐意帮助解答任何后续问题——我知道这里有很多活动部件。
3 个赞
pfaffman
(Jay Pfaffman)
8
我非常接近了!
唯一的问题是组件需要 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 个赞
david
(David Taylor)
9
在您的 Banner 组件中,您可以这样注入 currentUser 服务:
class Banner extends Component {
@service currentUser;
}
这样您就不需要从 widget 传递它了。
2 个赞
pfaffman
(Jay Pfaffman)
10
我知道传递 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");
}
});
});
},
};
david
(David Taylor)
12
是的!
在这种情况下,我认为您不需要导入 Service 类。只有在创建自己的服务时才需要它。您只需要 service 注入装饰器。
在最新版本的 Discourse/Ember 中,可以进一步简化,以避免需要“inject as”别名。Ember 现在可以直接将注入装饰器作为 service 提供。
import { service } from "@ember/service";
(但旧的 { inject as service } 仍然有效,而且据我所知,Ember 没有任何计划弃用它)
编辑:但也许我可以使用 decorateWidget 而不是插件出口。。。
1 个赞
pfaffman
(Jay Pfaffman)
13
linter 也这么认为 
我更喜欢这样。house ads 插件仍然是旧的方式。
1 个赞
pfaffman
(Jay Pfaffman)
关闭
14
此主题在最后回复后自动关闭,已有 30 天。 不再允许回复。