Separating Pinned Topics

Hello!

I’m not exactly sure how to go about doing this and was looking for a bit of assistance.

Basically, I’d like to have visual separation between the pinned topics and regular topics. This would be for a game studio’s community forums and that separation would be helpful for the users.

What I’m looking for is something like this:

[PINNED] Topic Name

Regular topic

Instead of:

[PINNED] Topic Name
Regular topic

I’ve already changed the background colour of the pinned topics to create a slight difference between the two. I’ve tried CSS, which has worked, but only on a page refresh.

I’ve attempted creating my own theme component, but that’s where I’m getting stuck as I’d need to add something, but I’m not sure where.

My goal is to add before the original (regular topics) tbody.

Any guidance is greatly appreciated!

1 Like

You can look into using the Filtered Topic Lists theme component with the in:pinned query.

If you instead want to stick to CSS, you can do something like this:

// target the last pin in the list
tr.topic-list-item.pinned:has(+ tr:not(.pinned)) td {
  // rough way to force space inside a table row
  padding-bottom: 1.8em;
}

tr.topic-list-item.pinned:has(+ tr:not(.pinned))::after {
  // content to display in the space if wanted
  content: 'regular';
  width: 100%;
  position: absolute;
  display: flex;
  height: 1em;
  left: 0;
  right: 0;
  bottom: 0;
  justify-content: center;
  border-top: 1px solid var(--primary-low);
}
5 Likes

Thanks for the help! Unfortunately, that didn’t work. I do have an attempt at a plugin that should do what I need it to do, but I can’t seem to get it working on Discourse 3.4.0-beta2.

Any assistance with this would be greatly appreciated!

Hey Terise,

I looked at your code, and you’re close!

Here are some feedbacks:

This means this should be:

export default class PinnedTopicBody extends Component {
  get pinnedTopics() {
    return this.outletArgs.topics.filter((t) => t.get("pinned"));
  }
}

and the template:

{{#if this.pinnedTopics}}
  <tbody class="pinned-topics">
    {{#each this.pinnedTopics as |topic|}}
      <TopicListItem
        @topic={{topic}}
        @bulkSelectEnabled={{@outletArgs.bulkSelectEnabled}}
        @lastVisitedTopic={{@outletArgs.lastVisitedTopic}}
        @selected={{@outletArgs.selected}}
        @hideCategory={{@outletArgs.hideCategory}}
        @showPosters={{true}}
      />
    {{/each}}
    <tr class="table-break">
      <td colspan="10">&nbsp;</td>
    </tr>
  </tbody>
{{/if}}
import { classNames, tagName } from "@ember-decorators/component";

@tagName("tbody")
@classNames("pinned-topics")
export default class PinnedTopicBody extends Component {
  ...
}
{{#if this.pinnedTopics}}
  {{#each this.pinnedTopics as |topic|}}
    ...
  {{/each}}
  <tr class="table-break">
    <td colspan="10">&nbsp;</td>
  </tr>
{{/if}}

image

(if you know you will do nothing on the element, you can keep the tbody in the template and use tagName("")).

Then, you get this:

I did not thoroughly examine it to see if there was a better way.
I just wanted to help make your code work! :smile:

5 Likes

Would I need anything in the components directory or would all the files reside in connectors?

The only reason I was doing this as a plugin instead of a Theme Component is because I have plans to add more functionality later on.

You don’t need the components directory here in this connector and code context.
You can see it in my screenshot because I modified an existing component. :smile:

That said, it depends on what you want to do later. It’s also possible to create a component in the connector that refers to another component (and this one, you would place it in components directory).

1 Like

That’s perfect, thank you so much!

I do have one last question, if you don’t mind. Is there a way to stop the pinned topics from appearing in the normal topic list so that the pinned topics aren’t duplicated?

Edit: I was actually able to do that with a bit of CSS.

Again, thank you so much for your help!

1 Like