2008年2月アーカイブ

某SNSで立て続けに上がってたので。

こういう時はコードを見るのですよ。せっかくPerlで書かれてるのだから。

/lib/MT/App/Wizard.pm


    require LWP::UserAgent;
    my $ua = LWP::UserAgent->new;
    my $request = HTTP::Request->new(GET => $path);
    my $response = $ua->request($request);

つまり、HTTPリクエスト送ってmt-staticの存在確認してるわけですね。だから、例えばサーバーから名前解決して123.456.789.0 とかIP返ってきた場合に、実はサーバーでは192.168.XX.XXとかにアクセスしなきゃならない時とか、テスト段階でBasic認証かけてる時とかはmt-staticが見つからん、ということになる(んじゃないかな。ちゃんと見てないけど)。 だから、サーバーのほうのHOST (/etc/hosts) ファイルとか設定してサーバーからちゃんとアクセスできるようにしてやればこのエラーは出ないんだと思うよ。

仮に、もし本当にこの仕様なんだったら(多分そうだと思うけど)、SixApartさんには見直しをお願いしたい(ローカルディスク上mt-staticのパスを見に行けばいいんじゃないでしょうか!?←これは駄目だな。ブラウザからアクセス出来るかどうかを見るようにすればいいんじゃないかな)。


追記:
「This URL path can be in the form of http://example.com/mt-static/ or simply /mt-static」日本語版では「このURLは http://example.com/mt-static/ のように入力するか、又は簡略化して /mt-static のように記述できます。」とテキストフィールドの下に出るわけですが、これ見落としますね。エラーが出ているのにグレー文字だし。画面の上のイエローのところに目が行きます。

ただ、この画面が出ている時点でCSSが読めている = mt-staticへのパスは通っているわけだから、見つからないっていうのはやっぱりユーザーへのフィードバックとしては「迷い」「混乱」の元かもね。

さらに追記:
ユーザーのブラウザからmt-staticが見えているかどうかが問題なのだから、こういう時こそAjaxでチェックするってのが良いように思えてきた...


CMSとして使うなら、まず最初はBasic認証付きのバーチャルホストとかでサイト設定してスタート、ってことも結構あるし。

いや、すいません投げやりで。月曜のセミナーの準備してますので許してくださいごめんなさい。

まずは普通の感想。まぁこんなもんでしょう。極端に外れている感覚ではない。但し色々突っ込みどころというか考えねばならぬことも。

人月なのかっ!?

表は標準的な単価の会社(1人月80〜100万円程度)の場合のものとなっている。単価の高い制作会社(1人月150万円以上)ならば、同じ予算でもできることが1つ左にシフトすると考えるといいだろう。逆に、単価の安い制作会社(1人月50〜70万円)ならば、同じ予算でもできることが1つ右にシフトする。

80万〜100万円ってのは一つの指標で、このくらいの数字を出さないと会社としては存続しにくい。世間がどうとか相場がどうとかいう以前に、銀行さんが優しい顔してくれんのですよ(多分)。Web屋も会社だからね。普通に経営していくために金融機関とのおつきあいとかもあるわけで。

問題はここ↓。

単価の高い制作会社(1人月150万円以上)ならば、同じ予算でもできることが1つ左にシフトすると考えるといいだろう。

違うな。単価の高い制作会社は「クオリティが高い」か「生産性が高い」かどちらかであるべきで、クオリティを文面で表現するのは難しいから生産性の話でいうと、単価が倍である制作会社は単価の低い制作会社の倍(数倍)の生産性があるから「同じ予算でもできることが1つ左にシフト」したりはしない(というか、そうあるべきじゃないか?)。

倍の単価ではあるが、アウトプットのスピードも2倍。だからアウトプットに対するコストは変わらない(筈)。

ウチも人月(日)単価で見積りを出すことが結構多いが、それはあくまでも分かりやすさと相場(競合)を意識してのこと。

例えば工数1ヶ月、100万円で契約した仕事を1ヶ月でやろうが2ヶ月でやろうが、はたまた3日でやろうが全然構わん筈である。大切なのはアウトプットやプロセスである。

