Table of contents
- 1. Documentation
- 1.1. Summary
- 1.2. Version History
- 1.3. Template Parameters
- 2. Template Code
Documentation
This box includes basic usage information for this template. When calling the template, this documentation will not appear. Functional template code should be placed outside the dotted box.
Summary
Template Description | Simple DekiScript-based Star Rater, either for page ratings or anything else you want to rate. It is inherently insecure, so it is only recommended for light-duty, non-critical usage. |
Requirements |
|
Documentation URL | http://developer.mindtouch.com/App_C.../StarRater_-_A simple_DekiScript-based_star_rater_for_light-duty_use |
Discussion URL |
Version History
Place newest version at the top of the table.
Version | Date | Author | Description |
---|---|---|---|
1.00b | 6-May-2011 | Neil Weinstock | First "official" release |
Template Parameters
Name | Type | Default | Description |
---|---|---|---|
property | str? | "star_data" | Name of the property in which the voting data will be stored. If you plan to have multiple StarRaters on a page, you should assign each one a unique property name to avoid collisions, otherwise, just leave this blank. The ID of the page is always tacked onto the end of the property name, so you can safely store the ratings data from multiple pages in the same page, without collision. |
msg | str? | <none> or "Rate this page:" if page==true | This is the little "please vote" message that gets placed above the stars. If this is not specified, and page==true (see below), this value will default to "Rate this page:". If the current user does not have voting rights, then the message is not displayed |
page | bool? | false | Page mode. This is a convenience for when you use this as a page rating mechanism. If true, then two things happen:
|
path | str? | page.path | Path of the page where the voting data property will be stored. |
Template Code
Unsafecontent Permission Check
// This code checks if the template is properly installed for unsafe content execution, // and may be removed if this check is not desired. If you leave this here, add your new code // in a new DekiScript block below this one. var thisTemplate = wiki.inclusions()[-1]; if (!wiki.pagepermissions(thisTemplate.id, thisTemplate.author.id).unsafecontent) <div style="color:red; width:75%; padding:5px; border:1px solid red;"> "WARNING: The page '"..thisTemplate.path.."' must be re-saved by a user with UNSAFECONTENT permission in order to work correctly. "; <a href="http://developer.mindtouch.com/en/kb/Using_templates_which_require_UNSAFECONTENT_permission"> "See this" </a>; " for more info."; </div>;
Parameter Processing
// Arg processing var errors = []; // prop: name of property used to store ratings data var prop = ($0 ?? $property ?? "star_data") .. "_" .. page.id; var table = "table_" .. prop; // msg: message to put above star rater var msg = $1 ?? $msg; // page: "page rating" mode, which floats the rater to the right and auto-populates // the "Rate this page:" message if necessary var pageMode = $2 ?? $page ?? false; if (pageMode && msg is nil) let msg = "Rate this page:"; // path: path of page on which to store property var path = $3 ?? $path ?? page.path; // Fetch page used as data store var p = page; if (path != page.path) { let p = wiki.getpage(path); if (p == nil) let errors ..= [ "can't find page with data store" ]; } // Fetch the current vote data var data = json.parse(p.properties[prop].text ?? '{}'); if (data is not map) { let errors ..= [ "star rating data store has wrong type ('"..typeof(data).."') instead of 'map')" ]; let data = {}; } var num_votes = #data - (data[prop] != nil ? 1 : 0); // Fetch current rating var rating = data[prop] ?? 0; if (rating is not num) { let errors ..= [ "current results have wrong type ('"..typeof(rating).."' instead of 'num')" ]; let rating = 0; } else let rating = num.round(rating, 1); // can the current user vote? var can_vote = !user.anonymous && wiki.pagepermissions(path).update;
Output Generation
// Must have dekiapi extension installed! dekiapi(); // Image must be attached to this template var imgURI = thisTemplate.files["star.gif"].uri; <html> <head> // // CSS and Javascript // // CSS-based rating UI <style type="text/css"> " #page-top .star-rater td { margin: 0px; padding: 0px; } #page-top .star-rating, #page-top .star-rating a:hover, #page-top .star-rating a:active, #page-top .star-rating a:focus, #page-top .star-rating .current-rating { background: url("..imgURI..") left -1000px repeat-x; } #page-top .star-rating { position:relative; width:125px; height:25px; overflow:hidden; list-style:none; margin:0; padding:0; background-position: left top; } #page-top .star-rating li { display: inline; } #page-top .star-rating a, #page-top .star-rating .current-rating { position:absolute; top:0; left:0; text-indent:-1000em; height:25px; line-height:25px; outline:none; overflow:hidden; border: none; margin:0; padding:0; } #page-top .star-rating a:hover, #page-top .star-rating a:active, #page-top .star-rating a:focus { background-position: left bottom; } #page-top .star-rating a.star1 { width:20%; z-index:6; } #page-top .star-rating a.star2 { width:40%; z-index:5; } #page-top .star-rating a.star3 { width:60%; z-index:4; } #page-top .star-rating a.star4 { width:80%; z-index:3; } #page-top .star-rating a.star5 { width:100%;z-index:2; } #page-top .star-rating .current-rating { z-index:1; background-position: left center; } #page-top .star-rating a:active { outline: none; } // remove halo effect in FireFox " </style>; // Initialize Display <script type="text/javascript"> " $(function() { starRaterDisplayUpdate('"..table.."', "..rating..", "..num_votes.."); }); " </script>; // Set display based on current rating <script type="text/javascript"> " function starRaterDisplayUpdate(id, rating, votes) { var $starRater = $('#'+id); $starRater.find('.current-rating').css('width',(20*rating)+'%').text('Currently '+rating+'/5 stars'); $starRater.find('.current-status').text(rating+'/5 stars ('+votes+' vote'+(votes != 1 ? 's)':')')); $starRater.find('a').each(function() { this.blur(); }); } " </script>; // Code to update the page properties, largely cribbed from SteveB's "UpdateStore" template <script type="text/javascript"> " Deki.subscribe('"..@channel.."', null, function(c, m, d) { var store_data = '"..prop.."'; var api_uri = '"..p.api.."'; var property = 'urn:custom.mindtouch.com#' + store_data; Deki.Api.ReadPageProperty(api_uri, property, function(result) { var data = eval('(' + (result.value || '{}') + ')'); for (var k in m) if (k != '_id_') data[k] = m[k]; var id = m['_id_']; var total = 0; var num_votes = 0; for (var k in data) { if (k != store_data) { ++ num_votes; total += Number(data[k]); } } var current_rating = Math.round(10*(num_votes ? total/num_votes : 0))/10; data[store_data] = current_rating; if(result.etag) Deki.Api.UpdatePageProperty(result.href, YAHOO.lang.JSON.stringify(data), result.etag, function() { starRaterDisplayUpdate(id, current_rating, num_votes); }, function(result) { alert('Error updating store (status: '+result.status+' - '+result.text+')'); } ); else Deki.Api.CreatePageProperty(api_uri, property, YAHOO.lang.JSON.stringify(data), function() { starRaterDisplayUpdate(id, current_rating, num_votes); }, function(result) { alert('Error creating store (status: '+result.status+' - '+result.text+')'); } ); }, function(result) { alert('An error occurred reading the store (status: '+result.status+' - '+result.text+')'); } ); }, null); " </script>; </head>; <body> //UI Table <table class="star-rater" id=(table) border="0" cellpadding="0" cellspacing="0" style=("padding:0px; margin:3px;" .. (pageMode ? "float:right;" : ""))><tbody> if (can_vote) <tr><td align="center" style="font-size: small;"> msg </td></tr>; <tr><td align="center"><ul class='star-rating'> <li class='current-rating'> </li> if (can_vote) foreach (var i in [1,2,3,4,5]) <li><a href='#' title=(i.." star out of 5") class=("star"..i) onClick=("Deki.publish('"..@channel.."', {'_id_':'"..table.."','"..user.name.."':"..i.." });")> i </a></li>; </ul></td></tr>; <tr><td class='current-status' align="center" style="font-size: x-small"> </td></tr>; </tbody></table>; </body>; </html>;
Comments