WolaWola
DynamicMTMLを利用したページ分割処理
- 2012-04-29 (日) 17:36
- MovableType
アーカイブのページ分割には今まで、ダイナミックパブリッシングを利用したページ分割や、検索CGIを使ったページ分割、それにPagerやPageButeなどのプラグインを利用したページ分割などがありました。あ、あと実は未だに使っているMTPaginateなんてのもありましたね。
しかしこれらは、それぞれに長所と共に短所があり、必ずしもどれがベストな選択とは言えないところがありました。
ダイナミックパブリッシングはPHPによる動的生成、検索CGIはPerlによる動的生成であり、それぞれ表示するたびにそれなりの負荷がかかります。
それに対して、プラグインによるアーカイブ生成は、表示はスタティックファイルなので高速ですが、再構築時にページ数に応じて負荷が高くなり、継続的にコンテンツを投入されるサイトでの、カテゴリーアーカイブを分割するような場合には、TimeOutエラーなどで処理できなくなる確率が高くなります。
DynamicMTMLを利用することで、再構築時の負荷もが低いまま、表示時の負荷もそれほど高くならない、ページ分割処理が可能になります。(最近はほとんどこの方法でページ分割をこなしてる気がする)
アーカイブを作成
例として、カテゴリーアーカイブとアイテム一覧をアーカイブとして出力するようにしてみます。
カテゴリーアーカイブのページ分割
DynamicMTMLでのアーカイブは、スタティックなHTMLファイルとして出力されます。そのHTML内に書かれたMTMLを動的に処理することで、内容を出し分けます。
以下カテゴリーアーカイブのページング処理部分の内容です。ヘッダやフッタ、その他装飾のスタティックな部分は省略してます。MTEntriesループ内で表示されるものは、「ブログ記事概要」テンプレートモジュールの内容になります。
URLの後ろに「?p=2」などとすることで2ページ以降が表示されます。MTQueryというDynamicMTMLのタグでkey指定して受け取っているので、そこを変更すれば「?page=2」等に変更もできます。
クエリで受け取ったページからもろもろの変数設定する部分
<<MTRawMTML>MTSetVar</MTRawMTML> name="blog_id" value="<$MTBlogID$>"> <<MTRawMTML>MTSetVar</MTRawMTML> name="total_entry" value="<$MTCategoryCount$>"> <MTDynamicMTML> <MTSetVar name="limit" value="20"> <MTQuery key="p" setvar="current_page"> <MTUnless name="current_page"><MTSetVar name="current_page" value="1"></MTUnless> <MTVar name="current_page" op="*" value="$limit" setvar="last_entry"> <MTVar name="last_entry" op="-" value="$limit" setvar="first_entry"> <MTVar name="total_entry" op="/" value="$limit" regex_replace="/\.\d+\$/","" setvar="total_pages"> <MTIf name="total_entry" op="mod" value="$limit"><MTSetVar name="total_pages" op="++"></MTIf> </MTDynamicMTML>
ココがMTEntriesループ部分
<<MTRawMTML>MTEntries</MTRawMTML> include_blogs="$blog_id" categories="<$MTCategoryLabel$>" limit="$limit" offset="$first_entry"> <MTRawMTML><$MTInclude module="ブログ記事概要" blog_id="$blog_id"$></MTRawMTML> <MTML tag="/MTEntries">
ココからPager用コード
<MTDynamicMTML> <MTIf name="total_pages" gt="1"> <MTUnless name="current_page" eq="1"><a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="current_page" op="--"$>">前へ</a></MTUnless> <MTFor var="x" from="1" to="$total_pages"> <MTIf name="x" eq="1"> <MTIf name="current_page" eq="1"> <span class="current">1</span> <MTElse> <a href="<$MTCurrentArchiveURL$>"><$MTVar name="x"$></a> </MTIf> <MTElse> <MTIf name="current_page" eq="$x"> <span class="current"><$MTVar name="x"$></span> <MTElse> <a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="x"$>"><$MTVar name="x"$></a> </MTIf> </MTIf> </MTFor> <MTUnless name="current_page" eq="$total_pages"><a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="current_page" op="++"$>">次へ</a></MTUnless> </MTIf> </MTDynamicMTML>
first_entryはMTEntriesに渡すオフセット値になっていて、この値に1を足すとそのページに表示される最初の記事が、記事全体での何番目かという数字になります。last_entryはそのページに表示される最後の記事が、全体で何番目の記事かという数字になりますが、厳密には最終ページなどで分割数に満たない時はこの数字より小さくなります。
よくある「21ページ中7ページ(121~140)」の様な表示は以下のコードで表示できます。
<MTDynamicMTML> <$MTVar name="total_pages"$>ページ中<$MTVar name="current_page"$>ページ(<$MTVar name="first_entry" op="++"$>~<MTIf name="current_page" eq="$total_pages"><$MTVar name="total_entry"$><MTElse><$MTVar name="last_entry"$></MTIf>) </MTDynamicMTML>
アイテム一覧ページ
さてアイテムの場合はと言うと、基本的にはブログ記事と一緒で、こんな感じになります。assets_per_rowモディファイアなどと組み合わせると、それっぽいアーカイブページが作成できるものと思います。
クエリで受け取ったページからもろもろの変数設定する部分
<<MTRawMTML>MTSetVar</MTRawMTML> name="blog_id" value="<$MTBlogID$>"> <<MTRawMTML>MTSetVar</MTRawMTML> name="total_asset" value="<$MTAssetCount$>"> <MTDynamicMTML> <MTSetVar name="limit" value="20"> <MTQuery key="p" setvar="current_page"> <MTUnless name="current_page"><MTSetVar name="current_page" value="1"></MTUnless> <MTVar name="current_page" op="*" value="$limit" setvar="last_asset"> <MTVar name="last_asset" op="-" value="$limit" setvar="first_asset"> <MTVar name="total_asset" op="/" value="$limit" regex_replace="/\.\d+\$/","" setvar="total_pages"> <MTIf name="total_asset" op="mod" value="$limit"><MTSetVar name="total_pages" op="++"></MTIf> </MTDynamicMTML>
ココがMTAssetsループ部分
<<MTRawMTML>MTAssets</MTRawMTML> include_blogs="$blog_id" sort_by="created_on" lastn="$limit" offset="$first_asset"> <MTRawMTML><$MTAssetThumnbnailLink width="200"$></MTRawMTML> <MTML tag="/MTAssets">
ココからPager用コード
<MTDynamicMTML> <MTIf name="total_pages" gt="1"> <MTUnless name="current_page" eq="1"><a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="current_page" op="--"$>">前へ</a></MTUnless> <MTFor var="x" from="1" to="$total_pages"> <MTIf name="x" eq="1"> <MTIf name="current_page" eq="1"> <span class="current">1</span> <MTElse> <a href="<$MTCurrentArchiveURL$>"><$MTVar name="x"$></a> </MTIf> <MTElse> <MTIf name="current_page" eq="$x"> <span class="current"><$MTVar name="x"$></span> <MTElse> <a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="x"$>"><$MTVar name="x"$></a> </MTIf> </MTIf> </MTFor> <MTUnless name="current_page" eq="$total_pages"><a href="<$MTCurrentArchiveURL$>?p=<$MTVar name="current_page" op="++"$>">次へ</a></MTUnless> </MTIf> </MTDynamicMTML>
他にも使い方が沢山
ダイナミックパブリッシングで動作するループタグで、limit指定やoffset指定が使えるものなら、応用可能です。
例えば、SearchEntriesを使うことで、簡単に複雑なクエリを処理する(DynamicMTMLのSearchEntriesタグは、フィールドの部分一致で指定が可能です)検索ページを作成できます。
この方法での負荷の発生は、主に表示時にダイナミックパブリッシング部分を動的に生成する部分になるはずです。
パラメータ部分に複雑ななクエリが必要な場合は、パラメータ生成までを静的に済ませられないかを検討したり、ブロック表示部の処理が複雑な場合は、別ファイルとして処理させておく等の手段が有効です。
単純なブロック表示の場合なら、さほど負荷は発生しませんので、そのページがダイナミックパブリッシングで処理されていると気づかないこともあります。
- Comments: 0
- TrackBacks: 0
コード上でカテゴリー(ORフォルダ)をuser_customでのソートにするには
- 2012-04-29 (日) 16:34
- MovableType
とある案件用に、カスタムフィールドプラグイン(あるウェブサイト上のフォルダを、管理画面の並び順(sort_by="user_custom")に選択肢として出力する)を作ってみました。
MTタグ上では、「sort_by="user_custom"」を指定(というかSubCategoriesのデフォルトになりましたね)すれば良いわけですが、プラグインコード内で、以下のように書いてもまるで並び替わる様子がありませんでした。
my @folders = MT->model( 'folder' )->load(
{ blog_id => $blog_id,
parent => '0'
},
{ 'sort' => 'user_custom',
direction => 'ascend',
}
);
そういえば、この並び替えデータってどこに保存されてるんだっけと、「mt_category」や「mt_category_meta」を見てみても、特に拡張されていません。ありそうなところを一通り見ていって、やっと場所がわかりました。「mt_blog_meta」に「category_order」や「folder_order」が保存されてました。値を見るとカンマ区切りのカテゴリーIDのようです。
コレをどうするんだか解らないので、やむを得ず、「MT::Template::Tags::Category」のコードを読んでみていくと、なんかおかしな事書いてあります。
@cats = $class->load(
{ blog_id => $ctx->stash('blog_id'),
parent => '0'
},
{ ( ( 'user_custom' eq $sort_by )
? ( sort => 'label' )
: ( sort => $sort_by )
),
direction => $sort_order,
}
);
$sort_byは指定されてるsort_byなわけですが、何故かそれが「user_custom」の時に、「sort => 'label'」を設定してます。え、なんで「label」とか思ったわけですが、その後を読んでいくとやっと理由がわかりました。
elsif ( 'user_custom' eq $sort_by ) {
my $blog = $ctx->stash('blog');
my $meta = $class_type . '_order';
my $text = $blog->$meta || '';
@$cats = MT::Category::_sort_by_id_list( $text, \@cats );
@$cats = reverse @$cats if $sort_order eq 'descend';
}
あぁなるほど、「sort_by="user_custom"」の場合は別に処理するわけですね。それでどうやら先ほど見つけた「category_order」を、Categoryオブジェクト(上の@cats)と一緒に、MT::Category::_sort_by_id_listに渡すことで、並べ替えが行われるみたいです。
my @folders = MT->model( 'folder' )->load(
{ blog_id => $blog_id,
parent => '0'
}
);
my $meta = 'folder_order';
my $text = $blog->$meta || '';
@$folders = MT::Category::_sort_by_id_list( $text, \@folders );
@$folders = reverse @$folders if $sort_order eq 'descend';
こうすりゃいいってことですね。 うまくいきました。
- Comments: 0
- TrackBacks: 0
ブログ記事投稿ユーザーのコンテクスト
- 2012-04-22 (日) 21:07
- MovableType
現在進行中の案件では、コミュニティ・ソリューションをベースに構築を行なってます。
ユーザーに対してカスタムフィールドで情報を追加してやって、それを記事一覧や、コメント一覧で表示しようと思っても、実はそれを行うブロックタグはMTには存在しません。
ユーザーコンテクストを生成するプラグイン
ブログ記事の投稿ユーザーに関するMTMLタグは「<$MTEntryAuthor$>」「<$MTEntryAuthorDisplayName$>」「<$MTEntryAuthorEmail$>」「<$MTEntryAuthorID$>」「<$MTEntryAuthorLink$>」「<$MTEntryAuthorNickName$>」「<$MTEntryAuthorURL$>」「<$MTEntryAuthorUsername$>」「<$MTEntryAuthorUserpic$>」「<MTEntryAuthorUserpicAsset>」「<$MTEntryAuthorUserpicURL$>」です。沢山あるのに大半はファンクションタグであり、ブロックタグとして登録ユーザーのコンテクストを生成するタグは存在しません。
「Movable Typeでブログ記事投稿ユーザーの情報を取得するEntryAuthorDataプラグイン: 小粋空間」を使うことで、ブログ記事投稿ユーザーのコンテクストが生成できます。
記事内には、MTタグで投稿ユーザーのコンテクストを生成する方法として、以下が書いてありますが、コレは必ずしもうまくいかないのではと思います。
<mt:Entries>
<$mt:EntryAuthorDisplayName setvar="name"$>
<mt:Authors display_name="$name">
<$mt:AuthorBasename$>
</mt:Authors>
</mt:Entries>
[Movable Typeでブログ記事投稿ユーザーの情報を取得するEntryAuthorDataプラグイン: 小粋空間:(2012年4月22日 18:56:31 引用)]
コレが成り立つためには、EntryAuthorDisplayNameがNULLを許容せずに、かつuniqueである必要があるものと思いますが、同一の表示名を登録可能なようですし、説明文にもあるように入力しないことも可能なようです。
セキュリティ上の理由により、ユーザー設定で表示名の設定が無い場合、何も表示されません。
[MTEntryAuthorDisplayName | テンプレートタグリファレンス:(2012年4月22日 19:19:00 引用)]
さてコメント投稿ユーザーのコンテクストは以下のプラグインで取得できます。
「Comment Author Context | MovableType.org - Home of the MT Community」
入手元が「plugins.movabletype.org」だけなので、そのうち入手できなくなるかも知れませんね。
また詳細は不明(詳しい追跡調査を行なっていませんが)なのですが、どうもこのプラグインを入れると、パスワードの変更に影響が出るようですし、「ユーザー」メニューを開く操作もおかしな動きになってしまうようです。特に後の方は、MT5.1への対応の問題ではないでしょうか。(最終的には後述の方法を使いプラグインは使用しなくなりました。)
ダイナミックパブリッシングでうまくいかない
さて、とりあえず、プラグインで処理する方向で進めていたのですが、途中でアーカイブの分割処理(DynamicMTMLによるアーカイブのページ分割・これは後日別エントリーにします)や、コメント欄でのログイン中のカレントユーザーの表示部分など、幾つかダイナミックパブリッシングで処理する箇所が出てきて、上記プラグインで対応できない部分があることが発覚しました。
まぁ、ダイナミックパブリッシングプラグインを書くという選択肢もあるわけですが、もう一度標準のMTタグだけで同じ処理ができないか考えてみました。
ユーザーのコンテクストはやはり、MTAuthorsを使って出力する以外なさそうです。
またMTAuthorsには残念ながら、特定のユーザーを指定するのにid指定を行うなどは出来ないようで、display_name指定で読む以外の方法はなさそうでした。
という訳で、MTAuthorsでdispaly_name(+追加指定)を指定し、ユーザー候補を読み込んだ後で、ユーザーのID(ブログ記事投稿者のIDやコメント投稿者のIDを取得するタグは存在する)により、対象ユーザーを確定する方法を取ることにしました。まぁ今回の案件では表示名の設定が必須になるように、登録画面に制限を加えていることもあり、display_nameである程度の絞り込みが出来るわけですが、これを指定しない状態で1000ユーザーや10000ユーザーを対象とした場合に、実用に耐えられるかはチョット問題ありそうですね。やはり最初のブロックタグである程度件数が絞り込めてないと、スケールアップしていった時に対応できなくなりそうです。(そういや、このモディファイア「display_name=""」とした場合は表示名を設定していないユーザーのみの絞込みになるんだろうか?)
<MTEntryAuthorID setvar="author_id"> <MTEntryAuthorDisplayName setvar="display_name"> <MTAuthors need_entry="1" display_name="$display_name"> <MTIf tag="AuthorID" eq="$author_id"> <$mt:AuthorBasename$> </MTIf> </MTAuthors>
こんな感じでどうにかなるのではないかと。
投稿された記事を表示するコンテクスト内で使用するものなので、少しでも対象を絞り込めるように「need_entry="1"」も指定してあります。その他ロールなど特定の条件が存在するならそれも追加したほうがよさそうですね。ここは、いかにMTAuthorsブロック内のループ回数を減らすかが、安定運用のキモになってくるはずです。
<MTCommenterID setvar="commnter_id"> <MTCommentAuthor setvar="commenter_name"> <MTAuthors display_name="$commenter_name" need_entry="0" any_type="1"> <MTIf tag="AuthorID" eq="$commnter_id"> <$mt:AuthorBasename$> </MTIf> </MTAuthors>
コメントの方も同じくこんな感じで処理できると思います。ただ、まだるっこしいですね。
MT5.2への要望
という訳で、MT5.2への要望です。
上記のように、実は基本的なMTタグで欠けているものがあります。MT5.1でのMTEntryPrimaryCategoryの様に、コレを待ち望んでいたんだというのが多々あるはずです。
ぜひ、ブログ記事の投稿ユーザーのコンテクストを生成する、MTEntryAuthorContextタグと、同じくコメントの投稿ユーザーコンテクストを生成する、MTCommnetUserContextの、MT本体への実装をご検討ください。
- Comments: 0
- TrackBacks: 0
ブログ記事の本文にスニペットやmtevalなどを使っている時は注意しよう
- 2012-04-05 (木) 23:42
- MovableType
なぜ、いきなりこんな記事というのは・・・ほっといてください。
値に 1 を設定すると、モディファイアを付与したファンクションタグの内容に含まれる Movable Type タグを展開します。
たとえば、MTEntryBody にこのグローバルフィルターを設定すると、ブログ記事本文で MTタグを使用できます。
[mteval | グローバル・モディファイアリファレンス:(2012年4月5日 20:24:19 引用)]
これは、かなり便利な機能です。MTInclude でプロフィール画像モジュールを使うなんて、天才的です。しかも変数としてユーザー名渡すなんてうますぎる。ただ、一箇所詰めが甘かった・・・
本文が使われる場所
ブログ記事の本文というのは、意識していない箇所にも使われています。
単純に公開された記事(ブログ記事テンプレート)だけではないんです。そこが要注意。
例えば今回のように「最新記事のフィードテンプレート」内には、「<summary><$mt:EntryExcerpt remove_html="1" encode_xml="1"$></summary>」だけではなく、以下の記述も存在します。
<content type="html" xml:lang="<$mt:BlogLanguage ietf="1"$>" xml:base="<$mt:BlogURL encode_xml="1"$>">
<$mt:EntryBody encode_xml="1"$>
<$mt:EntryMore encode_xml="1"$>
</content>
それからMTEntryExcerptも注意すべき。
ブログ記事の概要に入力した内容を表示します。概要に記述がないときは、ブログ記事の本文を、ブログ記事の設定で指定した概要の文字数だけ先頭から表示します。
[MTEntryExcerpt | テンプレートタグリファレンス:(2012年4月5日 20:39:43 引用)]
ブログ記事本文から自動生成された部分に、MTタグやスニペットコードが含まれていたとか、予想外の落とし穴が待っています。しかも自動生成の概要は文字数により切り取られますので、たまたまMTタグの途中で切り取られるというケースもありえます。
以上のことを踏まえて、フィードなどでのEntryBodyやEntryMoreが使われている部分には、必ず本文と同じグローバルフィルターを付ける必要があります。また検索などの動的生成についても同じく対処が必要です。
本文は、ソレでいいのですが自動生成時の概要などは、対応が難しかったりします。私は極力そういう場合、MTEntryExcerptタグは使わずに、MTEntryBodyから生成させるようにしています。
例えばmetaタグのdescriptionに、MTのデフォルト設定で概要を指定したい場合(要は100文字ということです)で、本文にMTタグを使い、mteval指定している時は次のように生成させます。
<meta name="description" content="<$MTEntryBody mteval="1" remove_html="1" trim="1" strip_linefeeds="1" trim_to="100+..." escape="html"$>" />
この場合、remove_htmlする前に、mteval処理するのがキモです。他にもスニペットなどの処理がある場合には、ここにグローバルフィルターを追加します。一旦HTMLとして変換出力した後で、HTML要素を削除し整形し、HTMLエスケープを行なっています。
また、コレとは別に同じく概要で生成される部分ですが、MTEntryTrackbackDataは要注意です。最近は使っている方も居ないかも知れないですが、コレが出力するRDF内にも記事の概要が出力されます。この出力については、上手に処理がしにくいので、以前はRDF自体をMTMLで記述し直して対応していました。今は出力していません。
通常ブログ記事ページ内は、キチンとチェックするのですが、どうしてもこういう細かいメタ情報などの部分は、処理を忘れがちです。
本文にグローバルフィルターを追加する場合は、一度全テンプレートを見直すぐらいの気持ちで、影響範囲を確かめるようにしましょうね。実際かなりのサイトのメタ情報でMTタグやスニペットを見かけたことがあります。
- Comments: 0
- TrackBacks: 0
list_actionsのconditionはcode実行時にもチェックされる
- 2012-04-05 (木) 17:54
- MovableType
ふと思いたち、以下のプラグインを現在のMT環境での動作用に修正してみた。
「byrnereese/mt-plugin-batchtmploptions」
まぁ、機能的には同じものがすでに以下のように存在するのだが、自分の勉強も兼ねてやってみました。
「alfasado/mt-plugin-set-template-build-type」
このプラグインは、テンプレートのプラグインアクションに、テンプレートの公開設定を直接変更するプルダウンを追加するもので、オリジナルのままだと、公開設定が行えないモジュールやシステムテンプレート等に対しても表示されています。
表示制限のために「condition」を付けてみることにしました。意外と情報ないなぁ。
探してみた「リストアクションの追加 · movabletype/Documentation Wiki」も、あまり参考になりません。
applications:
cms:
list_actions:
template:
publish_static:
label: Publish Statically
order: 105
code: $BatchTmplOpts::BatchTmplOpts::Plugin::itemset_stc
permissions: can_edit_templates
condition: $BatchTmplOpts::BatchTmplOpts::Plugin::is_publish
「condition」は該当するアクションが、表示されるかされないかを設定するもので、「return 1;」の場合に表示「return 0;」で非表示です。上記で言うとプラグイン内の「lib/BatchTmplOpts/Plugin.pm」の「is_publish」がソレを返します。
どうやら、テンプレート表示時には「filter_key」というパラメータで、各テンプレートの表示を絞り込んでいるようです。
なので、以下のようにすると「インデックステンプレート」と「アーカイブテンプレート」の時のみ表示されるようになります。
my $tmpl_type = $app->param('filter_key') || '';
if (($tmpl_type eq 'index_templates')||($tmpl_type eq 'archive_templates')) {
return 1;
}
return 0;
これで、うまく表示が制限されるようになりました。
さて、念のためと思って実際に使用してみると、何故かエラーが発生します。メッセージは以下のとおりです。
アクション(publish_static)が実装されていません。
イロイロ原因を調査してみて、どうやら上記の「condition」が影響しているようでした。
どうも、結果から考えると、管理画面の表示のタイミングだけでなく、コードの実行時にも「condition」の評価は行われるようです。その時に渡されている変数などが、管理画面表示と異なるため「return 0;」が戻ることが原因のようです。
「意外とめんどくさいのね」とか思いながら、他のプラグインの対応を見てみたら、「SetTemplateBuildType」ではconditionでの制限はせずに、出力されたものを管理画面上で置換処理を行い削除しているようです。
なるほど、それではMT本体のコードはどの様に処理しているかを見てみようと思いました。
「lib/MT/App/CMS.pm」「core_list_actions」の「template」部分を見ると、どうやら以前使用されていた公開プルダウンのコードが残っており(小粋空間: テンプレート一覧のアクションに「テンプレートの再構築」を追加する)、ソレを追いかけると、どうも「$app->mode eq 'itemset_action'」の時は無条件で「return 1;」になっているようです。プラグインアクションを実行した場合は無条件で正しいものとして扱うということですね。
うーん、それは・・・
それなら、そもそもプラグインアクションの実行時に、「condition」を見る必要はないのではとか思っちゃいました。まぁ中には有効なケースも存在するということなのかなぁ・・・
sub is_publish {
return 0 if (MT->version_number < 5);
my $app = MT->app
or return 0;
my $blog = $app->blog
or return 0;
return 1 if $app->mode eq 'itemset_action';
my $tmpl_type = $app->param('filter_key') || '';
if (($tmpl_type eq 'index_templates')||($tmpl_type eq 'archive_templates')) {
return 1;
}
return 0;
}
とりあえず、以上で完成しましたので、プラグイン公開します。元プラグインはライセンス指定書いていないんだよねなぁ。たぶんGPL v2.0では無いかと思います(ここは特に根拠なし)。
「naoaki011/mt-plugin-batchtmploptions」です。
気が向いたら使ってください。
まぁ、サイトの構築中のような、頻繁に公開設定を変更する場合以外は、あまり出番がないプラグインですけどね。
ついでにここでも、権限チェックしたほうがいいのかなぁ。まぁでも表示に関しては「permission」で絞り込まれるしな。
- Comments: 0
- TrackBacks: 0
- Tag Cloud
- Feeds
- Link Status
- In One
-
位置情報ブログパーツ「なかのひと」
- Links
-
- 3.5ping.org (by wu)
- Movable Type備忘録 (by bzbell) Closed
- 亜細亜ノ蛾 - Weblog (by asiamoth)
- Under the Bridge (by yoshi) Closed
- WingMemo (by TAEKO)
- Webmaster@Style (by アットスタイル)
- blog.aklaswad.com (by aklaswad)
- Junnama Online (Mirror) (by junnama)
- crema design (by crema)
- The blog of H.Fujimoto (by 壱)
- Ogawa::Buzz (by Ogawa)
- 小粋空間 (by yujiro)
- 世界中の1%の人々へ (by Dakiny)
- TOTOCO.ORG (by nin)
- 19740308(TM) (by トミナガ)
- キアズマ (by キアズマ)
- nlog(n) (by n)
- エムロジック放課後プロジェクト
- mersy’s lab (by mersy)
- デザインユニット linker(リンカー)
- Open MagicVox.net (by ぴろり)
- 小さな世界 (by にっく)
- かたつむりくんのWWW (by TinyBeans)
- Technology on Information - ToI (by たく)
- maRkのMyOwn (by maRk)
- Weeeblog.net (by okayama)
- Using MT (by Shinichi Nozawa)
- HashiMのたわごと(?) (by HashiM)
- 45式 (by 4n5)
- Powered By