例えば先日の会話から。

  • この仕事、ここからここまで何日?
  • 13日です。
  • ありえん。3日でやれ!

もちろんこれは極端な例だが、ここから13日を3日に近づけるためのプロセスの分解やノウハウの総動員が始まるわけだ(結果が「10日」であってもそれはそれで受け入れざるを得ないが、1日でも縮まればそれが利益につながるのだ。我々は派遣会社ではない。時給いくらが重要ではなく、アウトプットとインカムのせめぎ合いで食ってるのだ)。

もちろん、アウトプットは変わらずに単価だけが高い会社もあるだろう。ただし、そんな会社は退場させちまえば良い。ウチのほうが安くて良いもの出来て利益も出せるのであれば、仕事ぶんどってしまえば良い。

それでも単価が高いには訳がある

と、まぁ相変わらず吠えてみたわけだが、アウトプットは変わらずとも単価が高いことに意味がある場合もある。アウトプットのスピードもクオリティも変わらん、でも単価は高い。そんな会社には大抵小さな会社と比較して無駄がある。「無駄」とはいっても、それは必要なコストでもあるわけだが。

例えば事務経理をパートのおばちゃんや社長の奥さんがやっている会社と、専属の担当者がいる会社ではコストが違う。会社が大きくて中間管理職が多ければコストは上がる。価格も含めた競争力を保ちたければ会社を小さく保ち、効率を高めるという戦略がそこに生まれる。

ところが...

コストは高いかもしれぬが中間管理職がいて間接部門を抱える会社には一つ大きな武器がある。例えば「担当者が死んだらプロジェクトはどうなるか?」。

どうもならんよ、普通に引き継いでなんとかなりますよ、ってな組織なら当然同じアウトプットでも単価は高い筈だし高くて良いと思う。いわば「保険料」が上乗せされているようなものだ。こういう部分での高い価格設定はあって良いと思う。普通の考えだしね。

フリーランスや零細企業の場合、そうはいくまい!? 担当者どころか社長が死ねばプロジェクトはかなりヤバいだろう。


その上で、受託のWeb屋が考えるべきこと

そういう面での中間コストとか組織を維持するためのコストは価格に反映されて良い。単に地方は安いとか言ってる場合じゃないですぜ、旦那。

かなりgdgd感が出てますな。

これを元に高いとか安いとかというのは、確かに地方格差や、一定の金額とならない業界ということを再確認できましたが、『ふーん』くらいなもので、詐欺とか安すぎとかという声は一切当てにならない。

えーっと、地方がいやなら東京さいげば? それでやっていけるなら。

東京は嫌で程よく地方が良いならば京都へ行きなさい。京都は日本のシリコンバレーになるかもしれんですよ。

てな冗談? はさておき

web制作の価格は需要による

ここがもうなんと言うか間違ってるのよ。学校で習っただろ? 「需要と供給」って。

「地域で異なる」ってな表現もあるが、わかりやすく他にないものを供給できれば全国どこだって仕事はくるぜ!? 東京からだってさ。

だから旭川と検索して10ページ目以降の中小企業のホームページというのは、個人が作ったようなページしかないのです。

だからこのあたりがなんだかgdgdなんだよな。


他社にもできる仕事は価格競争に晒されると思え

うらやましいなぁ〜都会は。こんな単価で受けてみたいよな〜、と言っている時点で負けである。他社にもできる仕事で、且つ当社は「保険料込み」でないのだとしたら、東京に行ったって京都に行ったって食えないだろう。夢にまで見た単価「○百万円」の仕事も受けることはできない。

大阪は十分都会だし、地方とは違うというかもしれぬが(東京にオフィスも人もいるけれども)、仕事はちゃんと来るよ。そこそこの単価でも。

それは需要よりも供給に視点をあわせて、他の会社には出来ない何かを明確にしているからに他ならない。こんな時間だから続きはいずれ書く。

ひとつだけいっておくと、「価格ではない何か」をちゃんと持っているかどうかが大切なのさ。

「はてな」が京都へ戻るのが話題らしい。

で、昨年末当たりの人が辞めたことと関係あるとかないとかいうことを言っている人がちらほら。

結論を先に言えば、非上場企業の経営者が判断したことに他人がとやかく言うこともあるまい。

