August 2006

Entries Title

Web 2.0 アプリの階層構造 by Tim O'reilly

Date
2006-08-29 (Tue)
Category
Translation

後半部分を終えて、全体少し手を入れました。


Levels of the Game: Web 2.0 アプリの階層構造

著者: Tim O'reilly
翻訳: Takashi Mizohata

Jim Fallow の、“Web 2.0 アプリだけを使う2週間”という Technology Review の記事を読んでいると、『なんて奇妙なことするんだ!そりゃまるで、車の居住性を確かめるのに、自分のベッドではなく車のバックシートで、2週間快眠実験をするみたいなもんだ』と思った。Fallow は鋭いし、おもしろい指摘(それについては後述)もいくつかあるけれど、彼のしたことは普通の人々にとって Web 2.0 だけで頭をいっぱいにすることが、どれだけ大変かを明らかにしたんだ。『Web 2.0 の最も重要な前進は、Ajax がこれほど広範に採用採用されたということのようだが』と彼は云うが、なんていうかな、それはよくある間違いだよ。

Ajax を使っただけ、かつ Web 上にあるっていうだけでは、Web 2.0 アプリはできない。(Fallow は Dodgeball を最初に挙げている。アプリの検証をする時に “What is Web 2.0?[訳注: 日本語訳はWeb 2.0:次世代ソフトウェアのデザインパターンとビジネスモデル(前編)を参照]”の記事も間違いなく引いているけれど、その他のアプリに彼が言及する時よりもずいぶんといい加減だ。例えば、彼は Writely をテストケースの一つとして挙げて、Web 2.0 アプリのメリットを判断している。Writely のようなオンラインアプリケーションが、Word のようなローカルアプリケーションにどこまで到達しているのか。Writely は面白いけれど、Web 2.0 アプリの王道ってわけではないだろうね。)

こういった業界内の混乱を見て、僕は“Web 2.0度”の階層を思いついた。

Level 3: ネット上 *のみ* に存在できるアプリで、その本質的要素は、ネットワークから引き出されて人々やアプリをつなぐことができる。こういうアプリは、ネットワーク外部性をうまく利用して、より多くの人々をネットワークに動員する。例えば、EBay, craigslist, Wikipedia, del.icio.us, Skype(それにそう、Dodgeball もね)はここに当てはまる。これらのアプリは根本的に人々のオンライン上の活動に依っている。Web それ自体も同じような特徴を持っているし、Google やその他検索エンジンはだからこそ、それを活用しているのだ。(デスクトップ検索には、Web にあるようなページ同士のリンクないので、[Web上の] 検索エンジンが使っている技術は使えないので、それほどうまくいかない。)[検索エンジンの] Web 巡回は、つまり Web 2.0 の根本的営みで、検索行動をベースにした “Adsense for Content” などは、間違いなく“Web 2.0 の心”を持っているよね。このあいだ Google CEO の Eric Schmidt と話した時に、彼は自分の哲学と戦略をまとめてこう云った。『Internet と戦うな』。Web 2.0 アプリの階層構造の中で、最も高みにあるのはネットワークを包み込むようなことで、ネットワーク外部性がいかにして生まれるのかを理解し、自分のすることすべてでそれをうまく利用することができるものだ。

Level 2: オフラインでも存在できるけれど、オンラインにあることで独特の強みをもつようなアプリケーション。Flickr はまさにすばらしい見本だ。ローカルの写真管理ソフト(例えば iPhoto)にはない、オンラインコミュニティを活用することで特筆すべき力を持つ。実際の所、共有された写真データベース、オンラインコミュニティ、それに結果的に生み出されたもの(例えばタグデータベース)は、オフラインの競合者と Flickr とを区別する最たるものだ。そしてより徹底した Internet との付き合い方(例えば、アップロードされた写真のデフォルトが、“Public”な点)がオンラインに存在した先行者との違いになる。

