主题ID作为变量?

一个常见的词正是我不想要的。我不想让我的搜索结果包含所有工单,而是想找到一种搜索特定工单的方法。这就是为什么主题 ID 是理想的。它们是自动生成且唯一的。

不,我认为我正在使用的代码最初也是 awesomerobot 的,但我似乎找不到它的来源了。
我更喜欢我当前使用的代码在文本下方的放置方式,而不是那个代码块。

好吧,我做不到。也许你能做到。
“我有一套特定的技能。编码不属于其中。”

那么也许你应该把这个话题移到 Marketplace#feature。

1 个赞

你误会我的意思了。我的意思是,在搜索词中包含 topic:id 参数,这样就只会显示该主题中的结果。常用词可以省去更改“hi”和“hello”这类词的麻烦。

@tknospdr @pfaffman 我拼凑了一个快速组件,允许您输入主题 ID 并跳转到它。

创建一个新组件,并在“编辑 CSS/HTML”按钮下的 JS 选项卡中添加此内容[1]

import { apiInitializer } from "discourse/lib/api";
import Component from '@glimmer/component';
import { action } from "@ember/object";
import Form from "discourse/components/form";
import DiscourseURL from "discourse/lib/url";

export default apiInitializer((api) => {
    api.renderBeforeWrapperOutlet("full-page-search-filters",
        class GoToTopic extends Component {
            @action
            handleSubmit(data) {
                DiscourseURL.routeTo(`/t/${data.id}`);
            }

            <template>
                <div class="topic-id-go-to" style="margin-top: 1em;">
                    <Form @onSubmit={{this.handleSubmit}} as |form|>

                      <form.Field @name="id" @title="Topic id" as |field|>
                        <field.Input @type="number" @validation="required" />
                      </form.Field>

                      <form.Submit />
                    </Form>
                </div>
            </template>
        }
    );
});

这会在搜索页面添加一个输入框:


“提交”按钮用于转到主题[2];它不会影响搜索结果。

希望这对您有帮助!


  1. 我第一次使用 FormKit,它真的很酷! ↩︎

  2. 我无法更改按钮文本,因为这需要本地化… 这将需要一个完整的 TC 存储库,这可能有点过头了 :person_shrugging:. ↩︎

1 个赞

感谢 @NateDhaliwal,我非常感谢您的努力。
我创建了该组件,将代码粘贴到了 JS 选项卡下。确保它在我的主题上处于激活状态,但没有效果。
这是我的搜索页面的样子:

1 个赞

我在我的网站上设置了这个来玩,它似乎确实有效,但是,我收到了这个警告,这让我有些犹豫:

浏览器控制台中是否有任何错误?

这是唯一的错误:

我认为这是因为 JS 显示了主题 ID,而不是搜索。它只显示在我为该元素标记的页面上。

我禁用了“高级搜索横幅”组件,然后重新启用了它,现在它起作用了。
:man_shrugging:

1 个赞

好的,这是目前情况的总结:

  1. 我们有一个可行的解决方案。虽然它有点不够优雅,但它能满足我的需求,直到我们能够直接在标准搜索框中搜索主题 ID。
  2. @awesomerobot 建议的当前代码似乎有效,但会触发我上面发布的警告。
    2a. 当我删除用于显示主题 ID 的原始代码时,此警告消失了……
  3. 当您选择一个解决方案时,用于显示主题 ID 的代码会同时出现在原始帖子和解决方案中,有没有办法解决这个问题并阻止它在那里显示?
  4. 我对 CSS 做了一些美化,现在在我使用的指定类别中的每个帖子的每个回复上都有一个药丸状的标签。我猜答案是取消美化它,但如果有人知道其他方法,我宁愿保留它,我觉得它现在看起来不错。

@awesomerobot
您的代码效果很好,但看起来除了文本之外的任何 CSS 装饰都会在第一个帖子之后的每个帖子中显示为空白,并按照 CSS 的方式进行格式化。

关闭内联块,您将获得一个全宽的彩色条。
更改背景颜色,药丸会改变颜色
等等…

根据您的描述,您似乎告诉它只在第一个帖子中显示,但这只会影响文本。我们还能做些什么来在所有附加帖子中删除该元素吗?

1 个赞

好的,正如我所说,我不是程序员,但我很擅长向 Grok 提问。这是处理这两个问题的代码。

  1. 回复 2 到 X 中不再有空的 CSS 气泡。
  2. 引用的解决方案中不再重复主题 ID。

也许地球上没有人关心,但对于我们这些使用 Discourse 作为票务系统的人来说,这似乎是跟踪主题的好方法。

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

class TopicIdentifier extends Component {
  get topicId() {
    return this.args.post?.topic?.id;
  }

