2008/06/25

Plurk - Widget

  Plurk 的官方版 widget 無法修改 logo,導致許多人 CSS 改了老半天,把所有的顏色都和 blog 調到一致了,最後卻和這顆火腿不搭:



  另外原始版本還有 SMALL 模式顯示亂掉、interval 功能在 IE 下不會動的問題。因此我花了一點時間把程式簡化,拿掉不需要的部份,調整了參數傳入方式並加上註解。有興趣的人可以把底下整段複製走,修改必要的參數與色彩後,加進 Blogger 裡。(別家的部落格我沒測過,請自行實驗,能用就算賺到)

修改重點:
  • 有加「/* */」附註的行,是較有機會改動的地方。
  • CSS 中的 background 可以選擇用顏色或底圖,我放了範例,但最後記得留下一筆就好。
  • JavaScript 裡面有一排連續的「PWARG_xxx」是參數設定,大部份和原本的名稱一樣。
  • PWARG_USERID:請參考 Plurk 畫面右下方「Share your plurk page with friends: 」的格子裡,「from_uid=」接著一串數字,把它填進去。當然如果你暗戀我的話,不改也沒關係。
  • PWARG_WIDGETLOGO:請自行製作適當大小的 logo,並同時調整 CSS 中的圖寬。
完整程式碼:


<style type="text/css">
.plurk-widget {
    font: 11px 'Lucida Grande', 'Lucida Sans Unicode','Lucida Sans Regular', Tahoma, Verdana, sans-serif;
    background: #cf682f;    /* 主版底色 */
    /* background: url('http://www.plurk.com/static/theme/image/wallpaper.png'); 主版底圖 */
    padding: 4px;
    border: 1px solid #a14a19;    /* 主版外框 */
    max-width: 300px;
    width: auto;    /* Widget 寬度 */
    position: relative;
    padding-top: 40px;
    color: black;    /* 文字顏色 */
    text-align: left;
    padding-bottom: 0;
}

.plurk-widget a {
    color: #126cb8 !important;    /* 鏈結, 包括個人暱稱與回應 */
    padding: 0 !important;
    border: none !important;
    background: none;
    text-decoration: underline;
}

.plurk-widget img {
    border: none !important;
}

.plurk-widget a:hover{
    text-decoration: underline!important;
}

.plurk-widget .plurk-logo {
    display: block;
    padding: 0;
    margin: 0 6px 8px 0;
    width: 40px;    /* logo 寬度 */
    position: absolute;
    right: 0;
    top: 4px;
    height: 31px;
    padding: 0 !important;
}

.plurk-widget .plurk-timeline {
    clear: both;
    overflow-x: hidden;
    overflow-y: scroll;
    background: #cae7fd;    /* 時間軸底色 */
    /* background: url('http://www.plurk.com/static/theme/image/water.gif'); 時間軸底圖 */
    word-wrap: break-word;
    border: 1px solid #99705f;    /* 時間軸外框 */
    padding: 3px 8px;
}

.plurk-widget .plurk-nickname {
    color: black;
    text-decoration: none;
    font-weight: bold;
}

.plurk-widget .plurk-message {
    background: url(plurk-widget-separator.gif) repeat-x left bottom;
    padding: 6px 0 10px 0;
    margin: 0 0 4px 0;
}

.plurk-widget .plurk-meta {
    font-size: 0.9em;
    text-align: right;
    color: #578ebd;    /* 留言時間文字顏色 */
    padding-top: 2px;
}

.plurk-widget .plurk-qualifier {
    border-right: 1px solid #333;
    border-bottom: 1px solid #333;
}

.plurk-widget .plurk-empty {
    margin: 5px 0 0 0;
    padding: 10px;
    background-color: #F0F8FF;
    color: #4c8cc2;
    text-align: center;
    border: 1px solid #4c8cc2;
}

.plurk-widget .plurk-empty strong {
    font-weight: bold;
    color: black;
    display: block;
}

.plurk-widget .call-action{
    font-size: 0.9em;
    color: #fadfd0;
    padding: 10px 0 5px 0;
}

