Can't add new class to topic page elements using jQuery?

I’m struggling to learn more about how discourse works and I’m still confused after reading this. I’m trying to add a dynamic title to the admin’s username on the post page using jQuery but is not working.

But if I’ll target let’s say the body tag, and add a class, it works.
So can somebody please explain why is not working?
The code is inserted in the header tab btw.

<script>
  $(".names span.admin a").attr('title', 'Community Admin');
</script>

Do I need to inject this in a plugin outlet or something?

Probably because in this case jQuery is not playing nicely with the Ember & Widget rendering pipeline.

You see in this script, you have no control over when this fires and in relation to where the javascript app has got to whilst drawing the screen.

There’s an javascript api method for this though, see more here:

decorateWidget()

And this specific widget:

https://github.com/discourse/discourse/blob/015ea287785dacfa1866e677a49f2edf177e1e8f/app/assets/javascripts/discourse/app/widgets/poster-name.js#L37

However, before you go down that rabbit hole, let’s back up a bit, do you just want a Title to be shown?

e.g. on Jeff’s posts:

image

He has title: “co-founder”

Just create a new Group, add the Admins, go to Manage => Membership and edit the Default Title.

Now they can select this Title in their account settings in Preferences (or you can do that for them).

You can also use this to show a special Avatar flair (also demostrated by the above screen clip).

Obviously if you don’t want this so “fixed” you will have to look at the coding route, but this, I’m sure you’d agree, is a lot less effort

5 Likes

Thanks for your help. Not the actual forum title I’m looking for but to display a title on hover on this little crown icon I made ( visible only for admins ):
image

Btw the CSS code for this is:

.names span.admin a::after {
content: "";
width: 17px;
height: 14px;
margin-left: 5px;
background-image: url(https://www.dropbox.com/s/0oi0y3ex3rtfvk5/cd-crown.svg?raw=1);
background-repeat: none;
display: inline-block;
position: relative;

Nice.

Sounds like you might want to consider the widget route.

Also consider this api method:

api.reopenWidget("poster-name", {

      html() {
          <<your-code-here-but-consider-using-the-original-as-template>>
      }
}

I would recommend you look at: A tour of how the Widget (Virtual DOM) code in Discourse works

It’s significantly more effort to do this kind of thing in Discourse because it is an auto-magical-web-app, but once you do it right, the solution can be very robust.

5 Likes

Awesome, thanks a lot. I’ll take a look and post the solution if I’ll succeed. At first sight, Discourse looks so scary when it comes to customizing, and I thought WordPress is difficult :smile: .But, for sure once I’ll get familiar with all this plugins-templates thing, I guess it will become easier.

Actually, boom, there might be an even easier solution:

Consider this api method to swap out the normal moderator shield:

 api.replaceIcon('shield-alt', 'crown');

and then change the text of the tooltip here:

At which point, your original CSS is potentially redundant (though you can re-color the icon)

3 Likes

But this will remove the shield icon for moderators, right? Cause I don’t want that. I need to add that crown icon and the hovering text only for admins since they don’t have any at all on the posts page.

1 Like

Ah, yeah, I’m too used to my sites where I’m both a mod and an admin. If you split these roles that won’t work (ie Admin’s are never mods). You’d need to give Admins mod rights.

So explore the other options.

1 Like

Try this:

api.reopenWidget("poster-name", {
  posterGlyph(attrs) {
    if (attrs.moderator || attrs.groupModerator) {
      return iconNode("shield-alt", {
        title: I18n.t("user.moderator_tooltip"),
      });
    };
    if (attrs.admin) {
      return iconNode("crown", {
        title: I18n.t("user.admin_tooltip"),
      });
    }
  }
})

and

works for me:

In this case the first user is both admin and mod, second is just admin. You can embellish that logic; make the crown take precedence by switching the order of the if statements.

1 Like

Sounds like a solution but as I said I’m new to customizing Discourse…can you please explain where exactly do I need to paste your code cause I didn’t try any API method so far.

… give me a second, I’ll build this properly for you

Ok, this is now a Theme Component:

https://github.com/merefield/discourse-tc-staff-icons

(How do I install a Theme or Theme Component?)

Admin role takes precendence - by default a crown will show for an admin who also has moderator role.

You can now configure the icon by staff type.

image

Just make sure you add the icon names to the svg icon subset setting (or it won’t show):

Customize your title text here:

similarly for the moderator.

5 Likes

Awesome :slightly_smiling_face:. Thank you so much for your help!

pleasure (that one was quite fun!)

2 Likes

I’ve updated the TC so it now changes the staff icons on the User Card too (and possibly other places since I’ve modified the helper).

The icons are now configurable for both the admin and the moderator, though crown is the default for admin whilst moderator’s default is vanilla shield.

I’ve renamed the TC.

There are bound to be places where the icons are not converted, perhaps I’ll catch more in the future.

3 Likes

Thank you so much! This helped me with what I wanted to do for my Forum! I think your comment should be pinned for other users that are having issues with an icon displaying next to their name as an Admin. I used your feature to display the shield icon that is publicly shown on Moderators profile for Admins. Now, I can have the shield Icon without having Moderator Permissions and it has the correct Admin Tooltip when I only have the Admin Permissions. Thank so much for your time to create this Awesome component for people’s forums!

Edit: It does Not show publicly on their profile. It’s currently only working on posts.

1 Like

Pleasure. Feel free to fork, extend and PR!

2 Likes