I’ve recently finished working on a project for a client. This was an interesting journey and I want to tell you about it.
Several months ago a client approached to me with an interesting idea to create a social website where people could come and publish their top lists of everything you can imagine (for example, Top 5 Restaurants in Beijing). Client had his own vision of a project and wanted it to be implemented on Drupal, because of its modular nature and community support. After taking client’s vision and translating it into Drupal we came to what ended up as Listbattle.com (http://listbattle.com).
Main project requirements were:
1) Cool looking and convenient in creation “List” content type which has a custom background option and multi valued list of items.
2) Social functionality including users activity feed, awards for achievements, ability to follow other members activity and see own content.
3) Listings with data sorted by day/week/month view stats.
Below I’ll tell a bit about different functionality points and how they were implemented.
1 Content type: List
At the heart of listbattle.com lies a List content type which consists of different fields provided by Field API. I had several challenges implementing this task:
1.1 List positions
List positions are of multi valued nature and each position consists of several fields including: title, description, video url, media upload and media type.
To solve this problem I could go with Field collection (http://drupal.org/project/field_collection) module, but it would ended up not so good for performance. Each field_collection is an entity with 5 fields attached to it. This would produce 6 records in 6 different tables per one list position!
Thats why I created a custom field module which creates a custom field which holds all five fields, which creates one row in one table per position + gives nice integration with Views and gives possibility to handle this field in MongoDB in case of need.
1.2 Youtube url handling
One interesting feature of list position is a Youtube video url field. To embed a video you just need to put youtube url in it and custom field api will validate this url and embed video on the fly.
1.3 Background images
Every list can have a custom background, it can be predefined or uploaded by user. I looked at dynamic_background (http://drupal.org/project/dynamic_background) module at first. But it didn’t meet all our requirements plus it wasn’t so themeable without hacking. In the end it turned up to be easier to create one more custom Field which holds custom background data per node/entity.
1.4 Dynamic titles with placeholders
If you look at titles of List, it is dynamically generated from the data users enter. It has three predefined templates, like “Top X _____”, “___Top X_______”, “_____X________”, this was done to standardize titles which users create. To achieve this, I created a custom Field which holds title format, prefix, suffix and title text for each node. To dynamically change title input fields I leveraged Drupal Ajax framework which is really cool!
1.5 Battle / Relist functionality
Every list can be relisted (user can create own list based on any list) and battled (user can create his own version of your top 5 cartoons and put your list on a battle). I could use node clone (http://drupal.org/project/node_clone) module here but it turned out that our “clonning” process was a bit more complicated. In the end I created a custom module to leverage two different “clonning” workflows taking some nice ideas from node_clone’s module.
1.6 Social sharing
Every list can be shared on facebook/google/twitter via widgets provided by easy_social (http://drupal.org/project/easy_social) module.
2 Social features
Every user has a profile which has several interesting features, including:
2.1 Activity stream
The requirement was to create an activity stream for each user and to show all user’s and his friends activity and give a user ability to shout on his own “wall”. To achieve this, I used heartbeat module heavily customized via heartbeat API to play nicely with shoutbox module. I created heartbeat message templates for every needed activity (for example, “user X posted list Y”, “user A commented on List B”) and create them via Rules (http://drupal.org/project/rules) module, which takes care of creating actions depending on events.
Users can earn achievement badges depending on their actions. To make this possible I used achievements API (http://drupal.org/project/achievements) and created custom badges for different events and put rules in charge of controlling all of this. There are some badges at Listbattle which are dependent on custom user stats such as posts count, login counts, comments count etc. To count all these a custom userstats module was created. Possibly I will release it on drupal.org for public, after some polishing.
2.3 Facebook login
Users hate to register and almost everyone is on Facebook right now. To leverage this, Listbattle.com has Facebook Login/Sign Up function on a site powered by fboauth (http://drupal.org/project/fboauth) module which I highly recommend to use in such cases.
2.4 User views
At profile pages users can see favorite, created lists, list of people whom they follow and who’s following them. I used Views extensively to implement this functionality.
There are more than 10 different views to show List content types: category/tag views, top of the day/week/month lists and more.
The most interesting part here is day/week/month popular list views, where we needed to show popular lists and sort them by daily/weekly/monthly view stats data. The problem was even more complicated: we needed to gather stats on cached pages, which is impossible to do via standard hook_exit() methods. There were no ready made module to solve this, so I created entity_stats module (to be submitted to drupal.org soon), which can count view stats on node/user/taxonomy pages even if these pages are cached.
So these are major features of Listbattle.com and my story about how Drupal was leveraged to implement these features. On overall there were created 17 custom modules for the project, several of them to be shared on Drupal.org soon.
Current version of Listbattle.com is mvp (minimal viable product) actually, Listbattle.com team are working on building great content and there are lots of cool new features to be implemented in the future. Stay tuned.
At the end, here are some impressions from client about the project and our work together:
"The creation of List Battle has been both fun and in many ways instructive project. It evolved from a simple idea based on giving ordinary Internet users the opportunity to rank and categorize content on a toplist in a simple way, to becoming a relatively complex and complete project.
It resulted in an end product that I am very pleased with.
Tim is an extremely talented and developer, but he is also much more than that; He is a good communicator, he has a good visual and graphical understanding and then he is also extremely good at understanding projects from both a business-marketing standpoint and an end-user point of view.
I doubt Listbattle had ever been so well executed without Tim, so I feel very fortunate to have had Tim as a developer on the project, and I would not hesitate to work with him in the future." - Jeppe Nielsen, Listbattle.com