October 24, 2015
Creating an Aggregate Fivestar Average with Drupal Views

Difficulty:
Moderate (requires a tiny bit of programming, but all code will be provided)

Requirements:

  1. Drupal Fivestar (I am using 7.x - 2.1, though it probably works with any 7.x version)
  2. Drupal Views (Again, probably works with any 7.x version. I'm using 7.x-3.11)
  3. Entityreference (Any version will do)
  4. Ability to upload files to your website's server
     

Introduction

Fivestar is a Drupal module that adds, as its name indicates, a "five star" field type which can be attached to any Drupal entity. The Fivestar field type uses a Javascript-powered widget for both input and output, and is very useful for allowing users to provide ratings on content.


Example set of fivestar ratings

A common use case for Fivestar is to display an "aggregate" set of reviews - that is, if five users have submitted reviews on a piece of content, you might want to see the average of their reviews to get a feel for the general opinion of the community.

Another common use case is to separate the entity being reviewed from the entity which the Fivestar field is attached to. For example, if you have a content type called "Job", you may have a separate content type called "Job Review" which the Fivestar field may be attached to. Why would you want this? In my own use case, it's because we want additional information attached to the review beyond the fivestar rating - a Feedback textarea, for example.


Diagram of the Job - Job Review relationship, with stars showing the aggregation

Unfortunately, the basic Fivestar module does not give us the ability to display the aggregation of this use case on the Job object. However, using Views, and a little bit of Drupal template coding, we can make it work.


Instructions:

  1. Install Views, Entityreference and Fivestar like normal.
     
  2. Create the Job content type. You can set this up however you please.
     
  3. Before creating the Job Review content type, which will have Fivestar rating fields on it, we need to configure Fivestar globally.

    Go to /admin/config/content/fivestar, and in the "Tags" box, enter tags corresponding to the Fivestar fields you plan to add. If you have three fields, enter three tags, separated by a comma. These fields will be used to track votes between Fivestar fields. Click "Save configuration" once you're done.

  1. Create the Job Review content type. This should have at least one Fivestar field attached to it, as well as an Entity Reference field that points to the Job content type.

    For each Fivestar field, make sure to set the "Voting Tag" configuration to match one of the Tags you entered in the previous step.


The fields on my Job Review content type. Three Fivestar fields and an Entity Reference field


Each Fivestar field must have a unique Voting Tag setting, corresponding to the Tags you entered in the global configuration in Step 3.

  1. We've set up the content; now we need to set up a View that will display the aggregate value of each of the Fivestar fields. Create a new View that shows Content of type Job Posting.

  1. The first thing we will need to add in the View are Relationships - they can be found under the "Advanced" menu in the third column of the Views UI.

    Click "Add" next to "Relationships", and in the popup, search for "Content: Vote Results". Check the box next to it, and click "Add and configure relationship".

 

  1. In the "Configure" window, you will see three dropdowns under the "Data Filters" section.

    Leave the first one set to "No filtering", set the "Vote tag" value to the tag corresponding to one of the Fivestar fields you want to aggregate, and set the "Aggregation function" value to "Average Vote".

    Leave all other fields as they are. Click "Apply" when done to save the Relationship.

  1. Add Relationships for each of the Fivestar fields you want to aggregate. In my case, I added three, one for each field.

  1. Once you've added all your relationships, you can begin adding the Fivestar fields themselves. In the Views UI, in the column on the far left, click "Add" next to "Fields", and search "Vote Results: Value".

    Check the "Vote results: Value" field, and click "Apply".

  1. A configuration window for the inserted field will appear. The only field you need to change here is the "Relationship" field, which should be set to one of the Relationships we added. You can also change the Label if you like, but this is not required.

    Click "Apply" when done.

  1. You will need a Views field for each Fivestar field you wish to aggregate. Each Views field should link up to a different Views relationship. I have three Fivestar fields, three Views relationships, and hence three Views fields.

  1. At this point, the aggregation will be working. Add some Job Review content, and then preview the View.

    You will see that, for each Job, there will be an numeric average of Fivestar fields on the Job Reviews that reference that Job.


The three aggregated Fivestar fields for a Job. Note that I am displaying my data as a table; your View may look different.

  1. We got our aggregated field, but what we'd really like would be to display these aggregates in the five-star format - that is, use the five star widget to show the "star average" of each field. We can do this with a little bit of coding.

    In your view, find the "Other" menu (in the far right column) and click the "Information" link next to "Theme".

  1. Here's where things get a little complicated, so let's take things slow. In the window that pops up, you'll see a list of Views items - starting with "Display output" and "Style output", then followed by each of your Views fields.

    Next to each item in the list are a series of tpl.php file names. These are Views template files, which control how the Views item it is associated with is styled. One of these filenames will be bolded - the bolded one is the template that is actually being used to style the item.

    All of the Views Fields in the list should have "views-view-field.tpl.php" bolded, indicating that Views is using the default template file.

  1. We are going to create a new template file that will tell Views to style our fields using the Fivestar widget. The file should contain the following code. Copy and paste the code above into a file. 
<?php
 
$data = $row->{$field->field_alias};
$path = drupal_get_path('module', 'fivestar');
if(!empty($data))
{
  print theme('fivestar_static', array('rating' => $data, 'widget' => array('name' => 'basic', 'css' => $path . '/widgets/basic/basic.css')));
}
else
{
  print 'No votes';
}
  1. We now need to save the file and give it a name. It is very important that you name the file with a valid name, or Views won't pick it up.

    The file name should be the following format: 

    views-view-field--<view_id>--<field_id>.tpl.php 

    <view_id> and <field_id> are placeholders and should be replaced with their proper values.

    <view_id> is the ID of the View we are creating. You can find this in the URL on the View's edit page, which should be something like /admin/structure/views/view/<view_id>/edit. Note: if the ID has an underscore (_) in it, replace it with a dash (-) in the filename!

    <field_id> is the ID of the Fivestar Views field (note that this is different from the ID of the Fivestar field on the entity itself!) The easiest place to find this ID is in the Theme Information link above - find the name of the field in the list, and the ID will be next to it in parens. Note: again, replace any underscores with dashes when adding the field ID into the filename.

    Now that you have both of these values, you should have your full filename. My own placeholders were job-list and value (for <view_id> and <field_id> respectively), so my full filename was:

    views-view-field--job-list--value.tpl.php

  2. Save the code above into a file with the proper filename. Next, you need to upload it to your Drupal directory. It should be stored in the templates directory of your active theme!

    If you're not sure what your active theme is, you can find it under /admin/appearance

    If your active theme is one of the system themes (like Bartik or Seven), add your tpl.php file to <DRUPAL_ROOT>/themes/<theme_name>/templates

    If your active theme is a custom theme, add your tpl.php file to <DRUPAL_ROOT>/sites/all/themes/<theme_name>/templates.

  3. Repeat the steps 15 - 17 for all Fivestar Views fields. I have three fields, so I needed to upload three files. The contents of of each of the three files is the same, but the names are different.

  4. Once you have uploaded your tpl.php file(s), clear Drupal's cache and check out the Theme Information window in the View again. The bolding next to your Views Field should have changed, indicating that Views is now using your custom tpl.php to theme the field.


Note that the "views-view-field-job-list--value" tpl.phps are bolded now. This indicates that Views is using our custom templates to theme the fields.

  1. If you check the Preview field in Views, you'll see that the fields haven't changed. However, if you exit the Views UI and check the actual View itself, you will see the three fields themed with the fivestar widget!


This completes the tutorial. If you have any questions, please don't hesitate to email me at gwalliman@genost.org.