console.logでJavaScriptの変数の中身を見る

JavaScriptのコーディング中、オブジェクトや変数の中身を確認したくなることは多々あります。PHPの場合であればprint_rやvar_dumpで間に合うのですが、JavaScriptの場合にはconsole APIに対応したブラウザで対話式にチェックを行うのが便利なようです。

具体的には、FirefoxにFirebugを搭載した状態もしくはSafari、Chromeなどのwebkitブラウザで開発メニューを有効化した状態にて、webコンソールあるいはwebインスペクタのコンソールの入力エリアに命令を投げ与えます。

console APIのコンソール

console APIのコンソール

変数やオブジェクトの中身を参照したいなら、console.log(対象);という命令を与えエンターを押すと、コンソール画面に表示してくれます。特に便利なのは、引数にjQueryのオブジェクトを与えても表示してくれるという点です。さらにwebkitのブラウザは至れり尽くせりで、jQueryのセレクタでヒットした要素をちゃんと入れ子状にまとめて表示してくれるので、この方法を知っているか知らないかで、jQueryでの開発効率は違ってくるはずです。

コンソールに投げられる命令は結構ありますが、オブジェクトのプロパティをリストアップしてくれるconsole.dir()なども便利そうです。
また、コード中の任意の場所で呼び出して、ブラウザのコンソールに任意の時点での変数の状態を吐き出させることもできるので、通常の標準出力のような使い方も可能です。

なんというか素晴らしい時代ですね。

(追記:IEではconsole.logの仕様に落とし穴があるようなので、こちらのエントリも参考に)


clearfixのささやかな覚え書き

複数カラムのブログテンプレートなどを作成するとき、一般的にはCSSのfloatプロパティを使ってレイアウトを行います。たとえば2カラムで左にサイドメニュー、右に記事本文というレイアウトは、以下のようなhtml&CSSになるでしょう。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
.sidebar{
float : left;
}
.articlearea{
float : right;
}

カラムを包括する親ボックスの大きさが指定されており、各カラムが親ボックスの高さの値を超えないときには、特にレイアウト上の問題は起こりません。しかしながら、ブログのようにカラムの本文が可変長で親ボックスの高さを超えるケースが考えられるときには、カラムが親ボックスをはみ出て表示されてしまい、レイアウトが崩壊してしまいます。

はみ出たカラム

これは、ボックス内でfloat指定されている要素の大きさが親ボックスの大きさを決める際に参照されないという特性によるものです。したがって最も仕様に適った解決は、floatさせた要素の後にclearプロパティでfloat解除した要素を設けることです。空のdiv要素やvisibilityプロパティをhiddenにしたhr要素、br要素がよく使われます。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
 
//空divの場合
<div style="clear : both"></div>
 
//非表示にしたhrまたはbr
<hr class="clearfix" />
<br class="clearfix" />
</div>
 
CSS
.sidebar{
float : left;
}
.articlearea{
float : right;
}
.clearfix{
visibility : hidden;
clear : both;
}

この方法はシンプルですが、ページのセマンティック(意味)としてはデザイン修正の為だけの無意味な要素をhtmlに加える事になるので好ましくありません。
そこで、無駄な要素を加えることなくレイアウト修正を行う、名前もそのまま”clearfix”というテクニックが開発されました。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
//clearfixの追加部分
.wrapper:after{
content : "";
display : block;
clear : both;
}
//IE6,7用
.wrapper{
zoom : 1;
}
 
.sidebar{
float : left;
}
.articlearea{
float : right;
}

CSSのafter疑似要素を使って、floatを解除する要素を無理矢理埋め込むという形です。この方法ならば、検索エンジンやアプリケーションがページのhtmlのみを取得する場合に、解釈の混乱をひきおこす無駄な要素が発生しません。IE用の追加部分については、独自仕様のhasLayoutというプロパティがtrueであれば子要素のfloatを親ボックスのサイズ計算に含めるという特性を利用しています。無害なレイアウト指定(zoom:1;やwidth:100%;など)であれば何でも良いのですが、ソースの意図を明確にする為にzoom:1;の指定をしている場合が多いようです。

ここまでがclearfixの説明です。先に述べた通り、floatを解除する要素を最後に加えるという解決方法ですね。

