5

I want to set up a system where a user is given a title based on how much content they have created/published. So, for instance, if the user has published:

0 nodes  - Noobie
1+ nodes - Poster
10+ nodes - Frequent poster
20+ nodes - Super Poster
50+ nodes - God`

I'm wondering if there is a way to implement this in a Drupal site. I can think of a way to do it using database queries and a computed field, but I'm wondering if there might be a more efficient way to go about doing it.

4 Answers 4

7

I doubt there is a module for this, but hey. Do not let that bring you down, it's actually a great idea for a custom module! If you have a bit of patience, Drupal is very easy to learn once you get past the initial learning curve.

If you need a start, the module developper section and the create a module page on Drupal are great place to start.

There are many, many ways you could do this, but to start I would probably create a small module. Imagine it's called super_usernames, for the purpose of this post. I would just create a folder in sites/all/modules called `super_usernames. That folder would need to contain only 2 files:

super_usernames.info and super_usernames.module. The info file is very easy:

name = Super Usernames
description = Gives special credits to usernames depending on number of posts.
core = 7.x
files[] = super_usernames.module

The module file would need at the minimum just one hook to be defined. Hooks are just plain old php functions that use a simple naming convention in order to be executed by Drupal automatically.

The hook you need here is hook_node_view. Basically you want to add :

/*
 * Implements hook_node_load
 */