.plurk-widget .call-action a{
    color: #5a3f30 !important;    /* 最底下的廣告鏈結文字顏色 */
    text-decoration: underline;
    font-weight: normal;
}
</style>
<script id="PlurkWidgetScript" type="text/javascript">
/**
* Plurk Widget
* ------------
*
* Supported parameters:
*
*    - PWARG_USERID    the user_id whose plurks we want to display
*    - PWARG_HEIGHT    the height in pixels (has no effect if CSS is disabled)
*    - PWARG_NOCSS        set to "true" if you don't want any CSS applied
*    - PWARG_INTERVAL    the reloading interval in seconds
*            (30 per default, 0 for no reloading at all.)
*    - PWARG_CHUNK    the number of plurks in the widget
*    - PWARG_WIDGETLOGO    the logo we want to display
*
* If you are an advanced user and want to style the widget with custom CSS,
* here are the classes the widget uses:
*
* plurk-widget        the overall div that wraps the widget
* plurk-logo        a div that is usually used to display the logo
* plurk-timeline    the div containing the messages on the timeline
* plurk-loading-pane    a div that is displayed while data is retrieved
* plurk-message    a div that contains the message of a user
* plurk-nickname    a link to the users's profile
* plurk-qualifier    the span for the qualifier
* plurk-qualifier-x    the span for the qualifier x (x == says, thinks etc)
*
* For further information, you can reference the css file at
*    http://www.plurk.com/static/widget/widget.css
*
* (c) Copyright 2008 by Galt Networks.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* ------------
* Original version of this script:
*    http://www.plurk.com/static/widget/plurkwidget.js
*
* Modified by Sorry (http://www.plurk.com/user/sorry)
* Version 0.3
* 2008/6/25
*/

