Topic Ratings Plugin


(Angus McLeod) #1

Here’s something I started playing around with a little while ago and decided to spruce up this weekend. Please note the To do #1 (below).

Description

A Discourse plugin that lets you use topics to rate things.

  1. Topics can be designated as ‘for rating’, by being:

    1. posted in a category with ratings setting on (see below); or
    2. given the tag ‘rating’ (this requires the Discourse Tagging plugin).
  2. Each ratings topic concerns a single thing; e.g. a service or a product.

  3. Users rate by choosing a star rating when posting (i.e. in the composer).

  4. The average (mean) of all the ratings in the topic is displayed under the topic title and on the relevant topic list item.

  5. Exact topic rating averages can be toggled on/off with the Plugin setting ‘Show exact average rating’.

  6. If a topic has ratings and is subsequently moved to a non-ratings category, or has its ‘rating’ tag removed, the ratings are not deleted, but are hidden. Admins see the message ‘Topic has hidden ratings’ under the topic title.

To do

  1. Prevent a user from posting in a ratings topic more than once. Currently, users cannot rate in a ratings topic more than once.

  2. Created a sorted topic list (highest to lowest) of all topics within a ratings category or with the ‘rating’ tag. Perhaps use Bayseian estimation as discussed in the code comments.

  3. Add translations.

  4. Allow the user to select the tag(s) they wish to use to designate ratings topics in the admin config.

  5. Allow the user to choose the number of total stars in a rating.

  6. Allow the user to change the rating item image (i.e. use something other than stars).

  7. Add topic rating to page description in search results.

Some screenshots


Star Rating System
List of project ideas for Google Summer of Code 2016
Getting ratings plugin for discourse
Quick Messages Plugin
Topic List Previews
What determines the order of frequent poster icons in the topic list?
Displaying Star Rating in SERPs with Discourse
The best way to create aggregated metadata for a Topic based on its messages?
Basic Links Plugin
Topic of the week
Beginner's Guide to Creating Discourse Plugins - Part 1
(Angus McLeod) #2

Ok I’ve made a simple frontend exclusion of the ratings stars for users that have already posted in a ratings topic.

Ideally, I’d like to modify the topic and/or post guardians on the server to prevent a user from posting in a ratings topic twice. However, with my limited ruby skills, I can’t see an easy way to do this without just overriding the existing methods (assuming that’s possible this isn’t a very sustainable thing to do)… any ideas/tips? @sam

Relevant topic guardian method

Relevant post guardian method


(Régis Hanol) #3

We need to add plugin hooks here.


#4

Where is the button in the composer UI or for the finished post to rate the thread?
I have installed the plugin, given the thread the “rating” tag, and can see the empty stars at the top. But no button to actually rate it. :frowning: (Or must I use a non-admin account for that?)

EDIT: looked closely at the screenshots, and see that there is supposed to be a “Your rating” line there. Well, it’s missing in my instance.
Thought of a second reason this might not work: My instance is German. If the translation is missing…

Will create a test user and set his user interface to English. If it still does not work then something is broken.


#5

OK, mystery solved. As a normal user, I can answer even though my user interface is still in German.

Warn a guy about stuff like that, will ya! :wink:

(An option to allow admins to vote too would be honestly appreciated, though.)

Edit: Celebrated too early, its still broken.
I had the option to select stars on posting the initial reply. That did not affect the overall rating, though. And on editing the reply, the “Your rating” line is missing again. :frowning:
Switched the user interface of the test user to English - no change.

Help!?


(Angus McLeod) #6

@fackelwind Thanks for the feedback! I appreciate it. This precipitated a significant refactor to get it working as expected. In retrospect I’m surprised it worked before at all…

The only thing that doesn’t work now is the topic average will not get automatically updated for other users when a new user publishes a post with a rating or edits a rating in a post. Other users will see the updated rating on the new or updated post itself, but the topic average rating won’t update until those other users refresh. I will fix that soon.