Level 1: オフラインに存在することができ、かつ実際に存在するが、オンラインにすることで何かしらの追加機能がうまれるアプリケーション。Writely はまさにここにある。もし編集をコラボレーションをしたいなら、オンライン機能はすばらしい。が、自分一人で書きたいのなら、例えば Fallow がそうだったように、利はごくわずか(自分の持ってるコンピュータ以外でもつかえるってだけ)だ。

Level 0: 基本的にオンライン根付いているけれど、ローカルキャッシュにすべてのデータがありさえすれば、全くオフラインと変わらない使い心地のアプリケーション。MapQuest, Yahoo! Local それに Google Maps はこのカテゴリーにある(ただ housingmaps.com のような mashup は Level 3 に)。オンライン地図アプリがユーザの投稿を受け付ける付加機能は、そのアプリの階層を Level 2 に引き上げる。

Amazon について言及しなかったことに気がついたかい?それは、僕自身 Amazon が Level 2 なのか 3 なのか決めかねているからだ。Amazon風のオフラインカタログ(例えばお店)はありえそうだけど、Amazon は、オンラインのユーザ活動をより根深く活用して、この分野の限界を超えてる感がある。それに彼らにはアフィリエイトから S3 までの Web service がある。これはもう間違いなくあちら側 だよね。じゃぁやっぱりゲームのルールを変えるための戦略的能力の証しとして Level 3 にしておこう。

iTunes は Level をまたがったもう一つのすごい例だね。初期のマーケットとポジションは、(Level 1 の)デスクトップアプリに追加のオンライン機能だったけれど、iTunes Music Store が iTunes の中心的な存在になり競争力を増すにつれて、iTunes は Level 2 に移行する。最終的には last.fm にあるような機能と連携するようなレベルに達するには、iTunes は Internet という生地にしっかりと編み込まれてしまい、ネットからはなれると不自由な状態になる(つまり Level 3)になるだろう。(今でさえ、新しい CD を入れた時に offline だと、曲名がでてこなくて不満だろう。)まとめると、こういったアプリには Level を押し上げるための強いプレッシャーがかかっていると僕は信じている。人々が使えば使うほど、ネットワーク外部性は機能の運営の中心になるからだ。

と同時に、もちろん全く違う階層も存在する(社会はそんなに単純じゃないからね!)。つまりネット上にすべての機能を見いだすことができるけれど、デスクトップアプリとして存在する Email や IM はどうだろう。そういうときはつつましやかな電話を思い出してみるといい。

Fallow の記事にある非常に良い点として、序盤にある得意げに書かれた一節を僕は気に入っている。『遅かれ早かれ Dodgeball の事実に我々は直面しなくてはならない。ある人生の可能性--製品、冒険、提案、アイデアといった--が、あなたより若い人たちには確かに意味がある、ということをあなたが認識した時、Dodgeball は輝いて見えるだろう。』この洞察は、僕の頭の中に、大好きな Kim Stanley Robinson の火星三部作の一節をリピートする。『歴史は、我々より若干速い時間を動く波である。(原文: History is a wave that moves through time slightly faster than we do.)』(しばらく噛み締めてみてよ!美しくて、簡潔で、非常に洞察深い。もし意味が分かんなかったら、あと数年まってみることだ。)

あとこれも好き。『新しい Web はデジタルではなくアナログである。これは単一の、大きな、不連続のイノベーションの結果ではない、という意味に於いて。むしろ、ある意味進化的なものから劇的に違うものまで、新しいアイデア連続体を体現している。』多くの人々は、Web 2.0 が簡単に定義できるものではない、ということに四苦八苦している。Fallow は潔くそのアイデアを受け入れている。

Long Tail、具体的には、できることがより少なく、すべての人のすべてのことが解決できるようなものになりたくないアプリ、の興味深い帰結として彼はこうも云っている。『Ajax を使ってデスクトップアプリやサービスを置き換えてやろうという野心的なものは、意外にも“Short Tail”なアプローチをしばしば採用する。Short Tail主義の結果は、面白そうで、新しい“Long Tail” 事業部であり、オンラインアプリとデスクトップアプリの中間に存在する;無料のオンラインアプリは、日課的状況にある普通の人向け、有料のデスクトップアプリは、より膨れ上がって、ハイエンドユーザ向けに特化されるかもしれない。そして Dodgeball 原則の原点に戻るならば、それぞれのユーザの状況に応じたいくつかのアプリがあるはずだ、と。』

