カスタムフィールドあれこれ。
公開日 : 2008-02-11 16:47:13
カスタムフィールドの値にプラグインとかからアクセスする(保存する)のってどうすんの? ってな話題、とか、ベールに包まれた? 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->{'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;}
こんな感じで、カテゴリがアイコン付きで表示されてくれたりして素敵?