Here’s a screencast demonstrating the functionality: http://quick.as/b1wbSOa9g

@zogstrip @riking Hey guys, could you give me some advice on the best way to push topic updates to other clients from the server? I’m pushing the post updates using the aptly named post method publish_change_to_clients which uses the MessageBus. But I’m not sure of the best way to do the same for the average_rating custom field I’ve created for topics. I can send it to back to the current user’s client easily enough, but other clients? I’m sure it’s relatively straight forward, but with my basic ruby skills the answer isn’t jumping out at me…


(Kane York) #7

You want to use MessageBus.publish(channel, msg, group_ids: topic.secure_group_ids) with the same channel and a different message.

I’m not quite sure how to hook into the MessageBus.subscribe() call on the client, though…


#8

Alright, installed and quickly tested.
Rating now works (great!). However, I can rate all threads, whether or not they have a rating Tag attached. I also see stars under each Thread title (again, no rating Tag). Not ideal…
Klicking on the stars on the published post does not work (I think having to edit the post is fine, but since you advertised it, I am telling you about it).
Is there a way for the user to remove a rating again? (Not necessary, but nice to have.)

I will test more later today.

Just one more request: When you implement your restriction to one post per user in any rating thread, can you make that a setting? I think for my use case having a proper back and forth discussion might be better (of course with a limit of one rating per user :wink: ).


(Angus McLeod) #9

Thanks, I’ve got it working now. I was getting confused by the last parameter, i.e. the user or group ids, on the publish function; it made me think it wasn’t apposite for this case.

The topic controller subscribes to the message bus here. The ‘revised’ type case already handles the post update, so all I needed to do was set the bus message type to ‘revised’ and then add extra logic to save the average to the client’s topic model for the ‘revised’ case, i.e.

then

@fackelwind topic averages now update automatically for all clients when any rating is changed.


(Angus McLeod) #10

Yes, I see the issue, I’ll fix it tomorrow morning.

Klicking on the stars on the published post does not work (I think having to edit the post is fine, but since you advertised it, I am telling you about it).

Yes I should have mentioned, I removed that functionality (updated the description accordingly now). So you can only rate in the composer itself.

Just one more request: When you implement your restriction to one post per user in any rating thread, can you make that a setting? I think for my use case having a proper back and forth discussion might be better (of course with a limit of one rating per user :wink: ).

Yes, I think I’ll make it a setting.

Thanks!


#11

Thanks a bunch for your fast response!
I did not have a lot of time this morning, so I just sent of a very quick response. I want to really thank you for this plugin, it matches perfectly with what I want to make possible for our community! (completely new site, so I am free to play around with a still maturing plugin. :wink: )

Another Bug Report from me:

  • Right now, every post can vote, even when that user has already replied and voted in the thread.

  • If you do not vote, it counts as 0 stars. I don’t think this is the correct way to handle it: A non-vote should not influence the average at all. And just posting into a thread which can rate should not lower the average opinion about the topic. Besides, once you have klicked onto 1-5 stars, you can never go back to 0 stars, so even if there just had to be a default vote, it would not be correct.

And a wishlist item: Some way to see the precise average, and how many people have rated the topic how highly. Kinda obvious if you look at amazon or wherever. Just making sure. :wink:

EDIT: Since it might not be obvious: Even though I report everything that looks wrong to me, and even write down whishlist items, the most important thing is that the plugin does not influence threads which it shouldn’t (no rating Tag, category not marked for rating). People are starting to use my discourse instance. Whether this plugin does or doesn’t work correctly is not a big deal as long as only the rating trial topic is influenced. When every single thread is modified, that is a much bigger problem. (All topics created today show stars…)


#12

I have deinstalled the plugin again for now (rebuild the docker instance without it), to get rid of the visual clutter on threads that were not supposed to be rated.

I will happily retry it once that bug is fixed (though having to rebuild the instance for that, with the associated downtime, is unfortunate).


(Angus McLeod) #13