これもとても洞察に満ちている。『新しい Web はアナログではなくデジタルである。集合知たる Web 2.0 は自ずと整い導かれるはずであり、大きく、はっきりと目立つ、Yes-Or-No のシグナルを発する時にもっともうまく立ち回り、微妙な判断を提示しようと試みる時は最低である、という意味に於いて。』彼は、eBay の thumbs-up/thumbs-down 評価(落札者評価)と、Pandra のニュアンス評価を対比する。ニュアンスをフィードバックすることでユーザの好きそうな音楽を選ぶ、という Pandora のやり方は失敗していると彼は考えているようだ。しかしここには彼のニュアンスの欠如がある。Pandora は Web 2.0 アプリじゃないんだよ!!Pandora はユーザの好きそうな音楽を、探し当てるのにアルゴリズムを使っているし、これはオフラインでも可能なことだ。もし同じ問題への Web 2.0 なアプローチが欲しいなら、彼は last.fm を扱うべきだった。

Fallow の記事で僕が最も洞察深いと思ったのは、Web 2.0 が究極的に信頼に基づいているということ。ユーザ参加の構造を考える時に、とてもいい導入(装飾音)だね。Web 2.0 は究極的には信頼に基づいている。

彼はそのような信頼は壊れやすいと結論づける。そして(この記事を送ってくれた Tech Review の PR の人の言葉を引用すると)『もし信頼が壊れたら、新しい Web 人達の世代全体を、新しいトレンドを追うにはもう年老いたという多感な感傷に陥れる。』spam やフィッシング、罵倒の応酬それに Wikipedia 上の荒らしはともかく、僕は賛成しない。

信頼は常に壊れるもの。だけど、僕は Wallace Stevens の知恵に何度も何度も立ち返る。現実主義者、幻想が壊れても、それでもなお楽観主義に立ち戻る。彼はこう云った。『リアリストの yes は、yes と云わねばならぬから、すべての下に、二度と壊れぬ yes があるから。』人間の精神はとてもすばらしい。そして実際僕らは新しい方法で協調するためのツールを作り出すことだってできるし、それは僕らの精神に新しい表現方法を与えてくれるんだ。


訳後感想

今日たまたま YAMDAS を眺めててMusic Genome Projectというのを知って、それが Pandora の元だった、ということを知りました。もしこの Genome 集めが Web 2.0 風に行われたとしたらどうなったんだろうなぁ、と思いつつ音楽みたいな制約 Media では、専門家の意見が大事なのかなと思いました。でも User Impression Driven な Music Matching System も見てみたいような、予想内の結末になるのか。

javascriptで生成されたIMG要素のブラウザに依る挙動の違い

Date
2006-08-18 (Fri)
Category
javascript

難しくないと思っていたのだけど、結構面倒くさい問題に取り組んでいることにようやく気づいた。

IMG element loading timing

Gallery みたいなサイトを作ろうとしている。画像は javascript に file path を配列で渡して、window.onload イヴェントで要素を追加していく。画像ファイルの大きさによって、挙動をかえるつもりだったのだが、Safari だけ画像の大きさをちゃんと読んでくれない。

正確には例えば <img src="***" id="testimg" /> みたいな要素を生成し document.body (かそれ以降)に挿入する。Firefox, Opera だと、その要素に width / height 属性を振っていなくても、$('testimg').width みたいなアクセスができるけど、Safari だと 0 が帰ってくる。