これは、たとえ事実であっても言うべきではなかったと思う。
・合理的判断をしていない
・従業員の利便性より近藤社長の意志を尊重した
ということを明言してしまっているからだ。

普通、本社移転などの重大な事案は慎重に進められるべきもので、

経営陣で方向性がまとまる?従業員に意見を求める?退職者が多く予想される?再検討
・退職者の穴の損失・補充にかかる手間&コストvs本社移転のメリット・デメリットを勘案
・本社移転orそのままorあるいは最小限度の移転・・・など合理的に判断

指しているのはこちらのエントリー

合理的かどうかをこのエントリーから読み取る能力は僕にはないから何とも言えん。

短期的な見方をすれば、例えば従業員数が ? 割減って売り上げが現状維持だったらその会社は強くなったということだろうし、上場企業なら「収益性が高まった」てなもんで評価もあがることだろう。

長期的に見れば、その減った人材による今後の収益や会社の成長へのマイナスを考慮する必要があるわけだが、それは逆に今後の成長戦略への評価と併せて考えるべき問題でしょう?

失った人材による損失への評価 VS 今後の戦略(それが人材損失の理由であるか否かはたいした問題はなく)への評価

従業員が減ったことには固定費減というプラス面もあるわけだから、コストだけに限って言えば

「人件費の減少 と 地代家賃の安い京都に開発拠点を移すことによる固定費の減少 (広いスペースに移ったようだから単純に額だけを見ることもないだろうが、その場合は固定費減のかわりに広い職場環境を手に入れたことになる)」VS 「人材流出によるマイナス面」

ということになる。収益に直結する「顧客」「インフラ」が人材流出によって失われていないならば、「人材流出のマイナス」VS「移転や移転の理由となった今後の成長戦略」を考えて、後者が上回れば移転は成功というそれだけの話ではないのかな。


一方、バレンタインデー(!)にこの長文をポストしたゼロベースの石橋社長のエントリー。めっちゃ楽しく読ませていただいた。

2004年9月創業以来の入社人数8人、退職人数3人。

会社のことも石橋さんご本人のことも存じ上げないので何とも言えないが、受託ベースの会社であれば優秀な数字じゃないだろうか。ただし逆に辞めなければ良いと言うものでもなく、それを感じているからこそのこの原稿なんだと思う。

同じく、非上場企業の経営者が判断したことに他人がとやかく言うこともあるまい。だが、こっちにはちょっとだけとやかく言ってみる(良い悪いの話ではなく、自分の会社を考える際の参考として)。

例えば石橋が2,000万円の仕事をとってきたら、いったん石橋の売上が2,000万円。それをディレクターに1,800万円で引き継いだら石橋の原価が1,800万円で粗利200万、ディレクターは売上1,800万円。ディレクターがエンジニアとデザイナーに仕事を割り振ったらそれぞれ原価が発生、といった形で、各自が必要な粗利を自分で稼ぐ仕組み。

その価格はどう決めるか? 当事者が決める。交渉です。折り合わなかったら他の人に交渉する。場合によっては社内で折り合いがつかなければ社外へ。って、当たり前ですな。

場合によっては社内で折り合いがつかなければ社外へってあたりは僕もその通りで、いやむしろ僕は「社内で折り合いがついても」「社外の方が顧客が喜ぶ」クオリティが生み出せるなら「社内はいらない」くらいに考えている。

だからウチでは表現やクリエイティブのコンペとかの時は、社内と社外で競わせるなんてことを普通にやる。いや、やっていた(最近はコンペがなく、指名いただくケースがほとんどだから、やらない)。

ただ、ここだけ見るとそれって会社か? とも思う。

もちろんそのあたりもちゃんと書いてある。

ゼロベースという会社としては、そういうフリーランサーが苦手な営業、経理などの「経営サービス」を提供し、「好きで得意な仕事だけ」をやってもらいたい。忙しさも自分でコントロールしながら。

なるほどその部分は確かにそうで、ともすればフリーランサーが苦手な『「営業、経理などの「経営サービス」』を提供するってのには意味があるだろう。
ただ、『「営業、経理などの「経営サービス」』はアウトソースすることもできるよね。