;(function() {
    
    // globals and constants
    var
        PWARG_SERVERURL = 'http://www.plurk.com',
        PWARG_USERID = 1418700,    /* from_uid=xxxxxxx */
        PWARG_HEIGHT = 300,    /* Widget 高度 */
        PWARG_NOCSS = 'true',
        PWARG_INTERVAL = 0,
        PWARG_CHUNK = 10,
        PWARG_WIDGETLOGO = 'http://www.plurk.com/static/creatures/small/1.png',    /* 上方的 logo */

        QUALIFIER_COLORS = {
            is:    '#e57c43', says:    '#E2560B', feels:    '#2D83BE',
            thinks:    '#689CC1', wants:    '#8DB241', wishes:    '#5BB017',
            has:    '#7A9A37', loves:    '#B20C0C', hates:    '#111111',
            asks:    '#8361bc', will:    '#B46DB9', was:        '#525252',
            had:    '#8C8C8C', likes:    '#CB2728', shares:    '#A74949',
            gives:    '#620E0E'
        },
        TIME_UNITS = [
            [60 * 60 * 24 * 30, 'month'],
            [60 * 60 * 24 * 7, 'week'],
            [60 * 60 * 24, 'day'],
            [60 * 60, 'hour'],
            [60, 'minute']
        ],
        widget, lastRequest, fish, timeline, options;

    // general purpose helpers
    function each(s, f) {
        if (!s) return; var r;
        if (s.length !== undefined)
            for (var x = 0, y = s.length; x < y; ++x) {
                if (typeof (r = f.call(s[x], x)) !== 'undefined')
                    return r;
            }
        else for (var k in s)
            if (typeof (r = f.call(this, k, s[k])) !== 'undefined')
                return r;
    }

    // formatting
    function timedelta(d) {
        var delta = ((new Date()).getTime() - d.getTime()) / 1000, value;
        return each(TIME_UNITS, function() {
            if ((value = Math.floor(delta / this[0])) > 0)
                return value + ' ' + this[1] + (value != 1 ? 's' : '');
        }) || '0 minutes';
    }

    // DOM
    function $fnGetElmt(n) { return document.getElementsByTagName(n)[0]; }
    function $fnCreateElmt(n, a) {
        var rv = document.createElement(n);
        each(a, function(k, v) { rv.setAttribute(k, v); });
        return rv;
    }
    function $$fnAppendElmt(p, n, a) { return p.appendChild($fnCreateElmt(n, a)); }
    function $fnAppendText(n, t) { n.appendChild(document.createTextNode(t)); return n; }
    function $fnAppendHtml(n, h) { var t = $$fnAppendElmt(n, 'span'); t.innerHTML = h; return n; }

    // CSS
    function css(n, a, c) {
        each(a, function(k, v) { n.style[k] = v; });
        if (c) n.className = c; return n;
    }
    function hide(e) { e.style.display = 'none'; return e; }
    function show(e) { e.style.display = ''; return e; }

    // communication system
    if (!this.$__plurkWidgetReceiveData) {
        $__plurkWidgetReceivers = [];
        $__plurkWidgetReceiveData = function(data) {
            $__plurkWidgetReceivers[data.receiverID](data);
        }
    }
    var receiverID = $__plurkWidgetReceivers.length;
    $__plurkWidgetReceivers.push(function(data) {
        lastRequest.parentNode.removeChild(lastRequest);
        if (data.plurks) updatePlurks(data.plurks, data.private);
        lastRequest = null;
    });

    // widget code
    function initializeWidget() {
        if (PWARG_NOCSS !== 'true')
            $$fnAppendElmt($fnGetElmt('head'), 'link', {
                href:    PWARG_SERVERURL + '/static/widget/widget.css',
                rel:    'stylesheet',
                type:    'text/css'
            });
        css(widget, {visibility: 'hidden'});
        var logo = css($$fnAppendElmt(widget, 'a', {href: PWARG_SERVERURL + '/redeemByWidget?from_uid=' + PWARG_USERID}), {
            background: 'url(' + PWARG_WIDGETLOGO + ') no-repeat 0 0'
        }, 'plurk-logo');
        timeline = css($$fnAppendElmt(widget, 'div'), {
            height:         (PWARG_HEIGHT || 300) + 'px'
        }, 'plurk-timeline');
        fish = css($$fnAppendElmt(timeline, 'div'), {
            background:    'url(' + PWARG_SERVERURL + '/static/loading.gif) no-repeat center center',
            height:        '90px'
        }, 'plurk-loading-pane'),
        callLink = $$fnAppendElmt(widget, 'div'),
        callLink.innerHTML = '<a href="'+ PWARG_SERVERURL + '/redeemByWidget?from_uid=' + PWARG_USERID
            + '">一起來體驗 Plurk 吧</a>',
        callTo = css(callLink, null, 'call-action');
        requestPlurks();
        if (PWARG_INTERVAL && PWARG_INTERVAL !== '0')
            setInterval(requestPlurks, (parseInt(PWARG_INTERVAL, 10) || 30) * 1000);
    }

    function requestPlurks() {
        if (lastRequest) return;
        hide(fish);
        lastRequest = $$fnAppendElmt($fnGetElmt('head'), 'script', {
            type:    'text/javascript',
            src:    PWARG_SERVERURL + '/API/Widget.getUserPlurks?'
                    + 'user_id=' + PWARG_USERID
                    + '&receiver_id=' + receiverID
                    + '&per_chunk=' + PWARG_CHUNK
        });
    }

    function updatePlurks(plurks, is_private) {
        timeline.innerHTML = '';
        timeline.appendChild(show(fish));
        if (plurks.length) each(plurks, function(idx) {
            var plurk = css($$fnAppendElmt(timeline, 'div'), null, 'plurk-message');            
            $fnAppendText(css($$fnAppendElmt(plurk, 'a', {href: PWARG_SERVERURL + '/user/' + this.username}),
                 null, 'plurk-nickname'), this.username);
            if (this.qualifier != ':') {
                $fnAppendHtml(plurk, ' ');
                var shade = QUALIFIER_COLORS[this.en_qualifier];
                $fnAppendText(css($$fnAppendElmt(plurk, 'span'), {
                    backgroundColor:    shade,
                    padding:        '0 3px 0 3px',
                    color:            'white'
                }, 'plurk-qualifier plurk-qualifier-' + this.en_qualifier),
                     this.qualifier);
            }
            $fnAppendHtml(plurk, ' ' + this.content);
            $fnAppendText($$fnAppendElmt($fnAppendText(css($$fnAppendElmt(plurk, 'div'), null, 'plurk-meta'),
                 timedelta(this.pub_date) + ' ago | '), 'a', {
                href:    PWARG_SERVERURL + '/p/' + (this.id).toString(36),
                target:    '_blank'
            }), this.responses == 1 ? '1 response' : this.responses + ' responses');
        });
        else {
            var empty = css($$fnAppendElmt(timeline, 'div'), null, 'plurk-empty');
            $fnAppendText($$fnAppendElmt(empty, 'strong'), 'Ouch. ');
            $fnAppendText(empty, is_private
                ? '抱歉, 你設定了 private 屬性, 別人不能讀取你的 plurk. 這個 widget 沒有東西可以顯示.'
                : '你沒有 plurk 可以顯示. 先去寫個幾句吧 :).'
            );
        }
        hide(fish);
        css(widget, {visibility: 'visible'});
    }

    // widget setup
    widget = css($fnCreateElmt('div'), null, 'plurk-widget');
    var options = document.getElementById('PlurkWidgetScript');
    options.parentNode.replaceChild(widget, options);
    initializeWidget();

})();
</script>

  最後,不管你改爛了什麼,都不要來找我。我一概不負責任。

2 則留言:

靜靜地生活 提到...

感謝你的努力,側邊白色的撲浪看起來很漂亮,我研究看看怎麼合我的部落格

jiajou 提到...

已經用好了,幾乎都是套用你的,只有改了logo與連結顏色,謝謝你的程式碼。