それに対して、親ボックスのoverflowプロパティを明示的にhiddenと指定することで、親ボックスのサイズ計算方法を変えるというテクニックもあります。overflowプロパティとは、ボックス内の要素がボックスのサイズを超えてしまった際の表示方法についての指定で、何も指定しない状態はvisible、つまりはみ出た部分も表示する指定になります。これをhiddenと指定した場合、はみ出す部分のみ非表示となると同時に、ボックスの高さの計算式にfloatさせた要素も含まれるようになります。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
.wrapper{
overflow : hidden;
//IE6,7用
zoom : 1;
}
.sidebar{
float : left;
}
.articlearea{
float : right;
}

場当たり的な対応ではありますが、セマンティックを汚染せずさらに簡単なので、こちらをバカの一つ覚えのように使ってしまって良いかもしれません。


Conceptual:Ajax対応CSV表示プログラムOnlyCSViewを計画する

以前、PHPの便利なfgetcsv関数を使ったCSV表示プログラムを書きました。このプログラムはソースコードを読んで判るように、フォームで受け取ったパスのファイルを一時ファイルとしてコピーし、関数に与え処理した結果をページの再読み込み時に表示という手順を踏んでいます。もちろんPHPはサーバサイドで呼ばれるので、結果の表示に最低一回の画面遷移を必要とするnon-Ajaxなプログラムです。今回はこのプログラムを新しくAjax対応させて、OnlyCSViewという名前のWEBサービスにする計画を立てました。

完成までには色々と仕様的な壁にぶち当たりました。その過程をここに順を追って記しておくことで、これからPHPプログラムをAjax対応させようとする方、ならびに自分自身が同じ轍と格闘しないようにしようと思います。

Ajax対応のキモ 〜jQuery.post命令でPHPerにも直感的に

まずは今回のajax対応に関しては、jQueryを使うということに決めました。理由としてライブラリを使わない素のJavaScriptでの開発は、非同期処理実装のためブラウザ毎に異なった命令を使わなければならないということがあり、面倒臭くスマートでないからです。面倒臭いことは時にプログラミングの醍醐味でもあったりしますが、できればメイン部分の処理か、あるいは誰もやらないような事の方に労力をかけたいと思いますよね。
Ajax部分はPHPプログラムで慣れたPOSTを使いたかったので、jQuery.post命令を使います。

jQuery.post(引数1,引数2,引数3,引数4)
引数1 呼び出すurl 今回の例ではcsvtojson.phpという処理部分のファイル
引数2 呼び出し先に与えるデータ。複数の場合はラベルをつける {"label1" : data1,"label2" : data2}
PHP側では$_POST["label1"]のように取り出せる。省略可
引数3 エラーも含め値が帰ってきたら行う処理。省略可
引数4 データの種類。省略可

csvtojson.phpには何を書けば良いでしょうか。PHPのみで作ったCSV表示プログラムの中から、ユーザが指定したCSVファイルが何かを知る機能、と、配列に格納したデータを表に整形する機能、を取り除いて、この2つの機能はJavaScript側で実装するようにします。そうすることで、csvtojson.phpは入力がファイルパス(文字列)、出力が配列という単機能のプログラムにまとまります。
PHPとJavaScriptで配列の受け渡しをするには、JSONというフォーマットを使います。上に書いたjQuery.postの説明の引数2のところで既に出してしまいましたが、何の事はなくJavaScriptのオブジェクトの書式と同じです。ただしラベルは必ず文字列でなければなりません。PHPの配列をJSONにエンコード/デコードする際には、配列をjson_encode関数もしくはjson_decode関数に与えてやるだけで済みます。最後にエンコード済みのJSONフォーマットをechoして、csvtojson.phpの仕事は終わりです。

