Topic replies invisible until topic owner decides to reveal them?

So my SO is a teacher (ancient Greek and classical Latin) and has been using Discourse in her classes for a number of years now. She uses it mainly to distribute assignments to her students and discuss them afterwards. However, all the assignments are being handed in on paper during her classes.

Until now - since the schools have been closed because of all the corona panic she is moving to 100% online teaching, including the assignments. So all those students are currently e-mailing their work to her. This is very sub-optimal since it requires her to do quite a lot of administration (and I can tell you she is not very good at those kind of things :wink: ).

We were discussing a few options and she said: “why can’t I have a topic where people can only see my posts (i.e. the posts made by the topic starter) and their own posts? This would allow me to post an assignment as a topic and have every student post their answers below it without being able to see all the other answers. Then when everybody has entered their work and it is time to discuss, I want to be able to press a button to make the veil go away and make all posts in the topic visible to everyone, so they can all see and discuss each others work.”

Yes - brilliant! (that’s why I love her).

I’m going to build a plugin for this, probably leveraging the solved plugin for the magic switch (make everything visible as soon as the topic is solved). But before I start I wanted to gauge your opinion and get some feedback, and maybe get some ideas to make this even better.

Hints and pointers on how to efficiently implement this would also be very welcome - since there are many ways to retrieve a topic and when a single student finds a way to circumvent this then everything is worthless.

Is everything regarding a topic being passed through a TopicView? Could I leverage username_filters ? Or build something similar to that? Or is a guardian a better way?

Let me hear what you think!


It heavily depends on the security guarantees needed here, but since I assume students are quite savvy a CSS only solution is not going to work.

Now if a CSS solution does not work and these kids are probably going to be rascals and find every loophole to cheat.

Backdoor [quote] expansions, and all sorts of other shananigans may happen. A simple patch to “can see post” may not be enough.

A very secure way of doing this would be in PMs, the students submit the stuff via a PM and then once done… a “click” moves all the PMs to the topic. Clean … simple … secure.


Are solutions uploads or composer text?

If uploads, using the new Secure Media Uploads, plus a plugin to change the way the temporary URL is generated for user downloads to only generate “good” ones for staff may work and be a minimal change. After a topic is solved/tagged/closed the temporary URL goes back into the normal state so everyone can see everything.

It is also cool that you can see people submitting without seeing the content of the submission.


Thank you both for the feedback and ideas!

The problem is that she has 6 different classes with maybe 2 or 3 assignments each running simultaneously, so she has around 15 different assignments to manage. So it’s not going to be that easy I guess.

No, CSS only won’t work, that’s for sure. OTOH it wouldn’t be a huge problem if this gets cracked once or twice, as long as I don’t end up patching issues every day.

That is a really cool idea. But they’re mostly composer text, and she doesn’t want to force everything to be uploads either.


I’m going to edit the title since this is the request.

My gut feeling is this is more like a spoiler plugin than anything else. The spoilers would only be revealable by the topic owner.


Spoiler is going to be a bit tricky cause then you have to protect /raw routes as well.


  • Teacher posts “Why did war start in indochina”

  • Student creates a PM to self with the assignment, then once done, posts a link in the topic. (Advantage, revisions, does not bug teacher)

  • Teacher can then provide “direct feedback” in the PM

  • Once everything is graded teacher clicks “Publish” which copies the raw contents of the PM and replaces the link to the PM in the assignment topic.


People ask for this several times a year and the answer is always “You can’t have topic-specific permissions.” If you can work this out, I think that there will be considerable interest.


Well, this is a bit hairy. I’ve been hacking away a bit at TopicView and PostGuardian and this gets me at 80% without too much effort, including /raw and tricks with editing quoted post numbers. Right now I can still see posts that I shouldn’t be able to see via:

  • search
  • user activity
  • digest emails

So it needs some more patching. Right now, the above is all I can think of. Suggestions for other ways to get to a post are welcome.


And that’s still the answer. I think even asking this question indicates the person asking hasn’t really thought through what they are trying to accomplish, TBH.

I don’t mind an enhanced spoiler mode though, I think that makes sense.


What if this was implemented as “regular users creating whisper posts”?


Whispers to whom? The topic owner? Then they need to be demoted from whispers.


I still have to finish some small details but I have a working plugin now at GitHub - discoursehosting/discourse-private-replies

After installing and enabling the plugin the topic owner (and staff) will get an extra button at the bottom of each topic called Private Replies.

The button can be used to toggle ‘private replies’ mode for the topic.

When private replies mode is enabled,

  • topic owners can still see all posts
  • all other users will only see posts made by the topic owner, staff, and themselves.

Such a topic can be recognized by a banner on the top of the topic:

When the topic owner decides to make the posts public, they can use the same button on the bottom of the topic (now called ‘Public Replies’) to disable the Private Replies mode. The banner will disappear and all posts will be visible to everyone (honoring category security of course).

The plugin disables the following ways to retrieve the post contents:

  • topic view (i.e. the regular way of looking at posts)
  • user profile - activity
  • search
  • raw (/raw/topic_id/post_id)

Disclaimer 1:

The plugin does not completely hide who posted in the topic. The user avatars in the topic list are untouched and the topics are also visible in the user profile - summary. However, both of these do not reveal the contents of the post.

Disclaimer 2:

I don’t know if there are ways to retrieve post content that I might have overlooked. (I still have to test whether digests will reveal stuff, for instance). My SO is going to test this in the course of the upcoming weeks and I have no doubt that her students will be able to find some smart loopholes. I will try to close those as soon as I find out about them. Hints and tips are welcome!

I’ll make a plugin category post and a good later this week. In the meanwhile, I’d love your feedback!


What are the performance implications of this? A lot of third party plugins manage to add N+1, N-squared, N-cubed, N-to-the-power-of-N queries… hopefully that can be avoided here.

Also nice if it can be toggled per topic and have zero perf impact on any other topics except those where it is toggled on, rather than a global price that has to be paid all the time?


I did my best to keep things as efficient as possible, i.e. evaluate as lazily as I could and bail out of any filters as quickly as possible.

There is absolutely some room for small optimizations like caching the staff userid’s and the id’s of the protected topics, but I think I did pretty well for a first version. If anyone disagrees, please feel free to criticize my code.