为模板和JS API 现代化内联脚本标签

再次您好,非常感谢您的回复!

这是当前正在使用的、已弃用的代码,我将其粘贴到主题组件的 \u003chead\u003e 部分。还有一些支持性的 CSS,但这在这里不是问题。

<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
  const firstPost = helper.attrs.firstPost;
  const h = helper.h;
  if (firstPost) {
        let images = new Array();
        let goTo = new Array();
        
/////////////////////////////////
        let imageCount = 2;
        images[0]="/uploads/3213123123123213.jpg";
        goTo[0]="https://example1.com";
        images[1]="/uploads/djdsalklkjdsajsalkd.jpg";
        goTo[1]="https://example2.com";
/////////////////////////////////
        
        imageCount-=1;
        let randPick = Math.round(imageCount * Math.random());
        let theLink = goTo[randPick];
        let theImage = images[randPick];

    return h("div.p3-image", [
      h(
        "a.p3-image-link",
        { href: theLink,  target: "_blank" },
        h("img", { src: theImage})
      )
    ]);
  }
});
</script>

我一直在搜索并尝试使用现代方法实现类似功能的代码片段,这是我目前设法在 JS 选项卡中运行的代码:

import Component from "@glimmer/component";
import { withPluginApi } from "discourse/lib/plugin-api";

function customizePost(api) {
  api.renderAfterWrapperOutlet(
    "post-article-content",
    class extends Component {
      static shouldRender(args) {
        return args.post?.post_number === 1;
      }

      <template>Hello is this working? Yes but CSS divs are needed...</template>
      
    }
  );
}

export default {
  name: "not-sure-if-I-need-this",
  initialize() {
    withPluginApi((api) => {
      customizePost(api);
    });
  }
};

尝试以下方法:

import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.renderAfterWrapperOutlet(
    "post-article-content",
    class extends Component {
      @tracked imageSrc = "";
      @tracked imageHref = "";

      constructor() {
        super(...arguments)
        this.randomImageLink();
      }

      static shouldRender(args) {
        return args.post?.post_number === 1;
      }
      
      randomImageLink() {
        let images = new Array();
        let goTo = new Array();
        
        /////////////////////////////////
        let imageCount = 2;
        images[0]="/uploads/3213123123123213.jpg";
        goTo[0]="https://example1.com";
        images[1]="/uploads/djdsalklkjdsajsalkd.jpg";
        goTo[1]="https://example2.com";
        /////////////////////////////////
        
        imageCount-=1;
        let randPick = Math.round(imageCount * Math.random());
        this.imageSrc = goTo[randPick];
        this.imageHref = images[randPick];
      }

      <template>
        <div class="p3-image">
          <a href={{this.imageHref}} target="_blank">
            <img src={{this.imageSrc}} />
          </a>
        </div>
      </template>
    }
  );
});

您可能需要稍微调整一下,我还没有完全测试过。

2 个赞

抱歉回复慢了,我最近有点忙。

太棒了!它奏效了,只是这两行写反了:

        this.imageSrc = images[randPick];
        this.imageHref = goTo[randPick];

我需要学习一下 @tracked 是什么(我甚至不知道该怎么称呼它,是“被追踪的变量”吗?),以及那个 constructor 方法。我也不太明白 shouldRender 方法是如何以及在哪个时间点运行的。

非常感谢您的帮助,要我自己发现这些方法是不可能的。

2 个赞

您可以在此处阅读有关跟踪属性的更多信息。

我相信 shouldRender 在一开始就会运行,因为它决定了模板是否可见。

很高兴能帮到您!

2 个赞
<script type="text/x-handlebars" data-template-name="/connectors/discovery-list-container-top/moe-counter-banner">
  <div class="moe-counter-container">
    <img 
      src="https://moe.8845.top/get/?name=Monika&theme=booru-helltaker" 
      alt="访客计数器" 
      class="moe-counter-img"
    >
  </div>
</script>

我应该怎么写这个?我也是新手。

试试这个:

api.renderInOutlet(
  "discovery-list-container-top",
  <template>
    <div class="moe-counter-container">
      <img 
        src="https://moe.8845.top/get/?name=Monika&theme=booru-helltaker" 
        alt="Visitor Counter" 
        class="moe-counter-img"
      >
    </div>
  </template>
);

参见:

2 个赞

4 个帖子已拆分到新主题:迁移后调试页面更改 API

最新版本的 Discourse 中已移除对这些内联脚本标签的支持

2 个赞