jQuery.postの方では、引数4に”json”と指定してやる事で、帰ってきたデータをJSONと解釈してくれます。その他にとりうるオプションとして、”xml”,”html”,”script”,”jsonp”,”text”があります。もしCSVの整形表示部までcsvtojson.phpに担当させる設計にするならば、整形後のhtmlを”html”で受けるといった具合です。引数3はfunction(){…と結果が帰ってきた際の処理を匿名関数でそのまま書いてしまえば良く、さらにこの関数の引数として宣言された変数で、帰ってきたデータを受けられます。
実際にjQuery.postでcsvtojson.phpを呼んだ部分はこのようになりました。

jQuery.post("csvtojson.php", {"filepath" : filepath,"charset" : charset},function(data,status){
//処理。変数dataはcsvtojson.phpが返してきた値(JSON)。
//data[i][j]のようにアクセスして値を取り出せる。省略可。
//変数statusには成功、失敗などのステータスが入る。省略可。
},"json");

Ajax対応落とし穴 〜JavaScriptはファイルのローカルパスを知ることができない

メイン処理部分は後回しにして、csvtojson.phpに与えるローカルファイルパス取得の処理を考えます。JavaScriptではWEBページ内のフォームに入力された値を、フォームのname属性で特定して操作する事ができます。したがって、ユーザーに<input type=”file”>でローカルファイルをセットさせて、その値を取り出す。理論的にはそれで大丈夫なはずです。

//HTML部分
<input type="file" name="csvfile" accept="application/excel" />
.
.
.
//JavaScriptでセットされたパスを取得
var filepath = document.controlls.csvfile.value;

ところが、実際にはこの書き方ではパスを取得できません。試しに上のコードに続いてalert(filepath);というコードを実行すると、結果は以下のようになります。

fakepath

fakepathという単語で、実際のファイルパスがマスキングされています。良く言われる、JavaScriptではセキュリティ対策のためローカルファイルにアクセスできないという表現ですが、ファイルへのアクセスにエラーが出るという実装ではなく、そもそもローカルファイルパスを知る事ができないという仕様によるもののようです。したがって、PHPに受け渡してしまえば処理できるというものでもありません。

Ajax対応のキモ 〜HTML5のFile APIを使ってみる

そこで、ローカルファイルアクセスの問題を克服したとこちらも良く言われる、HTML5を使います。HTML4以前で作られたページでHTML5の機能を有効にするには、DOCTYPE宣言をこれまでの複雑なものから、<!DOCTYPE html>というシンプルなものに変えるだけです。詳しい説明はまた別のエントリで行いますね。
HTML5は2014年の正式勧告を目指して仕様策定中という段階であり、API導入の状況は各ブラウザによってまちまちです。今回使用するFile APIは、現時点でFirefoxとChromeが対応、Safariは部分的対応といった状況です。今回のプログラムがFirefoxおよびChromeのみ対応となってしまうのは、このSafari未対応部分の機能を使うからです。
File API対応ブラウザであれば、<input type=”file”>でユーザが選択したファイルに、name属性でなくid属性でアクセスできます。

//HTML部分
<input type="file" id="csvfile" accept="application/excel" />
.
.
.
//JavaScriptでセットされたファイルを変数に代入
var userfile = document.getElementById("csvfile").files[0];
//ファイル名取得
var name = userfile.name;
//サイズ取得
var size = userfile.size;
//タイプ取得
var type = userfile.type;
//urn取得
var urn = userfile.urn;

File APIは複数ファイルの選択にも対応しているため、セットされたファイルはインデクスで指定して取り出します。一つしかセットされていない場合はfiles[0]で指定します。
このurnというプロパティが、いかにもファイルパスだろうという安易な予想をしたのですが、実際ローカルファイルをセットして値を取得してみると空でした。大抵のFile APIの解説でも省略されているのですが、URNというのは、URLと同じくICANNによって唯一性が保証されたファイル名のことで、パスのようにユーザが主体的に値を設定せずとも存在しているものではないようです。いずれは活用するようになるかもしれない名前空間といったところでしょうか。

Ajax対応落とし穴 〜objectURLはセッションを越えられない

File APIにはローカルファイルのパスを知る2通りの方法が用意されています。どちらの方法も発想の逆転で、指定されたローカルファイルに新しくパスを与えるということでセキュリティ上の問題をクリアしています。方法の1つ、objectURLはファイルへの参照を示し、2つ目のDataURLはurl文字列にファイルの内容をそのまま展開してしまいます。もちろんobjectURLの方が圧倒的にバイト数が少ないので、Ajax通信で使うフォーマットとしてはこちらを採用したくなります。

//HTML部分
<input type="file" id="csvfile" accept="application/excel" />
.
.
.
//objectURLを作成
 
//Firefoxの場合
var filepath = window.URL.createObjectURL(document.getElementById("csvfile").files[0]);
//Chromeの場合
var filepath = window.webkitURL.createObjectURL(document.getElementById("csvfile").files[0]);
 
//jQuery.postに与える
jQuery.post("csvtojson.php", {"filepath" : filepath},function(){
//処理
},"json");

しかしながら、こうして作成したObjectURLはセッションを越えられないため、csvtojson.phpはこれを無効なパスと解釈します。残念ではあるのですが、ObjectURLにはまた別のところで活躍してもらうとしましょう。

Ajax対応のキモ 〜filereaderでData URLを作成しパス渡しを実現

Data URLというのは、先程も述べましたがファイル内容をそのまま展開してしまったURLのことで、このURLの解釈自体は大抵のブラウザが対応しています。具体的な採用例としては、Google画像検索で表示される画像がData URLです。File APIのfilereaderではアクセスしたローカルファイルをいくつかのフォーマットに展開することができるのですが、その内の一つのフォーマットがData URLなのです。filereaderの使い方を見てみましょう。

//HTML部分
<input type="file" id="csvfile" accept="application/excel" />
.
.
.
//filereaderインスタンスを作成し、メソッドでファイル読み込み
var reader = new FileReader();
//バイナリ文字列へ
reader.readAsBinaryString(document.getElementById("csvfile").files[0]);
//テキストへ(第二引数は文字コード)
reader.readAsText(document.getElementById("csvfile").files[0],"UTF-8");
//Data URLへ
reader.readAsDataURL(document.getElementById("csvfile").files[0]);
 
//読み込み終了時の処理(非同期なので他のステータスにもメソッドあり)
reader.onload = function(e){
//変数filepathに結果を代入
var filepath = e.target.result;
};

filereaderを使う場合には、FirefoxとChromeの分岐処理は必要ありません。作成されたData URLを、jQuery.postでcsvtojson.phpに送ると正常に処理されました。トラフィックには優しくない方法ですが、とりあえず既存PHPプログラムのAjax対応への糸口が見えました。

$.post("csvtojson.php", {"filepath" : filepath},function(data, textStatus){
var $table = $('<table id="ct"></table>');
for(var i in data){
var $onerow = $("<tr></tr>");
for(var j in data[i]){
$("<td></td>").text(data[i][j]).appendTo($onerow);
}
$onerow.appendTo($table);
}
$("#tablearea").append($table);
},"json");

csvtojson.phpが返してきたJSONをテーブルに整形しています。こちらもjQueryを使って幾分楽をしていますね。

ということで、とりあえず最低限のAjax対応が果たせました。デモはこちらから。
段々肉付けをして便利なサービスにしていきたいと思います。


akisi.site90.com時代の当サイトを利用されていた方へ

このたび急な移転をするはめになってしまいました。

契約サーバの000webhostが、通告無く前サイトを非公開状態にし、利用を続けるのなら金を払えという宣告をしてきたのです。

FTPやMySQLデータベースにアクセスする事もできず、先方が非公開にしたデータを移転のためローカルに落とす事も適いません。仕方が無いので、googleのキャッシュから記事を復元している最中です。画像データなど一部のものは完全に失われてしまったため、完全な復元は不可能ではあるのですが。

この000webhostは、特に瑕疵の無いサイトを予告無しで非公開にする手口を良く使うようです。無料でMySQLデータベースを提供しているのも、ファイルコピーによる単純なバックアップが不可能なデータベースを利用させる事で、有料サービス契約要求の際の人質の価値を大きくしようとしているのではないかと勘繰ってしまいます。

条件面だけを見て、000webhostを薦めるエントリをかつて書きましたが、現在こちらのサーバを他人に薦めようという気は全くありません。

記事は古いものから復元していく予定です。それまでこちらの記事がトップに出続ける筈ですので、ご了承ください。旧ページへのリンクなどありましたら、site90.comをtabiyaku.netに変更よろしくお願い致します。


子テーマを使ったWordPressカスタマイズ(CSS編)

(前口上が長いので、とりあえずタイトル通りのカスタマイズの方法だけ知りたいという方は、四段落ほど飛ばして読んで下さい)

WordPressカスタマイズ、ダッシュボードの左メニューからの設定変更を初級編とするならば、さしずめ中級編はCSSを用いた各要素の表示変更といったところでしょうか。静的ページのCSSによるレイアウトに習熟された方でも、いつも通りの手順でCSSをいじったが反映されない、あるいはダッシュボードで促されるままアップデートをしたら、苦労して設定したスタイルが無効になったなどなど、トラブルに直面して初めてWordPressが一筋縄でいかないという事に気付く筈です。まさにそこからが中級編の入り口で、中級編以降のカスタマイズには、WordPressの仕組みの一定以上の理解が必要とされるのです。

WordPressでは、一つのページを作るのに様々なディレクトリの様々なファイルを参照し、それらを決められた優先順位で読み込んで表示します。スタイルシートについてもそれは同様ですが、スタイルシートの性質として、同じ要素に対するスタイル指定は後に宣言された方を優先とするという原則と、idやクラスなど具体性のある宣言を優先するという原則があります。ゆえに、特定の要素について最終的に有効になっているスタイルがどのファイルのどこで宣言されたものかが判別できないと、現在のスタイルを変更しようと思っても変更の箇所がわかりません。
要素に実際どういったスタイルが有効になっているのかは、CSSの熟練者にとっては常識ですが、ブラウザの機能を使って調べられます。SafariやChromeなどのWebKit系ブラウザであれば、要素の上で右クリックし”要素の詳細を表示”を選択すると、”webインスペクタ”ウィンドウが現れるので、右側の”一致したCSSルール”という部分に注目します。画像の例ではp要素に適用されたルールが列挙されていますが、line-heightについてはcore.cssというファイルの250行目で宣言されたものの、同じcore.cssの1350行目でより具体的なルールが宣言されたため、効果が打ち消されていることがわかります。

WEBインスペクタ

Firefoxの場合も、右クリック→”要素を調査”で同様の機能を使うことができます。

さて、ブラウザの機能で宣言の位置が特定できたら、その箇所を変更することでスタイルの変更も有効になります。WordPressでは、大抵の場合最終的に有効になっているスタイルは、ルートディレクトリからwp-content→themes→現在使用中のテーマ名のディレクトリ、と階層を下ってその中にある、style.cssというファイルで宣言されています。つまり導入しているテーマに付随したCSSなのですが、このファイルをいじれば、とりあえずスタイルの変更ができることが多いと覚えておいて下さい。

しかしながら、このstyle.cssを直接いじっての変更は非推奨です。というのも、不具合が起きてしまったときにその原因が果たしてテーマ自体の問題なのか、あるいは加えた変更の問題なのか、が判別しづらくなります。また、テーマをアップデートする際にはこのstyle.cssごとアップデートされることになるので、アップデート毎に変更部分がリセットされてしまいます。

そういった問題を回避する方法として、WordPress3.0以降のヴァージョンには子テーマという仕組みが存在します。これにより現在有効になっているテーマを直接変更することなく、任意の部分のみに変更を付け足すことができます。また、ファイルとしては親テーマのパッケージの外部に置く形となるので、親テーマのファイルがアップデートされても影響を受けません。
具体的な設定方法を見ていきましょう。まずは子テーマのディレクトリを用意し、その中にstyle.cssというファイルを作ります。今回はmystiqueテーマの子テーマとしてchildtheme1というテーマを作るとします。style.cssの先頭に最低限以下の記述があれば、子テーマとして機能します。

/*
Theme Name: childtheme1
Template: mystique
*/

CSSのコメント行を使って、まずテーマ名と継承元テーマ名を宣言します。通常のスタイル宣言と違いコロンの左側にスペースは許されないので注意して下さい。またTemplateのラベルに指定する値は、親テーマの名称ではなく、themesディレクトリ下の親テーマのディレクトリ名です。大文字小文字の区別もあるので注意を払って下さい。
ともあれ、これで子テーマとして認識されるようになりました。ダッシュボードの左メニューの”外観”から”テーマ”を選ぶと、この子テーマが通常のテーマと同様選択できるようになっています。子テーマを選択すると、親テーマのファイルはそのままにstyle.cssのみ親テーマのではなく子テーマのものを読み込むようになります。

匿名作子テーマ

先程のstyle.cssに少し肉付けをしましょう。まず、子テーマのstyle.cssではスタイルの記述が行われていないので、このまま読み込むとテーマの表示が滅茶苦茶になってしまうはずです。親テーマのstyle.cssの記述を継承するための記述を行います。

/*
Theme Name: childtheme1
Template: mystique
*/
@import url('../mystique/style.css');

@import宣言に親テーマのパスを与えます。注意すべきなのは、子テーマのstyle.cssからの相対パスを与えるということです。
これで親テーマのスタイルを丸ごと読み込みました。さて、先述のCSSのルール、後から宣言した方を優先というものを思い出して下さい。つまり@import宣言の後でスタイルの設定を行えば、既に親テーマのstyle.cssで同じ要素に対する設定がされていても、自動的に子テーマのものが優先されるということです。

/*
Theme Name: childtheme1
Template: mystique
*/
@import url('../mystique/style.css');
#none{
display : none;
}