長期的に、ゼロベースという会社本体の存在意義は「ブランドマネジメント」。サービスの品質を担保し、ブランディングし、マーケティングする。

なるほどブランドはアウトソースできないから(もちろん理屈やビジュアルをアウトソースすることはできるが)、経営インフラ+ブランド、ブランドがあるからこそとってこれる仕事に関われるという魅力があって(もちろん社長個人の魅力も大きい)、それこそがゼロベースで働く意味だよ、と書いてあるように見えた。

ただ、この場合は「ゼロベース」というブランドと、フリーランサーが獲得したい「自分ブランド」への思いが衝突することがあるだろう。だから、少なくとも現段階においては石橋社長を超えるフリーランサーがそこで働くことはないんじゃないかと思う(これはどこの会社でも同じだろうが)。

ゼロベースに数少ない「ふつうの感覚」を持つ社員の意見:「まったく育てないから、勝手に育て」「べつに隠さないけど、教えないから、勝手に盗め」とか人材募集ページに書いた方がよい。びっくりするほど「育てる」機能を持っていない会社。

ははは、楽しいね。僕もかつてはそう思ってそうやっていた(この場合「やっていなかった」というのが正解か)。


「育てないけど勝手に育つ」ためには何が必要か?

さて、長い前振りが終わって本題。自社の話。

僕は「まったく育てないから、勝手に育て」「べつに隠さないけど、教えないから、勝手に盗め」を最近やめた。

人材については、これまでは正直お恥ずかしい話だがよく辞めていた。ところが気がつくと最近辞めていない。受託系ビジネスの場合は人材が流出することは生産力を即下げるから、おかげで今期は非常に良い数字が出ている。

求人費もかからないし (ブログ経由で一名来たけど広告費は払ってないし何人も面接していない)、人が変わることによるインフラ (ハード/ソフト) コストもかからないから当然と言えば当然だ。

じゃぁ、ここ最近は懇切丁寧に教えるようになったからこういう結果となったのか? いやそれは違うと思う (だって相変わらず何も教えてもらっていないとか中の人に言われるかもしれないしこう書いておくよ)。

これまでは「勝手に育つ人材」であることを求めたり、結果としてそういう目線でやってきたのだろう。勝手に育つ人材は、ウチに来る段階で既に何らかのモノを持っていて、放っておいても育つと。ところが、そんな人材が簡単に来るわけもない。

結果として現状の当社を構成しているのは、「勉強熱心」で「非常に真面目」な比較的若いスタッフが中心だ。フリーランサー指向とは多分違う。そして、彼らが何だか勝手に育っている。

もちろん育っているのは彼ら/彼女ら自身の努力のたまものであって、こちらはたいしたことはやっていない。ただ、少しだけ意識的に進めたことがある。

何をやったか? 「仕事をモジュール化した」。

仕事のモジュール化はワークフローの改善につながり情報発信力にもつながり、おまけにパッケージが出来た(そして、そこそこに売れている)。

基本的にやってことは以下の3点。

  • 徹底的に仕事のプロセスを分解すること
  • 分解されたひとつの仕事に対して再利用できるモジュールをつくること
  • モジュール化出来ない部分が一定比率より多い仕事 (あるいは過去のモジュールが活用出来ない仕事) は受けないこと

そして、その上で、

  • モジュールを組み合わせた「パターン」を作り、共有する (ワークフロー)
  • 役に立ちそうで汎用的なモジュールは公開したりアウトプットする (ブログ、自社サイト、セミナー等)

パッケージ/パターン化するというのは、特定の人材に依存しない状況をつくるということでもある。つまり一人が辞めてもツクルモノのクオリティやプロセス、コストに変化は殆どないという状況をつくること。

そして皮肉なことに、そうすることで人が辞めにくくなった(ただし相関関係はわからない。ただ単に現状の彼らが忍耐強いだけかもしれんし)。

出来上がったパッケージはこれ。これを最も使っているのは誰あろう当社のスタッフである。そしてこのパッケージを作っているのも当社のスタッフである(多くの部分は僕が書いているにしても、モジュールの設計や現場の要望を製品に反映させているのはスタッフだ)。プラットフォームをベースにモノを作っていくスキルがたまり、仕事を通じてモジュールは充実し、パッケージが仕事を生み、収益を生んでいく。