悩んだ後、document.images 配列だと Safari でも、width / height の属性値が自動的に補完されるようなので、そっちを使おう、と。で、一番上の問題というか、実装に気がついたというわけです。

  • Firefox は、img が生成された瞬間に、src 属性を参照しにいって、メモリに溜め込んでいます。
  • Opera, Safari, IE は img に view がついた時に src 属性を参照するようです。

って常識なんでしょうか。ちなみに Opera は自動補完される width / height 属性の値が間違っている時がありました。が、再現性が低いので、とりあえず保留にしておきます。

javascript版 trim と path 処理関連

Date
2006-08-17 (Thu)
Category
javascript

よく使う trim は String を prototype で拡張しました。ので、同名で違うことをしている人は、注意。path 関連は php に強く影響を受けています。というかもっときれいに書き直したいので、obsolete になる可能性大ですが、とりあえず挙げておきます。

使い方としては、

p = Path("http://umbra.nascom.nasa.gov/eit/images/eclipse/williams/Williams_College_wl.jpg")
alert(p["domain"]) // umbra.nascom.nasa.gov と表示される。 alert(p["dirname"]) // /eit/images/eclipse/williams と表示される。 alert(p["basename"]) // Williams_College_wl.jpg と表示される。 alert(p["extension"]) // jpg と表示される。

こんな感じ。Path() の戻り値は Object ではなくて Array です。Associated Array というか Hash なので、prototype.js でほにゃほにゃしたい時は例えば、

p = $H(Path("http://umbra.nascom.nasa.gov/eit/images/eclipse/williams/Williams_College_wl.jpg"));
p.each(function(el){
   alert(el)
});

とかすると

domain, umbra.nascom.nasa.gov
dirname, /eit/images/eclipse/williams
basename, Williams_College_wl.jpg
extension, jpg

みたいになります。

Source は以下。

Continue reading

URL designing with &id=...

Date
2006-08-11 (Fri)
Category
Google | Trivia

URLのパラメータに「id」を使用すると google にインデックスされない

へぇ〜。じゃぁこれは??

Google Search "inurl:id blog"

“?id=” でページ内検索してみよう!

正直、僕も知らなかったし、ヘェ〜と思った。でも Webmaster Help Center - Webmaster Guidelines を読んで、マジで?と思ったね。ID でページ内検索していくつか抜粋。Technical guidelines と中見出しのついているリストの以下3つ。

  • Use a text browser such as Lynx to examine your site, because most search engine spiders see your site much as Lynx would. If fancy features such as JavaScript, cookies, session IDs, frames, DHTML, or Flash keep you from seeing all of your site in a text browser, then search engine spiders may have trouble crawling your site.
  • Allow search bots to crawl your sites without session IDs or arguments that track their path through the site. These techniques are useful for tracking individual user behavior, but the access pattern of bots is entirely different. Using these techniques may result in incomplete indexing of your site, as bots may not be able to eliminate URLs that look different but actually point to the same page.
  • Don't use "&id=" as a parameter in your URLs, as we don't include these pages in our index.

前の二つは session ID と入ってるけど、page ID の話なんてしてねぇよ、って?もちろん session ID と page ID が違うのくらい知ってるけれど、まぁここで Search Engine 的に問題としているのは、dynamic に生成されるページなので、やや強引ですが一絡に話をします。まずは訳してみましょう。

  • Lynx のようなテキストブラウザを使って自身のサイトを確かめてください。多くのサーチエンジンは Lynx で見えるような世界を見ています。Javascript, Cookie, Session ID, Frame, DHTML あるいは Flash のような派手な機能を使っているのなら、テキストブラウザでも見られるようにしてください。そうすればサーチエンジンも難なくあなたのサイトを収集できるでしょう。
  • ユーザのページ閲覧順序を確認するための Session ID や引数を使わなくても、サーチエンジンがページを収集できるようにしてください。それらの技術は個別ユーザの閲覧行動を確認するためには非常に有用ですが、サーチエンジンのアクセスパターンは全く違います。Session ID や引数を使うことで、サーチエンジンが URL を見て、実際には同じなのに違うように見えるページを確認しきれずに、あなたのサイトの索引生成作業が完了しないままになる可能性もあります。
  • “&id=” を URL に含めないでください。我々はそういったページを索引生成作業に含めません。