I have made sure the topic averages will not be applied to new topics in a non-ratings category or without the ratings tag. Unfortunately this won’t fix existing topics with empty ratings you’ve made in your instance. If that is a significant issue, I’ll see if I can figure out how to fix it.

Right now, every post can vote, even when that user has already replied and voted in the thread.

I can’t reproduce this one. Could you check again if you re-install the plugin. Thanks.

If you do not vote, it counts as 0 stars. I don’t think this is the correct way to handle it: A non-vote should not influence the average at all. And just posting into a thread which can rate should not lower the average opinion about the topic. Besides, once you have klicked onto 1-5 stars, you can never go back to 0 stars, so even if there just had to be a default vote, it would not be correct.

Yes this is an issue. I think the way to handle it is if the user does not select a rating in a post, that post does not get a rating included. That user could still post on that topic with a rating in another post. Of course, once I add the setting to prevent a user posting in a ratings topic more than once, I will have to require that the user adds a rating to their single post. I will fix this one within the next two days.

And a wishlist item: Some way to see the precise average, and how many people have rated the topic how highly. Kinda obvious if you look at amazon or wherever. Just making sure. :wink:

Yes this is possible. I think I’ll add it next to the topic stars and add later a setting to show/hide it. I will do this one on the weekend.


#14

This is a significant issue, but not in the way you think. Having an SQL query to run against the DB (to remove the empty ratings) would not really help.
Think about this: How do you intend to handle the case where someone removes the “rating” tag from a topic? Or in any other way removes a topic from being a rated one?
I would argue that the only sane way for you to handle that case is to treat it as a vanilla topic: No stars, no possibility to rate, no restrictions in the amount of posts. So you don’t only look whether there are ratings when deciding on whether to draw stars or not, you always check whether the topic fulfills the criteria of being a rated one. (I have honestly no idea what you intend to do when someone tags an existing topic with “rating”, the setting to restrict it to one post per user is active, and users have already posted more than once…)

And if you have implement that, I won’t have any problems with stale ratings either. :wink:

I’ve got a discourse docker instance lying around on my desktop. Tell me when you have a version which you think should work, and I’ll test it there. :smiley:


A new versioned API for client side plugins
(Angus McLeod) #15

Sure, I’ll play around with the ‘removal’ case tomorrow morning.

This morning I migrated this to the new plugin api.


(Angus McLeod) #16

Ok! Finally had some time to work on this. Made various bugfixes and updates. Inter alia, I changed the category property that signified whether the category had ratings enabled, so existing categories with ratings enabled will have to be re-enabled to work.

The ratings tag and category toggle is now handled within the composer. If the creator of a topic removes/adds a ratings tag or changes from a ratings category in the first post of a topic the topic will refresh after they post and the ratings will show/hide depending on whether their action was to turn ratings on or off. If ratings are turned ‘off’ on a topic they are still there in the DB. If ratings are turned back on the same ratings will appear again.

Tomorrow or the next day, I’ll apply the same logic to the topic title edit (i.e. if the creator of the topic changes the category or tags by editing the topic title).

Then I’ll add the exact numeric rating to topics title sections and add a setting to toggle it. Then I’ll add an indication that a topic has ratings if those ratings are hidden (i.e. if the category or tags were changed) and a setting to toggle this too.


#17

That sounds really good!
I’ll play around with your plugin this weekend, see whether I have any more bug reports for you. :smiley:


(Angus McLeod) #18

Tomorrow or the next day, I’ll apply the same logic to the topic title edit (i.e. if the creator of the topic changes the category or tags by editing the topic title).

This is done.


(Angus McLeod) #19

Thanks @DavidGNavas for the Spanish translation!


(Jay Pfaffman) #20

It seems that the ratings plugin makes messages unavailable. Here are some logs. It looks like somehow messages don’t know that they don’t have ratings.

Logs.txt (43.7 KB)

When I disabled the ratings plugins my messages worked again.

Version	v1.5.0.beta11 +267	1.5.0.beta11

Discourse Voting