-
Ajaxアプリで使う「読み込み中...」アイコンが作れます。前景背景色が指定できるのでgood!
「del.icio.us JSON Feedsを使ってブックマークをサムネイル付きで表示する」の続きです。今回は「JSON Post Feeds」のコールバックの仕組み(JSONPともいう)を使ってみました。↓こんな感じです。
見た目や機能は前回のAjaxアプリと同じですが、コールバック関数を指定してJSON Post Feedsを取り込むという違いがあります。
JSON Post Feedsは次のようなscript要素を使って取り込んでいます。このとき「callback」というパラメータにというコールバック関数の名前を指定しています。
<script type="text/javascript" src="http://del.icio.us/feeds/json/developmentor?count=20&callback=onPosts" ></script>
このscript要素は次のようなJavaScript要素を出力します。callbackパラメータで指定した「onPosts」という関数を実行します。このとき関数の引数がブックマークのオブジェクトの配列になります。
onPosts([{ "u": "http://astore.amazon.co.jp/", "n": "11月15日から正式版がスタートしました。自由度も上がって使ってみたい気にさせます。", "d": "Amazonアソシエイト・プログラム インスタントストア", "t": ["amazon", "affiliate"] }, ... ]);
onPostsという関数を用意しておき、引数のブックマークのオブジェクトを使ってWEBページにブックマークのリストを表示しています。リストの表示方法は前回と同じです。
function onPosts(posts) { ... }
今回はあらかじめWEBページにscript要素を埋め込んでいますが、さらにJavaScriptを使ってscript要素を動的生成すれば、よりインタラクティブなAjaxアプリにもなるでしょう。どんどんJSONPという仕組みを活用しましょう。
「AOLVS Ajax APIを使ってビデオの主要なデータを表示してみる」の補足です。
ビデオの主要なデータといいながら「タグ」という重要なデータを紹介し忘れていました。そこで、ビデオに付与されたタグも表示するように改良しました。↓こんな感じです。
見やすいようにタグは文字色をグリーンで表示しています。
- Video.tags
- ビデオに付与されたタグです。タグをカンマ「,」区切った文字列です。タグがないときはundefinedになります。
「del.icio.us JSON Feeds」を使ってブックマークをサムネイル付きで表示してみました。↓こんな感じです。
ブックマークのサムネイルは「MozShot」というサービスを使って表示しています。ほかにもサムネイルを生成するサービスはありますが、「MozShot」のサムネイルは、周囲がボヤ~と浮いたような影になるので、そのデザインが気に入って使ってみました。
ブックマークを表示するJavaScriptコードは「JSON Post Feeds」のexampleを改造したものです。
JSON Post Feedsは次のようなscript要素を使って取り込みます。アドレスの「developmentor」はdel.icio.usの「username」に対応しますので、あなたのusernameに置き換えてください。「count」は取り込むブックマークの数を表します。最大は100件までみたい。
<script type="text/javascript" src="http://del.icio.us/feeds/json/developmentor?count=20"></script>
このscript要素は次のようなJavaScriptコードを出力します。「Delicious.posts」という配列にブックマークのオブジェクトが新しい順序で格納されます。
if(typeof(Delicious) == 'undefined') Delicious = {}; Delicious.posts = [{ "u": "http://astore.amazon.co.jp/", "n": "11月15日から正式版がスタートしました。自由度も上がって使ってみたい気にさせます。", "d": "Amazonアソシエイト・プログラム インスタントストア", "t": ["amazon", "affiliate"] }, ... ];
ブックマークのオブジェクトは次のプロパティを持ちます。プロパティの文字コードはUTF-8です。ただし、JavaScriptエンコードされていませんので、状況によっては都合が悪いこともあるかもしれません。
- u
- ブックマークのURLです。ブックマークをpostするときのurlに対応します。
- d
- ブックマークのタイトルです。ブックマークをpostするときのdescriptionに対応します。
- n
- ブックマークのメモです。ブックマークをpostするときのnotesに対応します。notesを省略したブックマークはこのプロパティを持たずundefinedになります。
- t
- ブックマークのタグです。ブックマークをpostするときのtagsに対応します。このプロパティは配列です。またtagsを省略したブックマークはこのプロパティを持たずundefinedになります。
JSON Post Feedsはコールバックを使った取り込み(JSONPという仕組み)にも対応しています。JSON Post Feedsのコールバックの使い方は、後日紹介しようと考えています。
-
最近よく見るオレンジの電波みたいなアイコンの配布元です。IE 7でも採用していますね。
BlosxomでBLOGRANGR 2.0の「BLOGRANGER検索 初号機」へのリンクを簡単に指定できるプラグインを作成してみました。blograngerプラグインといいます。blograngerプラグインはBlosxom 2.0に対応しています。
blograngerプラグインはエントリの中で、次のようにaタグのリンク先を指定できます。
- <a href="t:KEYWORD">TEXT</a>
- 「<a href="t:携帯電話">BLOGRANGER検索</a>」のようにaタグのリンク先に「t:」とキーワードを指定すると、「BLOGRANGER検索」のようにBLOGRANGER検索へのリンクを表示します。そのリンク先は指定したキーワードでブログを検索し、トピックで選ぶタブを使って検索結果を表示します。↓こんな感じです。
- <a href="b:KEYWORD">TEXT</a>
- 「<a href="b:携帯電話">BLOGRANGER検索</a>」のようにaタグのリンク先に「b:」とキーワードを指定すると、「BLOGRANGER検索」のようにBLOGRANGER検索へのリンクを表示します。そのリンク先は指定したキーワードでブログを検索し、ブロガーで選ぶタブを使って検索結果を表示します。↓こんな感じです。
- <a href="r:KEYWORD">TEXT</a>
- 「<a href="r:携帯電話">BLOGRANGER検索</a>」のようにaタグのリンク先に「r:」とキーワードを指定すると、「BLOGRANGER検索」のようにBLOGRANGER検索へのリンクを表示します。そのリンク先は指定したキーワードでブログを検索し、リンク先で選ぶタブで検索結果を表示します。↓こんな感じです。
- <a href="o:KEYWORD">TEXT</a>
- 「<a href="o:携帯電話">BLOGRANGER検索</a>」のようにaタグのリンク先に「o:」とキーワードを指定すると、「BLOGRANGER検索」のようにBLOGRANGER検索へのリンクを表示します。そのリンク先は指定したキーワードでブログ検索を実行し、感想で選ぶタブを使って検索結果を表示します。↓こんな感じです。
BLOGRANGER検索のURLフォーマットは公開されていないので、blograngerプラグインでは、URLを手打ちで試しながら期待する動作をした中で、もっとも簡単で短かったURLフォーマットを採用しました。ですので、今後も同じように動作するかどうかは保証できません。
BLOGRANGER検索のキーワードは「UTF-8」でエンコードする必要があります。そのためblograngerプラグインでは、次のようにキーワードの文字コードをJcodeモジュールを使ってUTF-8に変換しています。
## sub kanjicode { my ($textref, $kanjicode) = @_; use Jcode; &Jcode::convert($textref, $kanjicode); return $$textref; }
変換前のキーワードの文字コードはJcodeモジュールで自動検出しています。文字コードの自動検出やJcodeモジュールといった少し古い仕組みが許容できないときは、この「kanjicodeサブルーチン」を改良して別の仕組みに置き換えてください。またそもそもBlosxomをUTF-8ベースで動かしているならコメントアウトしてもよいでしょう。
blograngerプラグインのダウンロードは↓こちらからどうぞ。
- blogranger-0.1.0.zip -- (2006-11-22) MD5: fcc434ab3434f1acb09c4baa58c5a626
このブログは主に「goo RSSリーダーアプリ版 ブログライター機能」を使って書いているのですが、Windowsの調子が悪くなったとき、書きかけの記事までもが「oh! no!!!!!!」となってしまうことがあります。少し長めの記事だったりするとかなりショックだったりします。
そこで、gooブログライターで書きかけの記事を救出する方法を探してみました。
※以下の方法は保証外です。自己責任でお願いします。私はいかなる責任も追いません。
書きかけの記事がgooブログライターの記事一覧から消えていても、「下書き保存」していればまだその記事自体は残っているかもしれません。次のディレクトリの中に「entry_############.plist」というファイルがあるので、タイムスタンプ(更新日時ともいう)の新しい順に確認していきます。
C:Documents and Settings<user>Application DatagooRSSReaderweblogs
この「entry_############.plist」というファイルはXMLファイルです。ですので、メモ帳などのテキストエディタで開けます。運がよければXMLファイルの中から書きかけの記事が見つかるでしょう。
記事が見つかったら、その記事をコピーしてブログライターに貼り付けます。そして、記事の続きを書けばよいでしょう。見つからなかったら諦めるしかないですね。
余談ですが、ということはgooブログライターを使うと、ブログの記事をファイルとして手元にダウンロードできるってことですね。いいかも。
「Lyase.View Ajax指向のシンプルテンプレートエンジン(その3)」まではLyase.Viewの使い方を紹介しました。ここではLyase.Viewをより深く理解するため、Lyase.Viewのソースコードを読みながらその特徴に迫ります。
↓Lyase.Viewがテンプレートの文字列を解析するソースコードです。Lyase.Viewはテンプレートを解析しながら、そのテンプレートをJavaScriptコードに変換するという方法を使っています。
「new Function("context", parsed.join(""))」とあるように、Lyase.Viewは1つのテンプレートの文字列から1つのJavaScript関数を生成します。Functionオブジェクトを使って、動的にJavaScript関数を生成しているのがポイントです。Functionオブジェクトってこういう使い方もあるんですね。詳しくは「Mozilla Developer Center」の「Core JavaScript 1.5 Reference」を見てください。
Lyase.View = { _cache : {}, parse : function(template, id) { var self = Lyase.View,parsed = ["var __out=[],render = Lyase.View.render;"] var tokens = template.split("<%"); for(var i = 0, l = tokens.length; i<l; i++) { var token = tokens[i]; if(token.indexOf("%>") == -1){ parsed.push(self._string(token)); continue; } var parts = token.split("%>"); parsed.push(self[(parts[0].charAt(0) == "=")?"_value":"_code"](parts[0])); parsed.push(self._string(parts[1])); } parsed.push("return __out.join('');"); var templateFunc = new Function("context", parsed.join("")); if(id) self._cache[id] = templateFunc; return templateFunc; },
テンプレートの文字列から生成したFunctionオブジェクトは、テンプレートの識別子に関連付けてキャッシュしています。「using innerHTML(ページ中の要素として)」のときは要素IDを、「using a template file(外部ファイルとして)」のときはファイルパスを識別子に使います。そのため、同じテンプレートを繰り返し使ったとしても、テンプレートを解析するのは1度だけです。ただし例外があり、「using text(JavaScriptの文字列として)」のときはキャッシュされません。
render : function(options, values) { var self = Lyase.View, template, id; if(options.text) return self.parse(options.text, null)(values); if(options.element) var element = $(options.element); id = (options.file) ? options.file : element.id; if(self._cache[id]) return self._cache[id](values); if(options.element) { template = self._elementTemplate(element); }else { template = (new Ajax.Request(options.file,{asynchronous : false})).transport.responseText; } return self.parse(template, id)(values); },
「using a template file(外部ファイルとして)」のときはAjax.Request(prototype.js)を使って、テンプレートを外部ファイルから取得しますが、そのときHTTPサーバ側でエラーが発生しても、そのエラーレスポンスの内容をテンプレートして解釈しています。この振る舞いが許容できないときは、1例として次のようにソースコードを改良してエラーが発生したときの振る舞いを追加するとよいでしょう。
var request = new Ajax.Request(options.file, {asynchronous : false}).transport; template = request.status!=200 ? '...' : request.responseText;
Lyase.Viewの紹介は今回(その4)でおしまいです。
WEBサイトのアカウントパスワードを変更したとき、デスクトップ側の指紋認証ログオンパスワードを変更する手順を忘れてしまい、イライラすることがあるので、この機会に手順をメモしておきます。
![]() |
Microsoft Fingerprint Reader [DG2-00003]![]() ![]() ![]() ![]() ![]() by G-Tools |
はじめにパスワードを変更するWEBサイトを開きます。するとブラウザの右上に指紋認証ログオンのアイコンが現れるので、このアイコンをクリックします。指紋認証ログオン用のアカウントの編集は、このアイコンしか入口がないようなので、ついつい忘れてしまうのです。
すると、次のようなダイアログが表示されるので、指紋認証します。
すると、指紋認証ログオン用のアカウントが編集できます。
-
11月15日から正式版がスタートしました。自由度も上がって使ってみたい気にさせます。
del.icio.usの「daily blog posting」を使ってgooブログにブックマークを自動投稿する方法を紹介します。
はじめにgooブログの「ブログライター機能」を有効にします。gooブログの編集画面から「個人情報」を開きます。↓こんな感じです。
その中に「ブログライター機能(XML-RPC)」の項目がありますので「使用する」を選択します。さらにパスワードを指定します。このパスワードは「daily blog posting」を設定するときに使います。
次にdel.icio.usの「daily blog posting」を設定します。del.icio.usのsettingsから「daily blog posting」を開きます。↓こんな感じです。
「add a new thingy」を選択し、あなたのgooブログに情報に合わせて、次のように設定します。
- job_name
- 何か好きな名前を付けます。私は「blog.goo.ne.jp/developmentor」というgooブログのアドレスを指定しました。
- out_name
- goo IDを指定します。私は「developmentor」を指定しました。
- out_pass
- gooブログの「ブログライター機能(XML-RPC)」のパスワードを指定します。上で指定したパスワードです。goo IDのパスワードではありません。
- out_url
- 「
http://blog.goo.ne.jp/xmlrpc.php 」を指定します。固定です。 - out_time
- ブックマークを投稿する時刻0~23を指定します。私は「15」を指定しました。日本は標準時間で+9の差がありますので、「15」だとちょうど0時を指定したことになります。↓換算表を使ってください。
0 9時 1 10時 2 11時 3 12時 4 13時 5 14時 6 15時 7 16時 8 17時 9 18時 10 19時 11 20時 12 21時 13 22時 14 23時 15 0時 16 1時 17 2時 18 3時 19 4時 20 5時 21 6時 22 7時 23 8時 - out_blog_id
- 「1」を指定します。固定です。
- out_cat_id
- ブックマークを投稿するカテゴリIDを指定します。あなたのgooブログの何れかのカテゴリIDを指定します。私は「40e2265ec82cf7ede36bced6896f3cf9」を指定しました。カテゴリIDはあなたのgooブログのメニューからカテゴリを選択することで調べられます。カテゴリを選択した後、ブラウザのアドレスバーに注目してください。そのアドレスが「http://blog.goo.ne.jp/developmentor/c/40e2265ec82cf7ede36bced6896f3cf9」であれば、カテゴリIDは「40e2265ec82cf7ede36bced6896f3cf9」になります。
これで完了です。
指定した時刻になると、gooブログに最近1日のブックマークが自動投稿されます。こんな感じです。指定した時刻ぴったりには投稿されません。15分から30分ほど遅くなるようです。なお、最近1日のブックマークがないときは投稿されません。
最後にgooブログの「daily blog posting」を設定するにあたり、次のブログがとても参考になりました。ありがとうございます。
「Googleマップの吹き出しをタブ形式で表示する」の中で、東京近郊レジャースポット案内というAjaxアプリを作りましたが、さらにレジャースポットの定義を別のファイルに移動し、データとWEBページを分離してみました。↓こんな感じです。
WEBページのJavaScriptコードにあったレジャースポットの定義を…
var spots = [ // {lat: 緯度, lng: 経度, url: ブックマークURL} {lat: 35.660347, lng: 139.729121, url: [ 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1510', 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1789' ]}, // 六本木ヒルズ …途中、省略… ];
次のように、WEBページとは別のテキストファイルに移動してアップロードします。ここではファイル名を「googlemapsjson.txt」としました。
googlemapsjson.txt
[ {lat: 35.660347, lng: 139.729121, url: [ 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1510', 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1789' ]}, {lat: 35.665246, lng: 139.712319, url: [ 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1556', 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1790' ]}, {lat: 35.634017, lng: 139.878595, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1557'}, {lat: 35.705646, lng: 139.751887, url: [ 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1569', 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1791' ]}, {lat: 35.639511, lng: 139.760170, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1570'}, {lat: 35.673770, lng: 139.762745, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1577'}, {lat: 35.707127, lng: 139.753046, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1578'}, {lat: 35.664915, lng: 139.762487, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1579'}, {lat: 35.621966, lng: 139.750750, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1580'}, {lat: 35.654995, lng: 139.796476, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1581'}, {lat: 35.664897, lng: 139.766908, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1586'}, {lat: 35.658639, lng: 139.745407, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1587'}, {lat: 35.689492, lng: 139.691699, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1588'}, {lat: 35.672428, lng: 139.755728, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1589'}, {lat: 35.676368, lng: 139.699359, url: 'http://ranger.labs.goo.ne.jp/rpc/partsview.php?key=1590'} ]
WEBページのロードが完了したタイミングで、レジャースポットの定義をAjax.Request(prototype.js)を使って取得します。
function load() { var map = new GMap2(document.getElementById('map')); map.addControl(new GSmallMapControl()); map.addControl(new GMapTypeControl()); map.addControl(new GOverviewMapControl()); map.setCenter(new GLatLng(35.686302, 139.74575), 12);
Ajax.Requestの引数には前述の「googlemapsjson.txt」を指定します。そして、その「googlemapsjson.txt」を取得して、その取得したテキストをJavaScriptとして評価します。また失敗したときは、エラーメッセージを表示して終了します。
var request = new Ajax.Request('googlemapsjson.txt', { method: 'get', asynchronous : false }).transport; if (request.status!=200) return alert(request.status+' '+request.statusText); var spots = eval('('+request.responseText+')');
以降は今までどおり、レジャースポットの定義にしたがって地図上にマーカーを配置していきます。
for (var i=0; i<spots.length; i++) map.addOverlay(createMarker(spots[i])); }