このように書くと、idがnoneの要素が親テーマでどのように設定されていようと表示されなくなります。仕組みがわかれば、あとはつらつらといつも通りのCSS編集ができますね。

以上が子テーマのカスタマイズ(CSS編)です。子テーマではスタイルの変更以外にも、親テーマのもつテンプレートやウィジェットなども置き換え/追加することができます。そちらはPHPの知識が必要となってきますので、いずれ詳しく紹介したいと思います。


新ページおよび新カテゴリ”Conceptual”を追加

このサイトに新しく”Conceptual”という名前のページを作成し、完成させたプログラムおよびデモンストレーションへのリンクを張ることにしました。ページタイトルの下のメニューバーからリンクを辿ってみてください。あるいはここから。
同時に同名のブログ記事カテゴリを新しく設け、サブカテゴリからプログラム毎の作成過程などを追えるようにしました。キメラ系人間のtroublesomeな開発実録をお楽しみください。


WordPressテーマMystiqueの実力

WordPress解説の後編で言及したように、WordPressテーマの中には見た目やページ構成の変更のみならず、ウィジェットやプラグイン機能をもパッケージの中に内包する大規模なものがあります。このブログで採用しているMystiqueというテーマもそうした総合的なパッケージであり、一度使い慣れてしまうと他のテーマへ移行するのが億劫になってしまう程機能が多岐にわたります。折角なのでさらりと紹介させていただきましょう。

