מזהה נושא כמשתנה?

A common word is the opposite of what I want. I don’t want my search results to have EVERY ticket, I want a way to search for a specific ticket. That’s why topic ID would be ideal. They are automatically generated and unique.

No, I think the code I’m using was also awesomerobot’s originally, but I can’t seem to find it’s source anymore.
I prefer the placement of what I’m currently using better than that block under the text.

Well, I can’t do that. Maybe you can.
<Liam Neeson voice>I have a certain set of skills. Coding isn't among them.</Liam Neeson voice>

Then perhaps you should move this topic to Marketplace or Feature.

לייק 1

You misunderstand me. I meant having a common word including the topic:id parameter, so that only results from that topic show up. The common word removes the need to change words like ‘hi’ and ‘hello’.

@tknospdr @pfaffman I cobbled together a quick component that allows you to input the topic id and jump to it.

Create a new component, and add this to the JS tab under the Edit CSS/HTML button[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>
        }
    );
});

This adds an input to the Search page:


The Submit button is to go to the topic[2]; it does not affect search results.

Hope this helps!


  1. My first time using FormKit, it’s really cool! ↩︎

  2. I couldn’t change the button text, as that would require locales… which would need a whole TC repo, which might be overkill :person_shrugging:. ↩︎

לייק 1

Thanks @NateDhaliwal, I appreciate the effort.
I created the component, pasted the code under the JS tab. Made sure it was active on my theme, but no love.
This is what my search page looks like:

לייק 1

I set this up on my site to play around with and it does seem to work, however, I get this warning which gives me some pause:

האם יש שגיאות בקונסול הדפדפן?

This is the only error:

And I think that is for the JS to show the topic ID, not the search. It doesn’t show up except on the pages I earmarked for that element.

I disabled, then re-enabled the Advanced Search Banner component, and now it’s working.
:man_shrugging:

לייק 1

Alright, so a summary of the situation as it currently stands:

  1. We have a working solution. Although it’s slightly inelegant, it will suit my needs until such time as we can search for topic ID right in the standard search box.
  2. The current code suggested by @awesomerobot appears to work, but triggers the warning I posted above.
    2a. When I removed the original code I was using to display the topic ID, this warning went away…
  3. When you choose a solution, the code to display the topic ID shows up both in the original post, and in the solution, is there a way to account for that and repress it from showing there?
  4. I fancied up the CSS a little more, now I have a pill on every reply in every thread in the specified categories I’m using this in. I suppose the answer will be to un fancy it, but if anyone knows another way I’d rather keep it, I think it looks nice as is.

@awesomerobot
הקוד שלך עובד מצוין, אבל נראה שכל קישוט CSS מלבד טקסט מופיע בכל פוסט אחרי הראשון כרווח ריק מעוצב כפי שה-CSS אומר.

כבה את ה-inline block ותקבל פס צבע ברוחב מלא.
שנה את צבע הרקע והכדורית משנה צבע
וכו’…

בהתבסס על מה שכתבת, נראה שאמרת לו להופיע רק בפוסט הראשון, אבל זה משפיע רק על הטקסט. האם יש משהו אחר שאנחנו יכולים לעשות כדי להרוג את האלמנט בכל הפוסטים הנוספים?

לייק 1

בסדר, כפי שאמרתי, אני לא מתכנת, אבל אני מעולה בלשאול שאלות את Grok. הנה קוד שמטפל בשתי הבעיות.

  1. אין יותר בועות CSS ריקות בתשובות 2 עד X.
  2. אין יותר כפילות של מזהה נושא בפתרונות מצוטטים.

אולי אף אחד אחר על פני כדור הארץ לא אכפת לו, אבל זו נראית דרך טובה לעזור לעקוב אחר נושאים עבור אלה מאיתנו שמשתמשים ב-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]; // רשימה מופרדת בפסיקים של מזהי קטגוריות שברצונך שהדבר יופיע בהם
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- ניתן לערוך את התוכן למטה, {{this.topicId}} הוא המקום שבו ימולא מזהה הנושא -->
      מעקב אחר בעיות # הוא
      {{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]; // רשימה מופרדת בפסיקים של מזהי קטגוריות שברצונך שהדבר יופיע בהם
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- ניתן לערוך את התוכן למטה, {{this.topicId}} הוא המקום שבו ימולא מזהה הנושא -->
      מעקב אחר בעיות # הוא
      {{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 האלה ברכיב משלהם, או שזה חייב להיות בערכת הנושא עצמה?

I found another small anomaly. I was seeing the empty class bubbles in the first post of topics outside of the 2 I wanted them in so I had to update the code a little. Here’s the final product.

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; // first post in topic
    const desiredCategories = [9, 23]; // a comma separated list of category IDs you want this to appear in 
    const isInCategory = desiredCategories.includes(
      this.args.post?.topic.category.id
    );

    return firstPost && isInCategory;
  }

  <template>
    {{#if this.shouldShow}}
      <!-- you can edit the content below, {{this.topicId}} is where the topic ID will be filled -->
      Issue Tracking # is
      {{this.topicId}} 
      <!-- you can edit the content above -->
    {{/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);
  });
});

And to answer my own question, I moved all the code to a new theme component and it all still works fine.