2010年2月アーカイブ

続き。

MTベースの開発案件の時に「DBのスキーマはどうなりますか? ウチの方でPHPでMySQL叩いて開発とか後でできるでしょうか?」みたいな話が出るので。静的に動的なページを吐き出す(??)サンプル書いてみました。

エントリーを20件リストで表示する、ただそれだけ。直に書いてしまうとせっかくのテンプレートとロジックの分離のメリットが活かされないのですが、部分的に動的な処理を入れたいといった時にはまぁこんなやりかたも出来るということを覚えておいても良いと思います。

インデックス・テンプレートを作成し、「公開→スタティック」「出力ファイル名→foo.php」として保存・再構築。ブログ記事のリストの部分は動的に都度処理されます。それだけですが...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=<$MTPublishCharset$>" />
    <title>DPAPI Example - <MTBlogName escape="html"></title>
</head>
<body>
<?php
    include('<$MTCGIServerPath$>/php/mt.php');
    $mt = MT::get_instance(<MTBlogID>, '<$MTCGIServerPath$>/mt-config.cgi');
    require_once("MTUtil.php");
    $args['class'] = 'entry';
    $args['blog_id'] = <MTBlogID>;
    $args['offset']=0;
    $args['limit']=20;
    $entries = $mt->db()->fetch_entries($args);
    $max = count($entries);
    $i = 0;
    foreach ($entries as $entry) {
        if ($i==0) {
            echo '<ul>';
        }
        echo '<li>' . encode_html($entry->title) . '</li>';
        $i++;
        if ($i==$max) {
            echo '</ul>';
        }
    }
?>
</body>
</html>

スタッフの仕事の進捗がヤバげだったので急遽phpを担当することになってブロックタグの大物をMT5対応するためにガンダムBrand new APIと格闘してみたメモ書き。

# Power CMS for MTにはPHPプラグインが189もあるんだよ...

Twitter / Junnama Noda: MTのPHP API使ってアプリ開発してるのって日本でhoge人くらいなんだからこんなに力入れてガラッと変えなくても(泣)

さて、ブロックタグの中でのオブジェクトのロードや利用についてのメモを中心に。

エントリーをロード

$args['class'] = 'entry';
$args['blog_id'] = $blog_id;
$args['offset']=n;
$args['limit']=n;
$entries = $ctx->mt->db()->fetch_entries($args);

範囲指定をしてsqlでエントリー(や他のオブジェクト)を読み込む

$entries = $ctx->mt->db()->SelectLimit( $sql, $limit, $offset );

(範囲の指定無し)sqlを実行

$entries = $ctx->mt->db()->Execute( $sql );

読み込んだオブジェクト数の取得

$entries->RecordCount();

個々のレコードの取得

$entries->Move($counter);
$entry = $entries->FetchRow();

エントリーのオブジェクト化(但しcategoryやカスタムフィールドの読み込みはSQL側で調整する必要あり)

$e; 
while(list ($key, $val) = each($entry)) {
    if (preg_match('/^entry_/',$key)) {
        $e->$key = $val;
    }
}
# $ctx->stash('entry', $e);

特定のブログ記事オブジェクトの読み込み

$e = $ctx->mt->db()->fetch_entry($id);

特定のウェブページオブジェクトの読み込み

$e = $ctx->mt->db()->fetch_page($id);

Findでオブジェクトを読み込み

require_once 'class.mt_entry.php'; #entry
$_entry = new Entry;
$where = $where_statment;
$extra = array(
    'limit' => $limit,
    'offset' => $offset,
); 
$results = $_entry->Find($where, false, false, $extra);

続きがあります...

参考

MT::App::CMS(mt.cgi)のテンプレートファイル(tmpl以下、もしくはalt-tmpl以下の .tmplファイル)の中でMTタグを使えるうようにするプラグインCMSContextの新しいバージョン(β)を公開します。

コアなMTユーザーに評判? のプラグインをバージョンアップします(クレジットがウチの会社になってるんですが、とりあえずβということで先行してここで配布してみます)。ちなみに昨日No test, No document とか言ってTwitterに貼っていたやつはやっぱり(?)バグってました(今回のはざっとテストしましたすいません)。

