Drupal goes Social: Building a "Liking" Module in Drupal

Originally published at: http://www.sitepoint.com/drupal-goes-social-building-liking-module-drupal/

In this article, we are going to look at how we can create a Drupal module which will allow your users to like your posts. The implementation will use jQuery to make AJAX calls and save this data asynchronously.

logo_drupal

Creating your Drupal like module

Let’s start by creating the new Drupal module. To do that we should first create a folder called likepost in the sites\all\modules\custom directory of your Drupal installation as shown below:

Initial folder structure

Inside this folder, you should create a file called likepost.info with the following contents:

name = likepost
description = This module allows the user to like posts in Drupal.
core = 7.x

This file is responsible for providing metadata about your module. This allows Drupal to detect and load its contents.

Continue reading this article on SitePoint

Instead of doing this through custom module, you cn use flag module with almost no coding to implement like functionality.

Thanks for the article but I wonder is it normal to have HTML right inside the module code?
Can you show how can we move that markup into the external theme files?

Biggest issue here is that this module present a CRSF vunerability, there is no verification when accessing the like action callback, It should be a form to prevent abuse. Here is how to do things properly: Create forms in a safe way to avoid cross-site request forgeries (CSRF).

Usually we should stop here and fix the thing (or better, as was said earlier, use flag module and be done with it).

But let’s take it all the way, this is a vulgarization article so I’d rather people learn the right things (if not in the article, in the comments):

  1. There ought to be a custom permission for this, access content is way to permissive and un-customizable. Combine that with the CRSF issue and watch your DB melt.
  2. As far as I can see all anonymous users gets one vote and step on each others, clearly a bug (anon users have the user ID 0).
  3. User text is not translatable, the t() function needs to be used.
  4. Also, it would be great to use Drupal coding standards when writing Drupal code:
  • Indentation is 2 spaces.
  • else on a new line.
  1. There is no need to use $base_url, that’s what the l() function is for.

  2. There is a straight up bug in the JS, try displaying several likes on the page and things will get messed up. It is also neither using Drupal JS API nor JS standards.

// wrote the code without running it, should work but no guarantees.
(function ($) {
  "use strict";
  // jQuery ready doesn't work for content added through ajax,
  // always use Drupal.behaviors.
  Drupal.behaviors.likeLink = {
    attach: function (context) {
      // The jquery once plugin make sure initialization happens only once.
      // It is completely different from jQuery.one()
      $(context).find('likepost').once('like-link').each(function () {
        var $likepost = $(this);
        $likepost.find('a.like-link').click(function (event) {
          $.ajax({
            type: 'POST',
            url: this.href,
            dataType: 'json',
            success: function (data) {
              var $like = $(event.target);
              if (data.like_status === 0) {
                $like.html('Like');
              }
              else {
                $like.html('Delete Like');
              }
              $likepost.find('.total_count').html(data.total_count);
            },
            data: 'js=1'
          });

          return false;
        });
      });
    },
    // When removing the content during ajax calls, clean up things.
    detach: function (context, settings, trigger) {
      if (trigger === 'unload') {
        $(context).find('likepost').removeOnce('like-link')
          .find('a.like-link').off('click');
      }
    }
  };
})(jQuery);

On the plus side, using a theme function is good and special thumbs up for using #attached instead of the dirty drupal_add_js lots of kudos from me there :smile:.

There ought to be at least a tiny amount of peer review to avoid code presenting security vulnerability make it on sitepoint.com. Wouldn’t want people to complain about Drupal when it’s only fault may be hard to find documentation.

@nod_ thanks for the detailed feedback! We do have a peer review system in place, but sadly, we lack Drupalistas. Would you be interested in joining the peer review repo? All the upcoming posts are there first, for at least two weeks before publication, often longer, so if you could find the time to take a look from time to time and drop a comment or two, it’d be much appreciated. All I need is your Github username. A bit more info here.

I’m stretched for time but I can help a little. This feed is published on the Drupal planet after all. My github username is theodoreb.

You should now have access to the repo. I figure you’re probably as stretched for time as the rest of us, but even if you just briefly skim a post when waiting in line in a shop or something and leave a comment like “this and this should be like this and that”, it’s already a huge help. Thanks!

Yup, all good. Thanks. I’ll look out for Drupal posts in the queue :smile:

1 Like

@abbass786 any feedback on this, as the author? Or @upchuk as our Drupal regular?

For like/dislike I always use Flag module, because he support views

Not much from me. I agree with @nod_ on his points.

Yup Agreed.
The idea of this tutorial was not to just make that module.
But learn how pieces of which work together for instance how to use jQuery etc so that it can be used in any custom Drupal module you planning to make.

Thanks nod_ with the detailed feedback.
I agree with all the comments.

Just as a a beginner , when one is not use to coding in Drupal then too many concepts in one post (like using the T function etc) cause too much to digest. Though I completely agree that a final production code written for Drupal should have all the best practices mentioned by you.

But as a beginner if some one reads a post too many new concepts make one even not understand the core concept the the article is trying to highlight.

Having you in the review team will be awesome.
Looking forward to that and improve my Drupal skills :slight_smile:

Thanks for catching the drupal_add_js and recommending #attached in the peer review :slight_smile:

You little complicated task.
Instead of writing custom js code you can use class ‘ajax-link’ and use ajax command. Here example how to use this features of Drupal http://www.computerminds.co.uk/drupal-code/make-link-use-ajax-drupal-7-its-easy . Also there is a little performance improvements: you need place nid column in primary key first then uid (some info about this: https://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html )
And of course you have problems with anonymous users (you can use session_api module if you want to give permission for anonymous users to vote).

can this be used together with something like the ostatus module ?
…or any project that might be able to do (or aiming to do) decentralised federation for posts?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.