Template:Star Rater

    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
    • MindTouch 10.0 or later.
    • You must attach the star.gif file to your template page.
    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:

    1. The star rater is floated to the right
    2. The message (if not specified above) defaults to "Rate this page:"
    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>;
    
    Tag page (Edit tags)
    • No tags
    Page statistics
    3300 view(s), 1 edit(s) and 12792 character(s)

    Comments

    You must login to post a comment.

    Attach file

    Attachments

    FileSizeDateAttached by 
     star.gif
    No description
    1120 bytes02:27, 13 Jun 2012AdminActions