っていうか、Google ってそんなに馬鹿なんですか(反語)??ずいぶんと上からのもの言いだし。。

Google こそ究極の Bottom up の集団だと思っている僕としては、あのページはアジテーション以上ではないなと思う。件のページに書いてあるのはあくまで、サイト作成・管理の指針となるようなものであって、本当にそうしている、という仕様書ではないはず(僕だって Google の中の人ではないので、ホントはどうだか知らないけれど)。だって、整理の下手なダメ人間ばかりのこの世界で、そんな少数の整理|仕様|規格好きだけを相手にして、トップの座を守り続けられるわけない。

だから My RSS 管理人 aka さんのコンセプトというか結論というか主張には 100% 賛成するし、del.icio.us の Joshua が主張するような理由からも、&id= なんて ugly な URL は使うべきじゃない(ちょっと前に似たような記事書いたとこだし)と思う。けれども Subject にあるような 『URLのパラメータに「id」を使用すると google にインデックスされない』というのは、看板に偽りありと云うほかない。

PHPTALでQuoteを出力する

Date
2006-08-10 (Thu)
Category
php

PHPTAL を調べています。もうすぐ公開できると思う project でも使っています。PHPTAL だと、しっかり組んだ (X)HTML をテンプレート化するのがスゴく楽。コード書かない人でも、logic が理解できる人ならつかえると思う。Symfony でも一時期 View の所で使われたみたいだし、啓蒙する人が居れば結構流行りそうだけどな〜。っていうか、GUI 被せればいいのかも。次の project でやってみようかしらん。

さて。今回はちょっと tricky ではあるんですが、javascript の文 (statement)、つまり <script> 〜〜 </script> の波線の部分を PHPTAL で出力したろ、というのが今回の課題です。普通に文を出すのはいくらでも方法があるのですが、javascript で string を表現したい時はどうしても quote を使わないといけません(多分)。

でも、PHPTAL は HTML 要素の attribute を制御構造に使うという性質上、single quote (') と double quote(") は特別な意味を持っていて、普通に出力すると実体参照(entity reference、例えば &quote;みたいなやつ)に変換されてしまいます。無理に出そうとすると Error を吐きます(当たり前)。困った所で Forum を検索して解決法を発見。

html entities with phptal

<title tal:content="structure title" />

"structure" keyword tells PHPTAL that you've done all the escaping you want to do on the value. Nothing will be escaped, including <.

というわけで正解は structure というキーワードをつけると良い、でした。そしてコードは以下のようになります。ちょと長いがまぁ、tricky なことしてるので。PHPTAL 自体のせいではありませぬ。というか、むしろこういうのは別に、例えば JSON を挿入するとかでやった方が良いのかも。

<span tal:define='global dquote string:"' />
<span tal:define="global comma string:," />
var array = new Array( <span tal:repeat="each obj/array" tal:omit-tag=""> <span tal:content="structure dquote" tal:omit-tag="" />   <span tal:content="each/path" tal:omit-tag="" />   <span tal:content="structure dquote" tal:omit-tag="" />   <span tal:condition="not: repeat/each/end" tal:content="structure comma" tal:omit-tag="" /> </span> ); </script>

以下のコードは、PHPTAL がエラーを出します。っていうか当たり前ですが。。)

<span tal:content='"'/>

URL designing with mod_rewrite

Date
2006-08-09 (Wed)
Category
Web

前のエントリの続きを書きたいのだけれど、ちょいと忙しいので…この project が終わったらえいやと片付けます。

SEO とか、お題目のように唱えてる人たちには興味ないけど、例えば Flickr の URL designing はクールだよね、と思います。どの web 系 MVC framework にもたいてい mod_rewrite を使って、V(View) への redirector とか入れてあるし。でもな〜、mod_rewrite 難しそうだし。だいたい introduction の文章の始まりが悪いよね。。

