您好,我正在尝试将一个图片横幅添加到所有页面,该横幅会从两张随机图片中随机选择一张。当我将其添加到主题的Head部分并强制重新加载主页时,它就能正常工作:
编辑: 我更接近解决方案的尝试在这里:
您知道我哪里做错了吗?谢谢!
您好,我正在尝试将一个图片横幅添加到所有页面,该横幅会从两张随机图片中随机选择一张。当我将其添加到主题的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>
我认为缺失的一环是触发小部件重新渲染……如果我没记错的话,小部件会在交互时重新渲染,所以我添加了 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 })
)
]);
}
});
太棒了!非常感谢,我绝对想不到这一点!
这是主题组件完整的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>
值得一提的是,这也可以是一个 Ember 组件。从长远来看,我们将更多地依赖 Ember 而不是我们自定义的小部件系统。我们仍在处理 Ember 更新,因此我们关于自定义 Discourse 的文档在这方面有点滞后。
我整理了一个主题组件,展示了这如何作为 Ember 组件工作的示例:GitHub - awesomerobot/discourse-component-example
这里有 3 个重要的文件:
连接器(/javascripts/discourse/connectors/custom-header-banner-connector.hbs)
组件(/javascripts/discourse/components/custom-header-banner.js)
组件的模板(/javascripts/discourse/templates/components/custom-header-banner.hbs)
连接器是添加组件的地方,所以它只需要包含 <CustomHeaderBanner />。组件是我们检测页面更改(路由更改)并设置哪个图像/链接随机出现逻辑的地方。组件的模板是如何在 HTML 中呈现数据。
好的,很高兴知道,也非常感谢。我确认在我的网站上将其作为主题组件从您的存储库安装时,它确实有效。
另外,我是否可以通过“自定义 > 安装 > 创建新”界面,然后“编辑 CSS / HTML”手动将其添加为 Ember 主题组件?这样可以更轻松地根据需要快速更改图像和链接。我假设 custom-header-banner.js 的内容会放在“Head”下,然后 \u003cCustomHeaderBanner /\u003e 放在“After Header”或“Body”下,但不确定在哪里添加 custom-header-banner.hbs 的内容。
将其翻译成本地安装的主题组件要复杂一些,但为远程主题添加一些灵活性的一种方法是使用主题设置(https://meta.discourse.org/t/add-settings-to-your-discourse-theme/82557)。
这涉及到添加一个 settings.yml 文件(https://github.com/awesomerobot/discourse-component-example/blob/main/settings.yml`),并更新组件和/或模板中的一些值。然后,您将在主题组件管理页面上看到如下设置:
使用上面的 widget 实现并通过管理面板进行更新也是可以的,但我们倾向于建议尽可能使用 git;如果需要进行故障排除,它更容易共享,并且可以轻松跟踪您的更改。
太好了,非常感谢您耐心清晰的解释,很高兴也有这个选项。
你好,我又来了,我正在尝试找出一种最佳方法,只在特定 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.