function super_usernames_node_view($node, $view_mode){
  $supported_node_types = array('page', 'article', 'blog'); // Supports default content types
  if (in_array($node->type, $supported_node_types) { 
    // query to get number of nodes this user has published
    $result = db_query("SELECT count(nid) as nodecount from {node} WHERE uid = %d", $node->uid);
     $row = db_fetch_object($result); 
     $node_count = $row->nodecount; // Easier to read
     switch ($node_count){
       case $node_count >= 50:
           $node->super_username = "God";
         break;
       case $node_count >= 20:
          $node->super_username = "Super Poster";
         break; 
       case $node_count >= 10:
          $node->super_username = " Frequent Poster";
         break;
       case  $node_count >= 1:  // same as > 0, but who cares...
           $node->super_username = "Poster";
         break;
       default:
           $node->super_username = "Noobie";                  
     }
  }
}

Now. After doing this, all your nodes should contain the dynamic value of the number of nodes posted by that node's author. This would be added on the fly on every page load from content-types articles, and pages.

You still need to have it displayed somewhere, though! This is where you would ideally create a sub-theme (so as not to hack a base theme). But for the purpose of this post, we will simply modify one file: node.tpl.php.

Check the theme you are using, by default it is bartik but the procedure is mostly the same whatever theme you are using.

Go into your themes/bartik/templates directory, open the node.tpl.php file. Locate where you want to add the super username in the html, and add this code snippet:

<?php if ($node->super_username): ?>
  <div class="superUsername">
    <?php print $node->super_username; ?>
  </div>
<?php endif; ?>

Now. One last step, you may need to clear the cache for changes to take effect. Devel module makes it easy, Drush makes it even easier. After this, you should have your super usernames dynamically shown on all the content-types defined in the supported_node_types array.

Hope this doesn't sound too complicated, it's actually quite trivial when you go through the process a few times. Feel free to message me or repost here if you need any help.

Happy coding, cheers!

  • PS: This code has been slapped up from memory, nothing is tested but should be pretty close to a fully working example. Your mileage may vary, there may be typos in there.
6
  • I haven't gotten a chance to try and implement this yet, so I'll get back to you when I do. Seems like a great option though! Thanks for writing it our. However, I'm wondering if there is a way to make this information fieldable -- so that I can make it appear within Views and possibly modify its positioning within a node using Display Suite -- or is this created as a value that can only be displayed by modifying the node.tpl.php?
    – Mrweiner
    Commented Aug 17, 2012 at 23:31
  • Also, do you know if there is anything that needs to be changed to limit the count to only nodes of a certain type, or to allow this to appear in a user's profile page?
    – Mrweiner
    Commented Aug 18, 2012 at 7:18
  • If you look at the code, the first line in the function sets an array $supported_types that holds the content types you want a count on. As for having this data fieldable, of course it is possible but then the data would be "static", that is instead of being calculated on every node load would be calculated once, at node creation. If one takes this approach, the field would need to belong to the user, not the node. Consider this: User creates a node that has <super_username> field populated to newbie status. User creates 50 nodes. The original node still contains the original <noobie>. Commented Aug 18, 2012 at 12:24
  • A view uses templates that can be over-ridden just like the node.tpl.php. Even if you use a field, attached to the user, every time user creates a node you would need code to update the user profile on every node save. However you look at it, you need custom code somewhere and this simple module I posted is truly the most elegant and simple way I could think of. Simplicity and elegance is what I aim for, so that anyone looking at this can see at a glance what is happening. Of course, there can be improvements like returning a render array, but I kept it simple. Good-luck friend, cheers! Commented Aug 18, 2012 at 12:44
  • @stefgosselin : I know, nearly years later now, but do you still "doubt" (as in your 1st paragraph)? Refer to my answer I just added to understand why I ask ... Nevertheless: interesting answer (to consider for integrating in the Goals module also ... some day) Commented Apr 8, 2016 at 17:40
3

A general-purpose module for use cases like this is User Points, which integrates with Rules. You could use rules to automatically add points when a user's content is published. You could even make some content types more valuable than others.

As for the titles, there is the User Badges module for D6, although there has been no official release for D7. In the meantime, depending on how complex your setup is, you could add a text select field to the user profile and use Field Permissions to forbid users from editing it. Then, you could use Rules to automatically set the data value at each threshold (1, 10, 20, etc.)

1
  • Your first paragraph could be part of the original specs of the Goals module (refer to my answer I just added for details). Maybe you should edit your 2nd parg about D7-status these days (there is an official release now)? Quick extra question (curiosity) about the data value at each threshold: how would you "keep track" of its progress, or would you just recalculate the value any time a node would get published? Commented Apr 8, 2016 at 17:47
3

Another option to the already good suggestion of using the User Points + Rules modules, would be the Achievements module.

This is more geared towards mimicking the idea of gamification found on sites such as this, but will definitely give you full control if you're up for calling a few API functions.

1
  • 1
    For this task, I think I might go with the custom module suggested by stefgosselin. However, I'm definitely going to take a look at the Achievements module for other aspects of the site. Seems like a more all-encompassing way to take care of the task of user points/badges from one place. I'm new to writing modules, though, so I'm not at all familiar with making API calls. I see that there are a couple pages suggested on the module's page, but are there any other resources that you might suggest for getting started on learning the process?
    – Mrweiner
    Commented Aug 17, 2012 at 23:35
2

The Goals module is yet another solution to answer this question.

Goals and Tasks are implemented using fieldable entities. So you can customize Goals via "Manage Fields" and/or "Manage display". E.g. to add your own fields, such as:

  • descriptions.
  • images.
  • links to external resources.
  • etc.

Head over to the Goals video which includes:

  • a general introduction to the module.
  • a demonstration to install, configure and use it.
  • samples of how it uses the Rules modules to do its magic (i.e. to track the progress of a user to achieve the various roles.

Using the Goals Extras sub-module it integrates with the User Points module also.

Measuring the number of nodes published by a user (as in your question here), would really be like a getting started with this module: each of the 5 examples would become "a" Goal, whereas the actual "Tasks" would consists of just "publishing a node".

Even though your question (requirements) doesn't seem to include that, you could take it a bit further. E.g. by only taking into account 1 published node per day (so a user publishing 3 nodes on the same day would only count for 1).

All this can be done with site building features only (no custom code involved), though hooks are available to integrate it in custom coding also).

For more details, refer to its Community Documentation. For some details about how it differs from the Achievements module, refer to What is the difference with the Achievements module, which states:

The Goals module is built around using the admin interface configuration. Plus, goals and tasks within the Goals module are fieldable entities, so you have the flexibility to add additional fields and incorporate these entities into views.

I can't speak definitively for the Achievements module, but my best understanding is that it relies heavily on custom coding to handle many of the functions.

Disclosure: I'm the maintainer of this module.

2
  • Why I didn't know these kind of modules before? :( Thanks for sharing it and of course maintaining it :)
    – herci
    Commented Apr 8, 2016 at 18:00
  • 1
    @herci: don't worry, nobody knows all of the +17K modules available today, right? I only know about 500 to 1000 of them (most of them only by name) ... Also, if you're interested in another "interesting module", then use the "Try out a demonstration" link on that project page (and be aware I became the new maintainer of it recently also). Commented Apr 8, 2016 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.