火曜日, 4月 22, 2008

YahooUIのTabviewを使ったウィジット

たまにはBloggerネタでも タイトルの通りなんですが、YahooUIを利用したウィジットを見つけたので投稿してみます。 元ネタはHoctro's PlaceさんのIntroducing TabView Widget - Part 1ってやつです。 とりあえず、Hoctroさんの記事にはコメントを入れておいたんですが、勝手に紹介するな!!って怒られたらどうしよう。。。 結果的にはこんな感じになります。 主な特徴としては
  • 対象feedを元に一覧を作成する
  • なんと!他所さまのfeedを使える
  • 最新の投稿一覧とかコメントとかを見れる
  • ラベルで集約した結果を1つのタブとして表示できる
いろいろと準備が必要です。 注意事項として全文feedは使わないでください。 1:まず、肝になるJavaScriptを用意します。
/* ここはYahooUIを参照 */
<!-- Dependencies -->
<!-- Sam Skin CSS for TabView -->
<link href='http://yui.yahooapis.com/2.5.1/build/tabview/assets/skins/sam/tabview.css' rel='stylesheet' type='text/css'/>

<!-- JavaScript Dependencies for Tabview: -->
<script src='http://yui.yahooapis.com/2.5.1/build/yahoo-dom-event/yahoo-dom-event.js' type='text/javascript'/>
<script src='http://yui.yahooapis.com/2.5.1/build/element/element-beta-min.js' type='text/javascript'/>

<!-- OPTIONAL: Connection (required for dynamic loading of data) -->
<script src='http://yui.yahooapis.com/2.5.1/build/connection/connection-min.js' type='text/javascript'/>

<!-- Source file for TabView -->
<script src='http://yui.yahooapis.com/2.5.1/build/tabview/tabview-min.js' type='text/javascript'/>

<style type='text/css'>

/* ここからはウィジット用 */
.yui-content {
padding:1em; /* pad content container */
}

.yui-navset .yui-content {
border:1px solid #ccc;
}
.yui-navset .yui-nav .selected a, .yui-navset .yui-nav a:hover {
background-color:#fff;
}

