home > Movable Type > Movable Type のブログ記事の...
Movable Type のブログ記事の出力ファイル名を変更する管理画面のカスタマイズ
- 2008年9月22日 05:53
- Movable Type

Movable Type のブログ記事の出力ファイル名は、デフォルトのままだと、タイトルから判断してシステムが自動的に作成します。
基本的には、タイトルに含まれる英数字を拾い出し、スペースはアンダースコア「 _ 」、すべてが日本語だったら「 post-1 」のようになります。
このシステムが自動的に作成するファイル名が結構イケてなくて、異様に長かったりアンダースコアやらハイフンやらがバンバン入っていたりすることがあります。また、異様に長いファイル名があったと思ったら「 post-1 」というファイル名があったりして、サイト内での統一が全く取れていないことに気付き、悲しくなったりもします。
Movable Type の知識がある程度あれば、最初からアーカイブマッピングを設定し、ブログ記事の ID をファイル名にしたり、投稿日時をファイル名にしたりして、統一することができますが、僕のように「とりあえず始めてみた」的な人は、こういった状態に陥ることは少なくないのではないでしょうか。
だからと言って、途中でアーカイブマッピングを変更するわけにもいかないし、毎回手動で変更するのも面倒なので、目をつむってしまうことも少なくないかもしれません。
そこで、ブログ記事の編集画面に、「出力ファイル名を設定して保存」というボタンを作るカスタマイズをしてみました。
実装する機能
今回のカスタマイズで追加する
というボタンには、次のような機能を実装します。
- 出力ファイル名のロックを解除する。
- 出力ファイル名を「日-時分秒」のフォーマットで書き換える。Movable Type 備忘録さんの URL がそれっぽかったのでマネしました。
(例) 9月22日 6 時50分30 秒の場合:22-065030 - 書換え後にブログ記事を保存する。
- ただし、既に出力ファイル名がこのフォーマットになっている場合は、確認メッセージを表示し、書き換えて保存するか、書き換えずにそのまま保存するか分岐する。
カスタマイズ方法
管理画面のカスタマイズについては、Movable Type プロフェッショナル・スタイル MT4.1対応の Track B の「 5 ユーザー指向の管理画面をつくる」がとても参考になります。
カスタマイズするファイルの準備
今回カスタマイズするのは、ブログ記事やウェブページの編集画面用のテンプレートファイル「 edit_entry.tmpl 」です。このファイルは以下の場所にあります。
- mt
- tmpl
- cms
- edit_entry.tmpl
- cms
- tmpl
このファイルを直接カスタマイズせずに、ローカルにコピーして同名で保存したファイルをカスタマイズします。
カスタマイズ内容
さっそくカスタマイズしてみます。
まずは「出力するファイル名を設定して保存」ボタンを追加するために、「 edit_entry.tmpl 」の 60 行目の後に、次の button 要素を挿入します。
[ 60 行目]
><__trans phrase="Save"></button>
[挿入するソース]
<mt:if name="object_type" ne="page">
<button
mt:mode="save_entry"
name="basenameStamp_entry_save"
type="submit"
title="出力ファイル名に「日時分秒」を設定して保存"
class="primary-button"
onclick=" basenameStamp ()"
>出力ファイル名を設定して<__trans phrase="Save"></button>
</mt:if>
このボタンには、通常の「保存」と同様の機能を持たせたいので、54 ~ 60 行目の「保存」ボタンのソースをコピーして、少しだけ変更しています。
このボタンは、その性質上、ウェブページには必要ないので、if タグで全体を囲ってウェブページ以外にのみ反映されるようにしています。
<mt:if name="object_type" ne="page">
.....
</mt:if>
onclick で、クリックされたときに basenameStamp という JavaScript の関数を呼び出します。この関数が、今回のカスタマイズの肝です。
onclick=" basenameStamp ()"
次に、button 要素挿入後の 911 行目の後に、次のソースを挿入して、basenameStamp という JavaScript の関数を定義します。
[挿入後の 911 行目]
</script>
[挿入するソース]
<script type="text/javascript">
function basenameStamp () {
var defaultValue = document.entry_form.basename.value;
var defaultValueCheck = defaultValue.match(/\d{2}-\d{6}/);
function stamp () {
toggleFile();
function digits(num) {
if(num < 10){num = '0' + num;}
return num;
}
var now = new Date();
var dateTime = '' + digits(now.getDate()) + '-' + digits(now.getHours()) + digits(now.getMinutes()) + digits(now.getSeconds());
document.entry_form.basename.value = dateTime;
}
if (defaultValueCheck) {
var warning = confirm ("出力ファイル名は既に設定されている可能性があります。\n\n現在の出力ファイル名 : " + defaultValue + "\n\n変更して保存しますか?");
if (warning) { stamp (); }
} else {
stamp ();
}
}
</script>
関数内を上から順に見ていくと、まず、「出力ファイル名」を設定するテキストエリアの値を取得し、変数 defaultValue に代入します。
var defaultValue = document.entry_form.basename.value;
その変数 defaultValue の値を、設定するフォーマットになっているか正規表現でチェックし、結果を変数 defaultValueCheck に代入します。
var defaultValueCheck = defaultValue.match(/\d{2}-\d{6}/);
次に、出力ファイル名を書き換える関数 stamp を定義します。toggleFile(); は出力ファイルを変更できるようにするロックの解除、関数 digits で 10 未満の数字の頭に 0 を付けて 2 桁に、それ以降で出力ファイル名のテキストエリアの内容を、現在時刻を取得して先ほどのフォーマットにして書き換えます。
function stamp () {
toggleFile();
function digits(num) {
if(num < 10){num = '0' + num;}
return num;
}
var now = new Date();
var dateTime = '' + digits(now.getDate()) + '-' + digits(now.getHours()) + digits(now.getMinutes()) + digits(now.getSeconds());
document.entry_form.basename.value = dateTime;
}
最後に実際の処理を設定します。
if (defaultValueCheck) {
var warning = confirm ("出力ファイル名は既に設定されている可能性があります。\n\n現在の出力ファイル名 : " + defaultValue + "\n\n変更して保存しますか?");
if (warning) { stamp (); }
} else {
stamp ();
}
}
先ほど正規表現でチェックした値がマッチした場合は既に出力ファイル名を変更している可能性が高いので確認メッセージを表示します。「OK」をクリックすると出力ファイル名を書き換えて保存し、「キャンセル」を押すと書き換えずにそのまま保存します。これは誤ってファイル名を書き換えてしまわないようにする保険的な機能です。
正規表現でチェックした値がマッチしなかった場合は、出力ファイル名を書き換えて保存します。
カスタマイズしたファイルをアップロード
以上の内容に書き換えたファイルを文字コード UTF-8 で保存し、次のディレクトリにアップロードします。ファイル名は「 edit_entry.tmpl 」です。
- mt
- alt-tmpl
最初に「 edit_entry.tmpl 」があったディレクトリとは別ですのでご注意ください。
動作確認
ブログ記事の編集(作成)画面にアクセスしてみると、ボタンが表示されています。

