Display Group Badge On Topic List?


  • Hello,

    I'm trying to create a plugin that shows the group badge next to the username on the topic list. It's very similar to this, but on the topic list.

    Thank you in advance!


  • EDIT:

    I'm trying to create a plugin that shows the group badge next to or below the topic name. The idea is to notify the readers that a 'dev' or 'admin' has posted/responded to the topic.

    Are there any plugins available that can do this? Is it possible to create?

    Thank you in advance!

  • Gamers Admin

    This shouldn't be hard to do, listen for filter:topics.get and then load the users groups into the user object. Once that is done you can display them on partials/topics_list.tpl

    myPlugin.filterTopicsGet = async function (hookData) {
      const uids = hookData.topics.map(t => t.uid);
      const userGroups = await Groups.getUserGroups(uids);
      hookData.topics.forEach((t, i) => {
          t.user.groups = userGroups[i];
      });
      return hookData;
    };
    

    This would create a groups variable on every user object which you can access in the template.


  • @baris Thank you for this. I can now see the groups variable for users listed on the topics page. I do have a follow up question. Is there a way for us to access all posts (including users) in a topic from the topics page? Our goal is to dynamically place a badge under the topic title to indicate that a dev had posted/replied in the topic.

  • Gamers Admin

    @Teemberland For this you can use the sorted set tid:<tid>:posters it contains all uids who have posted in the topic (including the OP) and the score is the number of posts they have in that topic. So you need to grab the uids from this sorted set and check if any of the uids are in a dev group.


  • @baris great! I'll give this one a shot!


  • @baris thank you for your suggestion. I can get the posters now, but I'm not able to get their groups. Here's my code. Can you tell me what I'm missing here?

    var db = require.main.require('./src/database');
    
    theme.filterTopicsGetDevActivity = async function(hookData) {
      hookData.topics.forEach((t, i) => {
        db.getSortedSetRange('tid:' + t.tid + ':posters', 0, -1, function (err, uids) {
          t.foobar = uids;
        });
      });
      return hookData;
    }
    

    Here's my hook:

    {
      "hook": "filter:topics.get",
      "method": "filterTopicsGetDevActivity"
     }
    

    My template:

    <!-- IF topics.foobar.length -->
      <!-- BEGIN topics.foobar -->
        {topics.foobar}
      <!-- END topics.foobar -->
    <!-- ENDIF topics.foobar.length -->
    

    I tried using {topics.foobar.groups.slug} to display the group name, but the object becomes empty.

    0C69C8F1-2645-4727-9FAF-1FB311D185AF.png

  • Gamers Admin

    Your code is only getting the uids who have posted in the topic it is not loading any group data. It is also loading the uids in a foreach which won't work as you expect it. You need to use promises and assign the data once the call is complete.

    You want something like below, adjust as necessary.

    myPlugin.filterTopicsGet = async function (hookData) {
      const groupData = hookData.topics.map(async (t) => {
           const uids = await db.getSortedSetMembers('tid:' + t.tid + ':posters'));
           const userGroups = await Groups.getUserGroupMembership('groups:createtime', uids);       
           return userGroups.flat().includes('My developer group');
      });
    
      hookData.topics.forEach((t, i) => {
          t.postedInByDeveloper = groupData[i];
      });
      return hookData;
    };
    

  • @baris thank you! I think we're very close. When I call postedInByDeveloper in my template {topics.postedInByDeveloper} I get an [object Promise] in view.

    I also tried making an api call in the console to check the object and found that postedInByDeveloper is empty. See screenshot below.

    Screen Shot 2020-07-07 at 14.27.20 PM.png

  • Gamers Admin

    I was writing the code of the top of my head so it had errors, this should work I think.

    myPlugin.filterTopicsGet = async function (hookData) {
      const groupData = await Promise.all(hookData.topics.map(async (t) => {
           const uids = await db.getSortedSetMembers('tid:' + t.tid + ':posters');
           const userGroups = await Groups.getUserGroupMembership('groups:createtime', uids);       
           return userGroups.flat().includes('My developer group');
      }));
    
      hookData.topics.forEach((t, i) => {
          t.postedInByDeveloper = groupData[i];
      });
      return hookData;
    };
    

  • @baris I had to update to 1.14.x to get access to getSortedSetMember. I didn't know that this method was new. Also, I had to use a different method for flat() since I'm on the older version of node locally.

    Thank you once again for all your help!

Suggested Topics

| |