Building a powerful comment system

In this post, I am going to briefly describe the challenges we faced while building a powerful comment system.

Comments have become an integral part of our website. They are almost everywhere — challenges, problems, notes, and more will be added to our new products. We have been working to make the area more powerful and usable.

Here is what we did:

From the beginning

Our comment system is built using an open source django app named django-threadedcomments. In threadedcomments, commenters can reply both to the original item and to other comments. This open-source app best suited our requirements in terms of UX, hence we decided to use it. But later we realized it was not powerful enough and decided to add our own features to it.

Pluggable architecture

Our commmenting system is a plug and play app. We added a layer on top of django-threadedcommnets which lets us integrate comments anywhere on our website easily without writing the same code again.

Following is the snippet which we can include in any django template to add comments.

The single line of code above renders the complete comment list(including reply form) using bigpipe. Isn't it cool?

One more reason I am calling our comment system plug and play is that we can easily override most of the comments' display logic, showing comments differently on different pages. For example, comments appearing on a note and problem page needs to be shown differently based on the logic "who is the moderator of the content." This couldn't have been possible without the django template block tag.




Ajaxifying comments

This was the most challenging task because of the way django-threadedcomments is built. Special thanks to Virendra for taking the initiative and finding an easy-to-implement solution.

Posting a comment via AJAX request was relatively easy compared to deleting it because of comment's threaded nature. Whenever a comment is deleted, we first determine if that comment has at least a single child which is not deleted. Based on that logic, we decide the format in which the deleted comment will be shown to a user. If you didn't understand a word of what I wrote above, look at the images below.

Initial comments

After deleting comment 2, child comment 2.1 should be visible.

After deleting comment 2.1, delete complete tree.

We implemented a BFS algorithm to handle all the scenarios and corner cases.

Realtime sync

After ajaxifying comments, we decide to put the cherry on top. Making comments appear in real time was not easy at all. We are experimenting with Pusher to do the realtime job for us.

Following is generic the Python code for pushing data to Pusher via rabbitmq:

Pusher is great for broadcasting messages in real time, but it has some drawbacks. It doesn't have a scalable presence system, which means it's difficult to store info of more than 100 clients on the servers, making it difficult to write complex logic on client side.

Javascript code to post/delete comment:

Tagging people

It does exactly what it says, which means you can now tag people in comments, and they will be notified by email. Checkout the screenshot below.

Tagging people using @

Comment posted after tagging

I worked on this feature in our very first internal hackathon. I tried to make it as generic as possible by binding an event handler on "mentionable" class.

In backend, we query from the graph search database.

More to come

There are still a lot of improvements, like UI changes, in the pipeline which will be executed soon. If you have any suggestions, do let us know.

Hope these improvements have made the comments area on HackerEarth more engaging.

This post was originally written for the HackerEarth Engineering blog by Posted by Lalit Khattar. Follow him @LalitKhattar.

About the Author

Guest Author
Our guest articles are a collection of the best contributions made by members of the developer community on our blog. Discover articles on a wide range of topics, shared by top programmers across the world.