ウェブページの編集(作成)画面には表示されていません。

ボタンをクリックして、正常に動作することが確認できました。
![]()
以上です。カスタマイズしたファイルを置いておきますので、解凍してご自由にお使いください。
※ご利用は自己責任でお願いします。
- 【2008-10-01 追記】
この続きのカスタマイズで、「公開日」も同時に変更するカスタマイズを掲載しました。
TrackBack [0]
- TrackBack URL
- Link to this Entry



MTの出力ファイル名に悩んでいて、この記事にたどり着きました。
もうドンピシャでした。本当にありがとうございます。
ただ、こうなると欲が出てくるもので・・・
もし可能であればご教授願いたいのですが、
「公開日」を出力ファイル名に自動設定させることはできるでしょうか?
どこをいじれば良いのか、私にはサッパリでして。。
私の場合は記事をある程度まとめて投稿して、公開日指定で順次公開していくスタイルを取っているので、できれば出力ファイル名は公開日時と整合性を取りたいと思っています。
そしてできれば
2009年9月22日 6 時50分30 秒の場合:20090922-065030
というフォーマットにしたいのです・・・。
もし気が向いたら、で結構ですので、
ご返答いただけますととても嬉しいです。
mon さん、コメントありがとうございます。
> 「公開日」を出力ファイル名に自動設定させることはできるでしょうか?
できると思います。コメントいただいた記事の続編的な記事が次のページになるのですが、
----------
「出力ファイル名」と「公開日」を同時に変更する管理画面のカスタマイズ
http://www.tinybeans.net/blog/2008/10/01-063229.html
----------
こちらでは、現在時刻を取得して、「公開日」を上書きするという仕組みでやっているのですが、それを逆にすれば良いと思います。
つまり、公開日の「年月日」と「時間」のフィールドから値を取得して、整形して、ファイル名フィールドに挿入すればOKだと思います。
いかがでしょうか?
ご返答ありがとうございます!
不勉強なもので、ものすごく知識が乏しいのですが><、
いただいたご返答から推察するに、例えば以下のような形にすれば良いということでしょうか?(全く検討外れでしたらすみません・・・涙)
-------------------------------
var now = new Date();
var DateTime = ''+ document.entry_form.authored_on_date.getFullYear() + '-' + digits(document.entry_form.authored_on_date.getMonth() + 1) + '-' + digits(document.entry_form.authored_on_date.getDate()) + '-' + digits(now.getHours()) + digits(now.getMinutes()) + digits(now.getSeconds());
document.entry_form.basename.value = DateTime;
-------------------------------
これを「edit_entry.zip」のファイルの該当部分と差し替えれば良いのだろうか、と予測しているのですが・・・。
すみません、間違えました;;
以下に訂正します。
-------------------------------
var now = new Date();
var DateTime = ''+ document.entry_form.authored_on_date.getFullYear() + '-' + digits(document.entry_form.authored_on_date.getMonth() + 1) + '-' + digits(document.entry_form.authored_on_date.getDate()) + '-' + digits(document.entry_form.authored_on_date.getHours()) + digits(document.entry_form.authored_on_date.getMinutes()) + digits(document.entry_form.authored_on_date.getSeconds());
document.entry_form.basename.value = DateTime;
-------------------------------
mon さん、中途半端な回答しちゃってごめんなさい。該当部分を以下のようにしたら良いと思います。テストしていないので、ダメだったらまたコメントください。
var entryDate = document.entry_form.authored_on_date.value;
var entryTime = document.entry_form.authored_on_time.value;
var entryDateTime = '' + entryDate.replace(/-/g,'') + '-' + entryTime.replace(/:/g,'');
document.entry_form.basename.value = entryDateTime;
ちなみに、現在時刻は関係なくなるので、
var now = new Date();
は不要となります。
出来ました~!!!
大感激でした。本当にありがとうございます!!!
モヤモヤしていたものが取れて、とてもスッキリです。
お手数お掛けして申し訳ありませんでした。
私ももう少し勉強します!
今後も色々と参考にさせてください!!!
おー良かったですね!
お役に立てて良かったです。
はじめまして
私もとりあえず始めた一人です。
約一年の時を経て、今頃カスタマイズの勉強にとりかかりました;
>途中でアーカイブマッピングを変更するわけにもいかないし
こちらで質問なのですが、
途中で変更してしまうと過去のブログURLも変わってしまうのでしょうか・・?
よろしければ変えたあとの問題点をお教えください。
お願いします!
ぺこりんさん、コメントありがとうございます。
>途中でアーカイブマッピングを変更するわけにもいかないし こちらで質問なのですが、途中で変更してしまうと過去のブログURLも変わってしまうのでしょうか・・?
変わってしまうというか、多分同じ記事が過去の記事とマッピングを変えた後の記事とで2つできてしまいます。
http://www.tinybeans.net/blog/images/basename_before_after.png
2つできるならリンク切れもなく良いような気がしますが、結局そのブログ内のブログ記事に関するURL部分が全て変更されるので、以前のブログ記事URLにアクセスしたユーザーは、旧ブログ記事URL内を回り(しかも変更後の記事へのリンクはありませんし)、変更後の記事にアクセスしてきた人は、変更後のURL内を回るという、2つのレイヤーが出来てしまうのだと思います。
違ってたらごめんなさい!
tinybeansさん
お早いご回答をいただきありがとうございます!助かります^^。
なるほどー・・
アーカイブマッピング変更した後に過去のブログ記事だけ
その新URLをサーバーから削除しても、
再構築をしたらまた生成されちゃうんですかねえ?
(単なるブログなのでそこまでこだわってないですが・・
ちょっと悔しい-3-
過去のアーカイブマッピングを削除したあとにサーバーから削除すれば、再びそのアーカイブマッピングのファイルが書き出されることは無いと思いますよ。
結局問題は、そのページへのリンク切れが生じる可能性があるってところですね。はてブされてた場合とかですね。