.yui-navset .yui-nav li a {
background:#e5e5e5 url(http://developer.yahoo.com/yui/examples/tabview/img/round_4px_trans_gray.gif) no-repeat;
}
.yui-navset .yui-nav li a em {
background:transparent url(http://developer.yahoo.com/yui/examples/tabview/img/round_4px_trans_gray.gif) no-repeat top right;
padding:0.5em;
}

/* top oriented */

.yui-navset-top .yui-nav { margin-bottom:-1px; } /* for overlap, based on content border-width */
.yui-navset-top .yui-nav li a {
border-bottom:1px solid #ccc;
}

.yui-navset-top .yui-nav .selected a { border-bottom:0; }
.yui-navset-top .yui-nav .selected a em { padding-bottom:0.6em; } /* adjust height */
</style>

// ここにウィジット側からパラメータを与えます。
<script type='text/javascript'>
// Developed by Hoctro - All rights reserved 2007
// This credit must be included in all your derived usages.

// "cb" is intended to be a common library, where different widgets would
// utitlize the shared operations such as getTitle, getLink, etc. from a json object.
var cb = {
// search function requires these parameters:
// 1. query: a blogger address, such as "hoctro.blogspot.com",
// 2. type: type of return data, either "comments" or "posts",
// 3. start: the start-index parameter (where to start extracting data)
// 4. increment: the number of elements the json will get back. (the smaller value, the faster time to travel back)
// 5. func: the returned function the json object will feed.

search: function(query, type, start, increment, func) {
var script = document.createElement('script');
script.setAttribute('src', 'http://' + query + '/feeds/' + type + '/default?alt=json-in-script&start-index='
+ start + '&max-results=' + increment + '&callback=' + func + '&orderby=published');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
},

// searchLabel function return a result of posts w/ a label query
// it requires these parameters:
// 1. query: a blogger address, such as "hoctro.blogspot.com",
// 2. an array of labels
// 3. func: the returned function the json object will feed.
searchLabel: function(query, label, func) {
var script = document.createElement('script');
script.setAttribute('src', 'http://' + query + '/feeds/posts/default/-/' + encodeURIComponent(label) +
'?alt=json-in-script&callback=' + func + '&orderby=published');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
},

// getTotalResults needs the json object, and it'll return the total number of comments (or posts) of the blog.
getTotalResults: function(json) {
return json.feed.openSearch$totalResults.$t;
},

// getStartIndex gets the start index of a search inside an json object.
getStartIndex: function(json) {
return json.feed.openSearch$startIndex.$t;
},

// getLink return a href link if "name" matches the content inside "a" tags) of the link
getLink: function(entry, name) {
var alturl;

for (var k = 0; k < entry.link.length; k++) {
if (entry.link[k].rel == name)
alturl = entry.link[k].href;
}
return alturl;
},

// getTitle gets the title of the title of an entry of a json object.
getTitle: function(entry) {
return entry.title.$t;
},

// getContent gets the content inside an entry of a json object.
getContent: function(entry) {
return entry.content.$t;
},

// getCommentAuthor: gets the commenter name inside an entry of a json object.
getCommentAuthor: function(entry) {
return entry.author[0].name.$t;
},

// Given a json label search, this function return the decoded label.
getLabelFromURL: function(json) {
for (var l = 0; l < json.feed.link.length; l++) {
if (json.feed.link[l].rel == 'alternate') {
var raw = json.feed.link[l].href;
// The next two lines are borrowed from Ramani's Neo Template
// code. Thanks Ramani!
var label = raw.substr(raw.lastIndexOf('/')+1);
return decodeURIComponent(label);
}
}
},
txt : function (s) {
return s + " Widget by <a href='http://hoctro.blogspot.com" + "'>Hoctro</a>";
}
};
</script>
こんな感じです。 このオブジェクトを操作するようなウィジットになってます。 2:ウィジット側を実装
<b:widget id='HTML1' locked='false' title='MultiTab Widget' type='HTML'>
<b:includable id='main'>
<div class='widget-content'>
<!-- only display title if it's non-empty -->
<b:if cond='data:title != ""'>
 <h2 class='title'/>
</b:if>
<div id='doc'>
 <div>
   <h2>がらのうつうつ日記 TabView Widget</h2>
   <div class='yui-navset' id='multiTab1'/>
 </div>
</div>
<div id='103'/>
</div>

<script type='text/javascript'>
// Developed by Hoctro - All rights reserved 2007
// This credit must be included in all your derived usages.
var p1 = document.createElement('h6');
document.getElementById('103').appendChild(p1);
p1.innerHTML = cb.txt('TabView');

function listOneTab(json, tabView, title, act) {
 var label = '';
 var text = '';
 var nPost = 10;

 if (title == '')
   label += cb.getLabelFromURL(json);
 else
   label += title;

 text += '<div class=' + "tabview" + ' id=' + label + '><ul>';

 var numberPost = (json.feed.entry.length <= nPost) ? json.feed.entry.length : nPost;

 for (var i = 0; i < numberPost; i++) {
   var entry = json.feed.entry[i];
   text += '<li>' + '<a href="' + cb.getLink(entry, 'alternate')
+ '">' + cb.getTitle(entry) + '</a></li>';
 }

 text += '</ul></div>';

 tabView.addTab( new YAHOO.widget.Tab({
   label: label,
   content: text,
   active : act
 }));
}

var blog1 = 'utsuutsu.blogspot.com';
var tabView1 = new YAHOO.widget.TabView('multiTab1');
var labels1 = ['日記','うつ','開発'];
function listTab1(json) {
 listOneTab(json, tabView1, '', false);
}
function listLatestPostsTab1(json) {
 listOneTab(json, tabView1,'最新の投稿', true);
}
function listLatestCommentsTab1(json) {
 listOneTab(json, tabView1, '最新のコメント', false);
}

// Activating calls!

// Latest Posts
cb.search( blog1, 'posts', 1, 25, 'listLatestPostsTab1');

// Latest Comments
cb.search( blog1, 'comments', 1, 25, 'listLatestCommentsTab1');

// Preferred Labels
for (var i=0; i < labels1.length; i++)
 if (labels1[i]) cb.searchLabel(blog1, labels1[i], 'listTab1');
</script>
</b:includable>
</b:widget>
気をつけておかないといけないことが数点あります。
  • <h2>がらのうつうつ日記 TabView Widget</h2>はお好きなタイトルを
  • labels1 には集約して表示したいラベルを
  • nPostには一度に表示したい件数を
3:僕が勝手に変更している部分 タブ内のスタイル操作の為にulタブにtabviewという名前のclass属性を追加しています。 このスタイルを
]]></b:skin>
の手前に定義しています。
/*tabview
----------------------------------------------- */
.tabview li {
text-align: left;
}
とりあえず、今はこれしか入れてないですけど。。。 これでもう少し勝手が効くかな?
こういうことができるってことは、他のYahooUIを使って楽しいことができそうでもあるなぁ~

0 件のコメント:

failed to read qemu headerのときのメモ

かなり久々。。。 忘れないようにここに書きこんでおく。 ちょっとした手違いで libvirtでイメージを起動しようとすると failed to read qemu header なんておっしゃられて起動しない。。。 vmwareserverを使って...