まずテーマの基本的な情報です。ルーマニアのdigitalnatureというデヴェロッパーによって開発されているこのテーマは、2009年に最初のヴァージョンが出た後、2.x系から3.x系で一度互換性の無いメジャーアップデートをしています。現在はこの2.x系の系譜のlightヴァージョンと、3.x以降のbasicヴァージョンというラインナップを有しており、basicヴァージョンはダッシュボードのテーマ検索でヒットしない為、オフィシャルページからダウンロードして手動でインストールしなければなりません。昔からのユーザでも、未だに3.x系の存在を知らず2.x系のアップデートを待ち続けているという人が結構いるのではないかと思います。
このテーマの初期からの特徴は、見ての通り少しオタクっぽいデザインとjavascriptを利用したインタラクティブなメニューウィジェットです。当ブログのウィジェットエリアにある黒背景のウィジェットは、実はTabbed WidgetというMystiqueテーマ固有のウィジェットです。これがあることにより、ウィジェットエリアに幾つもウィジェットを並べてスペースを消費することを避けられるというわけで、デザイン上の恩恵は多大です。
3.x系では、このTabbed Widgetの設定もドラッグ&ドロップでするようになり、タブ化できるウィジェットの選択肢が増えた一方で、初心者がその存在に気付きにくくなりました。設定中のスクリーンショットを撮っておきましたので、導入時の参考にしてみて下さい。