タイトルの話に戻れば、現状の当社にとっては人が辞めるのはあまり良いこととはいえないが、ミスマッチでも無理に残ることが良いことである筈もない。ただし、入れ替わっても大きな問題は無い状況が出来つつあり、そうすることで結果人が辞めなくなりつつある。現状はそういうこと。


追記 :

ついでにもうひとつ。

  • Movable Typeはこうしたしくみをつくるのに非常に向いたツールである。

(追記)

あるって!
カスタムフィールドでアップロードしたアイテムを表示するには
http://www.Movable Type.jp/documentation/professional/custom-fields.html#item_view


これはいい、と思ってテンプレートを触り始めたら、アップされたデータをほとんど操作できないことがわかりました。「画像」なんかはそのまま画像として表示したいんですが、テキストリンクしか出せません。この不満を解消するプラグインも早速出てるんですが、結局のところJavascriptで操作しています。MTタグをもう少し追加してもらうだけでいいんですけどね。

ってエントリー書いてる暇あったらプラグイン書いた方が早いやん...


<MTIfNonEmpty tag="entrydata">
<p><MTentrydata HTMLImageElement="1"></p>
</MTIfNonEmpty>


<p><img src="パス" width="幅" height="高さ" alt="画像の名前" /></p>

HTMLImageElementってのは小文字で書くとhtmlimageelementって、何かPHPの関数名みたいでしょ(違っ!)。PHP版は...誰か作ってください...てか誰かすぐに作ると思ってたんだけどなぁ、このネタ。

カスタムフィールドの値にプラグインとかからアクセスする(保存する)のってどうすんの? ってな話題、とか、ベールに包まれた? MT4.1のカスタムフィールドのお話。

保存は CustomFields::Util の save_meta を, 取得は get_meta を呼ぶと良い。以下は保存の例。


use MT::Entry;
use CustomFields::Util qw( save_meta ); 

my $entry = MT::Entry->new;
$entry->blog_id($blog->id);
$entry->status(MT::Entry::RELEASE());
$entry->author_id($author->id);
$entry->title('My title');
$entry->text('Some text');
$entry->save
    or die $entry->errstr;

my $meta; 
$meta->{'field_basename1'} = 'foo'; 
$meta->{'field_basename2'} = 'bar'; 
&save_meta($entry, $meta);

テキスト関係のデータならこれで保存できる...が、画像とかアイテムの場合はどうすんの? ということなんですが、以下の例を見てください。そう、あのエディタにアイテムを貼付けた時のformタグと同じなんですねぇ。

# どうも、この仕様好きになれんですが...


my $url = '%r/images/photo.jpg';
my $asset = MT::Asset->load( { blog_id => $blog->id,
                               url => $url,
                               class => '*' } );
                               
unless ( defined $asset ) {
    # Create new asset & save...
}
my $site_url = $blog->site_url;
if ( $site_url =~ /(.*)¥/$/ ) {
    $site_url = $1;
}
$url =~ s/%r/$site_url/;
my $label = MT->translate( 'View' );
my $tag = '<form mt:asset-id="' . $asset->id . '" class="mt-enclosure mt-enclosure-' . $asset->class .
          '" style="display: inline;"><a href="' . $url . '">' . $label . '</a></form>';

$meta-&gt;{'field_basename3'} = $tag;

&save_meta($entry, $meta);

ObjectAssetにエントリーとアセットのそれぞれのIDをキーにしてダイレクトに保存しても良いのだけど、管理画面から再度エントリーとか保存すると関連付けデータ(ObjectAsset )が消えてしまうので、素直にやるならformタグつけるということです。

ところで、

  • カテゴリーにタイプが「画像」とかのカスタムフィールド登録して、あるカテゴリーで「画像を選択」→「保存」
  • 「一覧」メニュー→「アイテム」→(カテゴリーから選択した)「画像」をクリック

すると、僕の手元の環境だと以下のようなエラーを吐く(フィードバック済み)