改良点/追加された機能

  • テンプレートの複数箇所でタグが利用された時にキャッシュを使うことでDBへのアクセスを減らしました(これは昨年末の実装)。
  • 新たに「ユーザー情報の編集」画面でMT::Author系のタグを利用できるようになりました(CMSContextタグの中で)。
  • alt-tmplのパスを置き換えるのはそもそもCMSのContextとは別の話なので設定されていない場合はデフォルトのalt-tmplのままとしました。
  • alt-tmplのパスをシステムプラグイン設定及びブログ毎のプラグイン設定で設定出来るようにしました(ブログの設定があればそちらが優先されます)。
  • alt-tmplのパスをユーザーエージェント毎に指定できるようになりました。iPhone用の管理画面を作る、といった使い方が出来ます。
  • URLのパラメタをテンプレートのパラメタに自動的にセットするようにしました。mt.cgi?foo=bar とした場合、<mt:var name="cms:foo" escape="html"> といった形で取り出すことが出来ます。
  • ユーザーエージェント判別やその他いくつかのテンプレート・タグを追加しました。

要するにこれを使うとiPhone用MT管理画面とかが簡単に作れるようになります(誰か是非頑張ってくださいね)。あと...Nokiaは要らないよね? そうだよね?

テンプレートの例

alt-tmpl/cms/edit_entry.tmpl

<MTCMSContext>
    <MTEntryTitle escape="html">
</MTCMSContext>

<MTIfUserAgentIsiPhone>
    # Some Template for iPhone
</MTIfUserAgentIsiPhone>

設定画面

Safari003.jpg

タグ

タグはCMSのテンプレート中で利用できます。

ブロックタグ

MTCMSContextCMSのテンプレートの中でMTEntries等のタグを利用できるようになります。
MTIfUserCan現在のユーザーがpermissionモディファイア(例:can_post)で指定した権限を有している場合に真となります。
MTIfUserAgentIsiPhoneユーザーエージェントがiPhone/iPod Touchの場合に真となります。
MTIfUserAgentIsDoCoMoユーザーエージェントがDoCoMoの場合に真となります。
MTIfUserAgentIsAUユーザーエージェントがauの場合に真となります。
MTIfUserAgentIsSoftBankユーザーエージェントがSoftBankの場合に真となります。
MTIfUserAgentIsMobileユーザーエージェントがiPhone/iPod Touch/DoCoMo/au/SoftBankの場合に真となります。
MTIfUserAgentIsKeitaiユーザーエージェントがDoCoMo/au/SoftBankの場合に真となります(iPhone/iPod Touchの場合は偽)。

ファンクションタグ

MTUserAgent$app->get_header( 'User-Agent' );の値をそのまま出力します。

プラグインのダウンロード

ライセンス

問い合わせいただいたのとユーザー名が正しくてパスワード違いの場合にブロックできなかったことが判明したので修正しました。

加えて、IPアドレスのホワイトリスト/ブラックリストに対応させました。IPリストは改行区切りで。画像のように 192.168.11.0/24 のような記述にも対応しています。

ユーザー名やパスワードを間違うことでアクセス元IPアドレスからのログインを一定時間制限します。IPアドレスについてはホワイトリスト→ブラックリストの順にチェックします。お分かりいただけると思いますが設定を間違えるとログイン出来なくなりますのでご利用は計画的に! (無保証、自己責任でのご利用をお願いします)。

Protectionプラグインの設定画面

プラグインのダウンロード

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

続きです(当日のデモで関連付けがうまくいかなかったのが余程悔しかったのだろう...)。

この方法で出来ないのは、エントリーに対するタグの重み付けなんですね。例えば上記エントリーには「MTDDC」というタグが最も重みが付けられるべきで、そうなれば確実に当日も失敗? しなかったわけです。ところが現状の方法では単語の出現回数なんかでの重み付けがなされないのです。

これについてはMT::ObjectTagオブジェクトを拡張してタグの重み付けを付けるという方法なんかが考えられますが(出現回数なんかでスコアを付ける)、興味のある方はトライしてみても面白いんじゃないでしょうか。

と書いてみたものの...というか「興味のある方=俺」なので取り敢えずMT::ObjectTagに「score」というカラムを追加して出現回数を保存するようにしてみた。

scoreを追加したobjecttagテーブル