Tabbed Widgetその1

まずArbitaryウィジェットエリアに投げ込む


Tabbed Widgetその2

Tabbed Widgetウィジェットの設定項目として登場するので、チェックボックスで有効化

その他、ひととおり他の人気テーマでできることは抑えています。画像をクリックした時のLightBox的挙動、投稿画像のサムネイル化、写真ギャラリー機能、ソーシャルメディア対応、コメントのレーティングなど。また、さすがにメジャーアップデートで前ヴァージョンからの設定引き継ぎができなかった事は問題と認識していたのか、テーマの設定を独自フォーマットでインポート/エクスポートする機能が追加されています。

テーマ設定の吐き出し/読み込み

このような強力な機能を備えたテーマであるが故、ここまで技術力があるならもうWordPress作っちゃえばいいよという感もあるのですが、実は作っているらしいです(笑)。公式ホームページによれば、テーマのアップデート頻度が減少したのはWordPressクローンを作っているからとの事。かつてのWordPressで可能だったように、データベースにMySQL以外を指定できるようにするらしいです。その他、モジュールとプラグインの一本化などなど。
個人プログラマのこのプロジェクトが、将来的にWordPressを淘汰するまでに至ったら面白いですね。Movable Typeとのシェア転換がそうであったように、OSSは一見些細な切っ掛けから勢力図のドラマティックな転換もあり得る筈です。

(2012.6追記:現在一時的にテーマを外しています。)