”膨大な設定例やドキュメントがあるにもかかわらず、 mod_rewrite は黒魔術である。かなりイケてるっぽい黒魔術だが、 やっぱり黒魔術である。“ -- Brian Moore Apache 1.3 mod_rewrite モジュール より

黒魔術だもん。しかも文の締めもスゴい否定的だし。っていうかこの文章は、5年くらい前、僕に RegEx は難しいっていうトラウマを産みつけたよね… それに比べて 2.2 のApache Module mod_rewrite はこざっぱりしている。こっちを先に読みたかった。。

解説なんかは、ググればいくらでもでてくるので、バックグラウンドでどういう風に処理してるかを、 Wordpress を例に手短に説明してみたいと思う。。

Worepress を例にとって

Worepress では管理画面 Options -> Permalinks で、permalink の構造を変えることができる。default だと、index.php をただ省略しただけで、query 文字列が丸見え ?=123 みたいに。それだとまず Ugly だし、Search Engine 的にも良くないので、static なページ風に見せましょう、ってデフォルトで二つ選択肢があります。まとめるとこんな感じ(Wordpress まま)。

Default
http://example.local/?p=123
Date and name based
http://example.local/2006/08/09/sample-post/
Numeric
http://example.local/archives/123

ようやく閑話休題。下のふたつは .htaccess ファイルを Wordpress 側で生成して、その中で mod_rewrite を使っているんだ。ははぁ、けっこう構造違うし、2種類の htaccess があって、見比べれば勉強になるかもと思った。甘かった。どちらを使っても生成される htaccess は一緒。以下転載。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

ググると URL の一部を切り取って、それを query に再構築みたいな例はいくらでも見つかるけど、それって、query を変えるたびに htaccess を書かなきゃ行けないってことでしょ!?それはちょっと…と思っていたので、Wordpress のこの方法はぜひとも理解したい。結果、黒魔法でもありませんでした。

1行目: RewriteEngine ディレクティヴ

ノーコメントで。スイッチオン。

2行目: RewriteBase ディレクティヴ

これだけはググって意味が分かった。Apache のアクセス制限: /~dareka での設定 の前後を読むといい。要するに、最終出力の URL のベースを指定する。

3〜4行目: RewriteCond ディレクティヴ

どういう条件で、URL を変更するのか、という条件を記述する。引数( %{SOME_VAR} ) はサーバ変数や、正規表現のバックリファレンス(正規表現でマッチした部分の文字列)なんかを入れられる。上記の Wordpress の例ではサーバ変数を使っていて、お尻に付いてる !-f と !-d はオプションでそれぞれ、ファイルではない、とディレクトリではない、という意味。というわけで全体では、

『リクエストされた URI がファイルあるいはディレクトリを指し示さないとき、以下のルールで URL を書き換える』

という意味でした。

5行目: RewriteRule ディレクティヴ

これが本命。実際の URL 変換ルールはここに書く。これを間違えると死ねるらしいし、ここでは一行しかないけれど何行も書いて、複雑な処理をすることもできるらしい。これに関してもググればいくらでも例があるのでそちらを参照。この文章の意味は

『一文字 (.) 以上の入力があると、それはすべて index.php にリダイレクトしてください。[L] があるので、mod_rewrite 用の処理はこれでおしまいです。』

という意味。

まとめ

え?じゃぁ URI は mod_rewrite で組み直したりしてないの?と思った人、その通り。ではどうしてるかというと、HTTP リクエスト自体をもう一度見直してそれを処理側で組み直しているのです。例えば PHP だと $_SERVER['REQUEST_URI']; とすると、HTTP リクエスト自体を取得できます。それを PHP で処理して、必要な Controller なり Model なりを適用する、と。

正直ちょっとすっきりしない。だって URI の組み直しを2箇所で別々にやってるってことでしょ?パフォーマンス悪そう。でもそのかわり柔軟性は高いねぇ。どっちがいいのかな??

Return to Page Top