Mugo Web main content.

Separate Star Rating aggregate value from "your rating"

By: Peter Keung | November 28, 2011 | eZ Publish development tips

eZ Publish comes standard with the Star Rating extension, which adds the ability for users to rate content on your website. It works well out of the box. By default, the interface to rate an article is combined with the aggregate rating on an article. Here's a quick example on how to tweak that functionality so that "your rating" is separate from the aggregate rating.

This is the default, combined interface that shows the aggregate rating and the ability for the user to rate the article:

Default Star Rating interface

This is the desired interface, which will split the interface...

- before rating:

Star Rating in progress

- after rating:

Star Rating after being rated

To achieve this, here is a code diff of the star rating datatype view template, which separates out "your rating" and also fetches the current user's rating:

--- extension\ezstarrating\design\standard\templates\content\datatype\view\ezsrrating.tpl
+++ extension\yourextension\design\yourdesign\templates\content\datatype\view\ezsrrating.tpl
@@ -2,9 +2,6 @@
 
 <ul id="ezsr_rating_{$attribute.id}" class="ezsr-star-rating">
    <li id="ezsr_rating_percent_{$attribute.id}" class="ezsr-current-rating" style="width:{$rating.rounded_average|div(5)|mul(100)}%;">{'Currently %current_rating out of 5 Stars.'|i18n('extension/ezstarrating/datatype', '', hash( '%current_rating', concat('<span>', $rating.rounded_average|wash, '</span>') ))}</li>
-   {for 1 to 5 as $num}
-       <li><a href="JavaScript:void(0);" id="ezsr_{$attribute.id}_{$attribute.version}_{$num}" title="{'Rate %rating stars out of 5'|i18n('extension/ezstarrating/datatype', '', hash( '%rating', $num ))}" class="ezsr-stars-{$num}" rel="nofollow" onfocus="this.blur();">{$num}</a></li>
-   {/for}
 </ul>
 
 {'Rating: %current_rating/5'|i18n('extension/ezstarrating/datatype', '', hash( '%current_rating', concat('<span id="ezsr_average_', $attribute.id, '" class="ezsr-average-rating">', $rating.rating_average|wash, '</span>') ))}
@@ -19,6 +16,20 @@
 {ezcss_require( 'star_rating.css' )}
 {* Enable rating code if not disabled on attribute and user has access to rate! *}
 {if and( $attribute.data_int|not, has_access_to_limitation( 'ezjscore', 'call', hash( 'FunctionList', 'ezstarrating_rate' ) ))}
+    {def $rating_current_user = 0
+         $current_user = fetch( 'user', 'current_user' )
+    }
+    {def $rating_object = fetch_starrating_data( hash( 'contentobject_id', $attribute.contentobject_id, 'user_id', $current_user.contentobject_id ) )}
+    {if $rating_object}
+        {set $rating_current_user = $rating_object.0.rating}
+    {/if}
+    <p>{'Your rating:'|i18n('extension/ezstarrating/datatype')}</p>
+    <ul class="ezsr-star-rating">
+       <li id="ezsr_your_rating" class="ezsr-current-rating" style="width:{$rating_current_user|div(5)|mul(100)}%;">{'Your rating is %current_rating out of 5 stars.'|i18n('extension/ezstarrating/datatype', '', hash( '%current_rating', concat('<span>', $rating_current_user|wash(), '</span>') ))}</li>
+       {for 1 to 5 as $num}
+           <li><a href="JavaScript:void(0);" id="ezsr_{$attribute.id}_{$attribute.version}_{$num}" title="{'Rate %rating stars out of 5'|i18n('extension/ezstarrating/datatype', '', hash( '%rating', $num ))}" class="ezsr-stars-{$num}" rel="nofollow" onfocus="this.blur();">{$num}</a></li>
+       {/for}
+    </ul>
     {*
        eZStarRating supports both yui3.0 and jQuery as decided by ezjscore.ini[eZJSCore]PreferredLibrary
        For the JavaScript code look in: design/standard/javascript/ezstarrating_*.js

The other tweak is for the JavaScript code, so that whenever a user rates an article, the "your rating" display gets immediately updated. Since the Star Rating extension supports both jQuery and YUI 3, we need to update the code for each library:

--- extension\ezstarrating\design\standard\javascript\ezstarrating_jquery.js
+++ extension\yourextension\design\yourdesign\javascript\ezstarrating_jquery.js
@@ -27,6 +27,7 @@
         var args = $(this).attr('id').split('_');
         $('#ezsr_rating_' + args[1]).removeClass('ezsr-star-rating-enabled');
         $('li a', '#ezsr_rating_' + args[1]).unbind( 'click' );
+        $('#ezsr_your_rating').css( 'width', ( ( args[3] / 5 ) * 100 ) + '%' );
         jQuery.ez( 'ezstarrating::rate::' + args[1] + '::' + args[2] + '::' + args[3], {}, _callBack );
         return false;
     }
--- extension\ezstarrating\design\standard\javascript\ezstarrating_yui3.js
+++ extension\yourextension\design\yourdesign\javascript\ezstarrating_yui3.js
@@ -26,6 +26,7 @@
         var args = e.currentTarget.getAttribute('id').split('_');
         Y.all('#ezsr_rating_' + args[1]).removeClass('ezsr-star-rating-enabled');
         Y.all('#ezsr_rating_' + args[1] + ' li a').detach( 'click', _rate );
+        Y.all('#ezsr_your_rating').setStyle( 'width', ( ( args[3] / 5 ) * 100 ) + '%' );
         Y.io.ez( 'ezstarrating::rate::' + args[1] + '::' + args[2] + '::' + args[3], { on : { success: _callBack } } );
     }