Cannot find column 'title' for class 'MT::Category' at lib/MT/App/CMS.pm line 6545

この部分をプラグインでオーバーライトするのは...無理かなぁ(できるのか?)

MTOSの場合はlib/MT/App/CMS.pmに手を入れちゃえば良いですが、MTOSにはカスタムフィールドが無いので問題にはならないでしょうけど。

いずれにしてもアセットとオブジェクトの関連付けについてはエントリーだけじゃなくてカテゴリーとかブログとかについても保存出来るとベターじゃないですかね。

* ついでの余談且つ、今さらな話題ですが、オブジェクトの名前が「title」だったり「label」だったり「name」だったりするんですよね。もし統一されてたらすごく気持ちいいなぁ...とか(慣れたからいいですけど...今さらですしねぇ)。


diff ./mtos/lib/MTOS/App/CMS_org.pm ./MTOS/lib/MT/App/CMS.pm
6543,6561c6543,6579
<                 my $entry_class = $app->model($place->object_ds);
<                 my $entry = $entry_class->load($place->object_id);
<                 my %entry_data = (
<                     id    => $place->object_id,
<                     class => $entry->class_type,
<                     entry => $entry,
<                     title => $entry->title,
<                 );
<                 if (my $ts = $entry->authored_on) {
<                     $entry_data{authored_on_ts} = $ts;
<                     $entry_data{authored_on_formatted} =
<                       format_ts( LISTING_DATETIME_FORMAT, $ts, undef,
<                         $app->user ? $app->user->preferred_language : undef );
<                 }
<                 if (my $ts = $entry->created_on) {
<                     $entry_data{created_on_ts} = $ts;
<                     $entry_data{created_on_formatted} =
<                       format_ts( LISTING_DATETIME_FORMAT, $ts, undef,
<                         $app->user ? $app->user->preferred_language : undef );
---
>                 my $obj_class = $app->model($place->object_ds);
>                 if ($place->object_ds eq 'entry') {
>                     my $entry = $obj_class->load($place->object_id);
>                     my %entry_data = (
>                         id    => $place->object_id,
>                         class => $entry->class_type,
>                         entry => $entry,
>                         title => $entry->title,
>                     );
>                     if (my $ts = $entry->authored_on) {
>                         $entry_data{authored_on_ts} = $ts;
>                         $entry_data{authored_on_formatted} =
>                           format_ts( LISTING_DATETIME_FORMAT, $ts, undef,
>                             $app->user ? $app->user->preferred_language : undef );
>                     }
>                     if (my $ts = $entry->created_on) {
>                         $entry_data{created_on_ts} = $ts;
>                         $entry_data{created_on_formatted} =
>                           format_ts( LISTING_DATETIME_FORMAT, $ts, undef,
>                             $app->user ? $app->user->preferred_language : undef );
>                     }
>                     push @appears_in, ¥%entry_data;
>                 } elsif ($place->object_ds eq 'category') {
>                     my $category = $obj_class->load($place->object_id);
>                     my %category_data = (
>                         id    => $place->object_id,
>                         class => $category->class_type,
>                         category => $category,
>                         title => $category->label,
>                     );
>                     if (my $ts = $category->created_on) {
>                         $category_data{created_on_ts} = $ts;
>                         $category_data{created_on_formatted} =
>                           format_ts( LISTING_DATETIME_FORMAT, $ts, undef,
>                             $app->user ? $app->user->preferred_language : undef );
>                     }
>                     push @appears_in, ¥%category_data;
6563d6580
<                 push @appears_in, ¥%entry_data;

ついでにCSSのどこかに以下加えておくと、


.icon-entry { background-image: url('../images/nav_icons/color/entry.gif'); padding-left:16px; background-repeat:no-repeat;background-position:3px;}
.icon-category { background-image: url('../images/nav_icons/color/categories.gif'); padding-left:16px; background-repeat:no-repeat;background-position:left;}

こんな感じで、カテゴリがアイコン付きで表示されてくれたりして素敵?

アセットの利用状況

えーっと、面白いもん作ってしまった(<<自分で言うか!?)

このあいだエントリー編集画面でMTEntries等のタグを使えるようにするCMSEntryContextというのを思いつきで作ったのだけど、idが振られていないとエラーになるとかエントリーはいけるけどカテゴリーは駄目とか、「確認」>>「ブログ記事を再編集」だと効かないとかあったので、そのあたり改良して「Entry」を外して「CMSContext」という名前にしました。

何が面白いって、ちょっとムービーでも見てくださいな。

でね、まぁこういったプラグインは確かに良く? あるわけなんですけど、CMSContext.pl は別として、これらの実装には、実は...

Perlのコード1行も書いてないんですよ。

すべてMTタグ(「タグクラウド入力支援」の方はMTタグ+JavaScript/CSS, カテゴリのショートカットの方はMTタグのみ)

JavaScript使っといてノンプログラミングじゃねーだろ! ってのは置いておいて、とにかくテンプレートだけであれこれ出来るんですね。

これまでPerlでプラグイン書くってのが一般的だったんだけど、MT4.1でMTMLがプログラミングチックに書けるようになったわけで、MTタグであれこれやってきたテンプレートいじりの好きなデザイナーさんとかがこれからは面白いの作ってくれるんじゃないかなぁ〜と思うのです。

まぁ、Perlで書かれていない段階でそれを「プラグイン」と呼ぶかどうかわからんのですけどね。

カテゴリの編集画面の右側に「ショートカット」としてカテゴリに属しているエントリーを表示するには、

  1. プラグインの tmpl/フォルダに edit_category.tmplをコピー
  2. フッタモジュールの直前に以下のブロックを追加

<mt:setvarblock name="related_content" append="1">
<mt:cmscontext>
<mt:setvarblock name="category"><mt:categorylabel></mt:setvarblock>
<mtapp:widget
        id="useful-links"
        label="<__trans phrase="Useful links">">
        <ul>
        <mt:entries lastn="10" category="$category">
            <li class="current-filter"><a href="<mt:var name="script_url">?__mode=view&amp;_type=entry&amp;id=<mt:entryid>&amp;blog_id=<mt:blogid>"><mt:entrytitle></a></li>
        </mt:entries>
        </ul>
    </mtapp:widget>
</mt:cmscontext>
</mt:setvarblock>

以上。

気になっているところがあるにはあって、編集画面(__mode=view)が呼び出される段階で、一回エントリーとかカテゴリーはロードされてるわけだから、も一回ロードしなくても取得出来ないのかなぁ...ってなところが気になっていると言えば気になっている(何か文章無茶苦茶やな。あるにはあってとか気になっていると言えば気になってる...とか)。ちょっとソース追いかけてみたけど今日はわからんかった、っていうか仕事たまってて時間がない!

いや、しかしMTで作るの楽!

皆さんテスト用データってどうしてますか?

僕はもっぱらこのブログのエクスポートデータを利用してましたが、やっぱり客先では恥ずかしいので...とはいえある程度のコンテンツが無いとテストにもならんじゃないですか。

ということで、「Wikipedia」の特定の一覧ページからソースを取得してテスト用データを作成するスクリプトを書いて取得生成したテスト用データを置いておきます。

(追記)と思ったんですが、GFDLのライセンス的なことが気になるしスプログ作られるのも嫌だし一旦削除します。

手順としては、

ターゲットとなるページを決めて(今回は「日本の法律一覧」ページをターゲットとしました。何故なら「一覧」ページを取得するのが簡単でそこそこ量があって都合が良かったから)、URLを抽出して LWP::UserAgent; でもってソースを取得、パラグラフを先頭から3つ、各text, text_more, keywordsに放り込んで且つexcerptには元ページのURL、ターゲットページの見出しを読んでプライマリカテゴリ, カテゴリを抽出(同じタグも付けて)、で、ごにょごにょして...

今気づいたけど、日付(authored_on)を適当にずらしておけば日付アーカイブのテストにも使えたよなぁ。まぁ次回やるとするか。

Wikipediaがソースだから「クリエイティブ・コモンズ」 GFDLです。「スプログ」には使うなよ!

とりあえず400程度のエントリーをテスト用に生成できます。

Facebook

Twitter

このアーカイブについて

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

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

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

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

Powered by Movable Type 6.2.6