  get shouldShow() {
    const firstPost = this.args.post?.post_number === 1; // 主题中的第一个帖子
    const desiredCategories = [9, 23]; // 您希望其显示的类别 ID 的逗号分隔列表
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- 您可以编辑下面的内容,{{this.topicId}} 将填充主题 ID -->
      Issue Tracking # is
      {{this.topicId}}
      <!-- 您可以编辑上面的内容 -->
    {{/if}}
  </template>
}

export default apiInitializer("0.8.40", (api) => {
  api.decorateCookedElement((element, helper) => {
```gjs
import { apiInitializer } from "discourse/lib/api";
import Component from "@glimmer/component";

class TopicIdentifier extends Component {
  get topicId() {
    return this.args.post?.topic?.id;
  }

  get shouldShow() {
    const firstPost = this.args.post?.post_number === 1; // 主题中的第一个帖子
    const desiredCategories = [9, 23]; // 您希望其显示的类别 ID 的逗号分隔列表
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- 您可以编辑下面的内容,{{this.topicId}} 将填充主题 ID -->
      Issue Tracking # is
      {{this.topicId}}
      <!-- 您可以编辑上面的内容 -->
    {{/if}}
  </template>
}

export default apiInitializer("0.8.40", (api) => {
  api.decorateCookedElement((element, helper) => {
    // 仅当这是第一个帖子且不在解决方案引用中时继续
    // 仅当这是第一个帖子,不在引用中,并且在所需的类别中时继续
    const post = helper?.model;
    const desiredCategories = [9, 23]; // 匹配 TopicIdentifier 中的类别
    if (
    if (
      helper?.model?.post_number !== 1 ||
      !post ||
      post.post_number !== 1 ||
      !desiredCategories.includes(post.topic?.category?.id) || // 检查类别
      element.classList.contains("post__contents-cooked-quote") || // 检查元素本身是否是引用内容
      element.closest("aside.accepted-answer") || // 检查解决方案/引用包装器
      element.closest(".quote") // 对通用引用的附加检查
    ) {
      return;
    }

    const wrapper = document.createElement("div");
    wrapper.className = "tracking-id";

    helper?.renderGlimmer(
      wrapper,
      <template><TopicIdentifier @post={{helper.model}} /></template>
    );

    element.appendChild(wrapper);
  });
});
3 个赞

我没能早点处理这件事,但我很高兴你解决了!这看起来是一个合理的解决方案。

1 个赞

我知道我可以轻松地测试它,但您是否能立即告诉我,如果我将此 JS 和 CSS 放入其自己的组件中,它是否会起作用,还是必须放在主题本身中?

我发现了另一个小异常。我看到主题的第一个帖子中出现了空的类气泡,而不是我想要的两个,所以我不得不稍微更新一下代码。这是最终产品。

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

class TopicIdentifier extends Component {
  get topicId() {
    return this.args.post?.topic?.id;
  }

  get shouldShow() {
    const firstPost = this.args.post?.post_number === 1; // 主题的第一个帖子
    const desiredCategories = [9, 23]; // 你希望它出现的分类 ID 的逗号分隔列表
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- 你可以编辑下面的内容,{{this.topicId}} 将会填充主题 ID -->
      Issue Tracking # is
      {{this.topicId}}
      <!-- 你可以编辑上面的内容 -->
    {{/if}}
  </template>
}

export default apiInitializer("0.8.40", (api) => {
  api.decorateCookedElement((element, helper) => {
    // Only proceed if this is the first post and not inside a solution quote
    // Only proceed if this is the first post, not in a quote, and in the desired category
    const post = helper?.model;
    const desiredCategories = [9, 23]; // Match the categories from TopicIdentifier
    if (
    if (
      helper?.model?.post_number !== 1 ||
      !post ||
      post.post_number !== 1 ||
      !desiredCategories.includes(post.topic?.category?.id) || // Check category
      element.classList.contains("post__contents-cooked-quote") || // Check if the element itself is the quote content
      element.closest("aside.accepted-answer") || // Check for solution/quote wrapper
      element.closest(".quote") // Additional check for generic quotes
    ) {
      return;
    }

    const wrapper = document.createElement("div");
    wrapper.className = "tracking-id";

    helper?.renderGlimmer(
      wrapper,
      <template><TopicIdentifier @post={{helper.model}} /></template>
    );

    element.appendChild(wrapper);
  });
});
      element.classList.contains("post__contents-cooked-quote") || // Check if the element itself is the quote content
      element.closest("aside.accepted-answer") || // Check for solution/quote wrapper
      element.closest(".quote") // Additional check for generic quotes
    ) {
      return;
    }

    const wrapper = document.createElement("div");
    wrapper.className = "tracking-id";

    helper?.renderGlimmer(
      wrapper,
      <template><TopicIdentifier @post={{helper.model}} /></template>
    );

    element.appendChild(wrapper);
  });
});

为了回答我自己的问题,我将所有代码移到了一个新的主题组件中,它仍然可以正常工作。