今回はここまででRelatedEntryを取り出すほうはまだなんだけどね。

MT5にも対応させました。ってかそのままで行けたのでMT5で設定されてない場合はclassがwebsiteのブログを1つロードするようにしました。

完全に自分のために書いた。MT4で複数のブログを作成してサイトを運用しているケースで、メインとなるブログを指定してその下に子ブログぶら下げて運用すること多いと思うんですよ。自社のサイトでもそうしてます。

でね、結構サイトを確認しながら新しいページや記事を作成することが多いわけです。サイト内の他のページにリンクを貼ったり過去の記事を確認しながら表記やマークアップ整えたり。

で、ダッシュボードとかシステムメニューに行った時に「サイトの表示」リンクがないためにURL直接叩いたりメインのブログに移動してからリンククリックしてることが実は多くて、なんでここにリンクがないんだろうって思ってた。

システムメニューに「サイトを表示」ボタンを追加

URLはシステムプラグイン設定で登録。登録されてなければIDの一番若いブログのsite_urlをセットします。

プラグイン設定画面でサイトのURLを指定

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

きっかけはTwitterでのこのあたりのやりとりと、今お手伝いしているコンクール絡みのイベントがあるっていうことなんですが、Twitterに声で投稿できるかというテーマがあって、ちょっとやってみた。らくらくホンでTwitter(モバツイッター(以下モバツイ))を使って気づくあたりの話も含めて少し紹介したい。

Twitter / aok mto: .@fshin2000 伝言です。らくらくホンの音声「入力」にも対応してほしい。私自身は未経験なため、何も差し挟む余地はありませんです。土曜日に弱視の人の集まりで、聞きました。

Twitter / Junnama Noda: おそらく音声メールなのでユーザー毎にメール経由のポスト可能ならいけるのでは? http://bit.ly/9Eco70 RT @fshin2000: @pinpain そんな機能があるんですか。なんかブラウザベースだと難しそうな気もしなくもないけど...

Twitter / えふしん: @junnama @pinpain じゃぁ「メール投稿」でできますね。

イベントはこちら。2月24日開催です。

機種はF884i(らくらくホンプレミアム)。僕の記憶ではこの機能(音声メール)はオプションで月々210円。興味あったので申し込んでおいたのです。使ったのは今回が初めて。有料である理由は、変換を行うのをiアプリからASP経由で行うため。つまり、流石にこの携帯の中にそれだけの処理が出来るものが埋め込まれているわけれはなく、音声認識からテキスト化は外部のサーバーを使っているのです。

このあたりについては少し前の記事ですが下記のページに紹介記事があります。

音声入力中の画面

尚、当然ながらただ音声で入力するだけでなく、ウェブの読み上げから投稿操作までは音声ガイダンスを通じて出来ます。まったく画面を見ることなく僕にも投稿が行えました。

手順は下記の通り。

  • モバツイへアクセス
  • メール投稿
  • メール作成(題名入力状態)
  • 本文欄へ移動
  • [カメラボタン]でiアプリ起動
  • 決定ボタン
  • バイブが振動(または音声ガイダンス)
  • 声で入力(30秒以内)
  • iアプリがサーバーに通信してテキスト変換
  • 確認>確定
  • 続きがあれば再度[カメラボタン]でiアプリ起動
  • 内容確定後、送信

一連の動き? を音声ファイルにしましたのでアップします。

さて、感想等

「Twitter+モバツイ+らくらくホンが拓く新しい世界」なんていうタイトルを書いたわけですが、これやっぱり新しいコミュニケーションの世界なんだと思います。不思議な感じ。

実際僕が視力を失ってスクリーンリーダーのお世話になることを考えたらそれなりにかなり必死で取り組まなきゃならないと思うんですが、Twitterを使うだけなら実際自分で画面見ないでいけましたから。入力、確認といった煩わしさもなく、まさにTwitter的な世界観とでもいうのでしょうか。

昨日からの帰り道に練習がてらポストしてみたんですが、何ていうか電話で会話している感じ。タイムラインを読み上げて、アクセスキー[3]でメール投稿画面へ飛び(欲を言えばアクセスキー[3]でダイレクトにメールが立ち上がって欲しい。そうすればもっとシームレスに読み上げ>投稿へ移行できる)、そこから上記の手順でポストします。ひとこと程度のつぶやきなら30秒でいけるし、少し長いものは複数に分けて入れます。ただ、このあたりはいずれ技術が解決してくれると思う。

日常的に使うのであれば変換サーバーとのやりとりの待ち時間とかiアプリ起動の待ち時間とか気にならないわけじゃないですが、新しい可能性を十分に感じさせてくれます。

モバツイのアクセシビリティ

モバツイの[元]省エネモード、らくらくホンをも意識されたようなシンプルな表示モード、これで音声読み上げモードでは格段に使いやすくなります。理解もしやすいようにリンクのラベルも工夫されています。このあたりは仕方ないんだろうけど、慣れてくると少しラベルが冗長に感じられるようにはなりますが。慣れてしまうと「このつぶやきにリプライ@」→「リプライ」のほうがシンプルだし、上級者モードとかを作るのがいいのかもしれないですね。あるいは「ガイダンスモード」っていうのがあって、ガイダンスモードでは「このつぶやきにリプライ@」、通常モードでは「リプライ」とか。開発側の負担は間違いなく増えますが、こうなればもっと使い勝手が良くなると思います。

アクセシビリティ=アクセス出来ること、であれば冗長なラベルであってもクリアできてるわけですが、携帯電話、音声読み上げに最適化となれば、ラベルの長いのは少し気になります。

ただ、これはUA側で例えばa要素のtitleを読み上げるかどうか、とかいった実装が出来るようになれば解決する問題でもあります。アクセシビリティって結局最後はそういった話になるんだと僕は思います。

もう一点は既に書きましたがアクセスキー[3]でダイレクトにメールが立ち上がって欲しい。これはえふしんさんもそう感じてもらえたみたいだから、別に音声読み上げに限ったことじゃないですよね。

Twitterそのものが抱える(日本語環境での)アクセシビリティ

これはモバツイに関することじゃないんですが、一番読み上げていて気になるのは実は「ユーザー名」なんです。例えば「fshin2000さん」は、「えふえすえっちあい、にせんさん」です。「junnama」じゃ「じゅんなま」なんですが。英語圏なら名前が単語として登録されているケースが多いでしょうから読めると思うのですが、たとえば「にせんさん」てのは「2003」ともとれてしまうし(fshin2000さんすいません、特に取り上げた理由はないんですw)ユーザー名は本当にわかりにくいです。

ログイン名が表示されるのはTwitterの仕様だから、ここは「設定」画面の「名前」のほうを表示することで解決出来そうな気もします。但しTwitterは@ユーザー名っていうルールがあるので、つぶやきの本文の中にもユーザー名が頻繁に出てきます。とはいえ実際の読み上げ環境で利用しておられる方はさほど気にしておられないのかもしれませんが。とはいえ、絶対名前が日本語で扱えた方がわかりやすいと思う。これは絶対にそうだと思います。

それでもこれは新しい体験、新しい世界

例えばiモードブラウザのインプット要素やテキストエリアが同じく音声入力に対応してサーバーへの接続時間等の問題が解消されたら(またサイト制作者側がこういった用途を意識して構築を行えば)、あたらしい可能性が広がるんじゃないかって。そう思います。正直新鮮な体験でした。ケータイサイトやケータイWebサービスを構築している人には是非とも考えて欲しいテーマです。

それでは、次回はイベントでお会いしましょう。

関連エントリー

テスト用のポストをします。

先週末に行われたMTDDCに参加してライトニングトークで大トリ? をつとめさせていただきました。前日まで何を話すか決めてなかったんですが、今回はまぁ大阪開催じゃないし? ネタ抜きにして純粋にハックネタを話させていただきました。さすがに数百人前にしてつまらないネタじゃ悪いし(しかも時間一時間近く押していて、あそこで滑ると会場のコンテキスト? に影響するっていう危機感もありましたし。

すでにお気づきの方もいらっしゃる通り、今回のネタは今年一発目に上げた下記のエントリーの改良版です。

タグのプライベートモードを使うっていうのを直前に思いついてしまったのが今回の肝でした(しかし何でググると3.3のドキュメントが出てくんの?)。

方針は以下の通りです。

  • 一回目の保存時には入力されたタグがあればそれにプラスしてタグが自動追加される
  • ユーザー辞書に登録されている単語は無条件にタグとして登録される
  • タイトルに1度以上、もしくはタイトル+テキストに2回以上出現した単語で「名詞,一般」もしくは「名詞,固有名詞,組織」にマッチするもの、且つ一定以上のバイト長の単語(サンプルでは[7]以上)をプライベート・タグとして登録する

前提としてMeCab、MeCab.pmをインストールする必要があります。ここで紹介するパスは私のMac上でのパスです。MacPortを使ってインストールしているので、一般的な環境とは異なるであろうことご了承ください。

タグとして登録したい単語を下記のようにCSVを作成した保存します。ここでのポイントは「Movable Type Developers & Designers Conference」を「MTDDC」として登録する等のようにマッチした文字列をタグとしてどのように登録したいかを定義付けることです。この辞書では「アルファサード有限会社」と「アルファサード」は同じ「アルファサード」として登録されるようになります。

Movable Type Developers & Designers Conference,-1,-1,1,名詞,一般,*,*,*,*,MTDDC,MTDDC,MTDDC,Tags
プラグイン,-1,-1,1,名詞,一般,*,*,*,*,プラグイン,プラグイン,プラグイン,Tags
Movable Type,-1,-1,1,名詞,一般,*,*,*,*,Movable Type,Movable Type,Movable Type,Tags
アクセシビリティ,-1,-1,1,名詞,一般,*,*,*,*,アクセシビリティ,アクセシビリティ,アクセシビリティ,Tags
アルファサード有限会社,-1,-1,1,名詞,一般,*,*,*,*,アルファサード,アルファサード,アルファサード,Tags
アルファサード,-1,-1,1,名詞,一般,*,*,*,*,アルファサード,アルファサード,アルファサード,Tags
セミナー,-1,-1,1,名詞,一般,*,*,*,*,セミナー・イベント,セミナー・イベント,セミナー・イベント,Tags
イベント,-1,-1,1,名詞,一般,*,*,*,*,セミナー・イベント,セミナー・イベント,セミナー・イベント,Tags
リリース,-1,-1,1,名詞,一般,*,*,*,*,リリース情報,リリース情報,リリース情報,Tags
cd /opt/user
sudo /opt/local/libexec/mecab/mecab-dict-index -d /opt/local/lib/mecab/dic/ipadic-utf8 -u user.dic -f utf8 -t utf8 dict.csv

user.dicが生成されるので、mecabrcにこのファイルをユーザー辞書として使うように登録します。

vi /opt/local/etc/mecabrc

下記の行を追加

userdic = /opt/user/user.dic

プラグイン(当日使ったものです)をMTにインストールします。

自動的に付けられたタグ

これで、ユーザー辞書に登録してあるものは無条件に、形態素解析で自動追加したものは「プライベートタグ(@からはじまる隠しタグ)」として登録されるようになります。

あとはogawaさんの TagSupplementalsプラグインにお任せです。

<mt:EntryIfTagged>
<div class="entry-body">
<h2>関連する話題</h2>
<ul>
    <MTRelatedEntries lastn="3">
        <li><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
    </MTRelatedEntries>
</ul>
</div>
</mt:EntryIfTagged>

関連エントリーを自動表示

ちゃんと大阪でのMTDDCの記事が一番目に出てますよね?(当日失敗したのは...自動でタグ付けされるのを見せたいがために文章色々直前で追加しちゃったんですよね...クソ!)

この方法で出来ないのは、エントリーに対するタグの重み付けなんですね。例えば上記エントリーには「MTDDC」というタグが最も重みが付けられるべきで、そうなれば確実に当日も失敗? しなかったわけです。ところが現状の方法では単語の出現回数なんかでの重み付けがなされないのです。

これについてはMT::ObjectTagオブジェクトを拡張してタグの重み付けを付けるという方法なんかが考えられますが(出現回数なんかでスコアを付ける)、興味のある方はトライしてみても面白いんじゃないでしょうか。

翌日のHack-A-Thonにも参加しましたが、こっちのほうはまたいずれ。

Facebook

Twitter

このアーカイブについて

このページには、2010年2月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2010年1月です。

次のアーカイブは2010年3月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 6.2.6