TypePadの最近のブログ記事

TypePadで5000エントリぐらいあるブログを、やっとの思いで、MovableType4に移し終えました。

Permalinkを維持するところがかなり苦労した。

このブログもTypePadベースのココログで動いているんだけど、やっぱり3000エントリぐらいあるんで、移すとなると同じ手段使うかもしれない。

今回の作業でできたもの:

M.C.P.C.: MovableType4で一気にカテゴリを追加する
M.C.P.C.: TypePadからMovableTypeに移行するときPerlスクリプトを使い元のPermalinkになるようBasenameを設定する

移設作業準備中は、移設先はrobots.txtをセットすると思うんだけれども、作業後は外すなり設定変えるのを忘れないでね。

TypePadからエクスポートして、MovableTypeにインポートすると、Permalinkのファイル名(Basenameに由来)が書き換わっちゃうという問題は2004年の時点から言われていた問題で(まてMovableTypeってそんなに古いのかよ)、これを解決するために、Perlでスクリプトを書いたというお話。

シチュエーションとしては、TypePadの方のblogはまだURLが生きていて、これからLinuxサーバで稼働しているMovableTypeに移設しようとしているという想定。だから、DNSの切り替えはまだしていないってことですね。

~~~

1. TypePadからエクスポートして、MovableTypeにインポート

まず、MovableTypeにエントリをすべて移設します。やり方は、TypePadの方でエクスポートを選び、ファイルをダウンロードしたあと、MovableTypeの方で、インポートを選び、ダウンロードしたファイルをアップロードします。あちこちにやり方があるので割愛。

この時点で、MovableTypeの方のエントリのファイル名は、元のTypePadの方のエントリと違っています。

2. TypePadでエントリタイトル-Permalinkの対応表を書き出し

次に、TypePadの方で、次のようなテンプレートを作ります。

Filename: title-permalink.yaml

---
<MTEntries lastn="9999"><$MTEntryTitle$>: <$MTEntryPermalink$>
</MTEntries>

これは、エントリタイトルとPermalinkの対応表となります。

これをTypePadで再構築すると、

---
ブログエントリ1: http://example.com/2008/01/post_1.html
ブログエントリ2: http://example.com/2008/01/post_1.html
…
ブログエントリ99: http://example.com/2008/01/post_99.html

とかなります。これには、http://example.com/title-permalink.yaml でアクセスできるとしよう。

3. MovableTypeのアーカイブテンプレートのPermalink命名規則を設定し直す

今度は、MovableTypeの、インポートしたblogの「デザイン-テンプレート」の中の、「アーカイブテンプレート」の「ブログ記事」を選択。

下の方の「テンプレートの設定」を開き、 「アーカイブマッピング」のところがデフォルトだと「yyyy/mm/entry-basename.html」となっているので、「yyyy/mm/entry_basename.html」を選択し直します。これをしておかないと、TypePadのアンダースコアを含むpermakinkがハイフンになってしまうので注意。あと、ディレクトリのほりかたを特殊にしていた場合は、選択肢の中にないかもしれないので、http://www.movabletype.jp/documentation/appendices/archive-file-path-specifiers.html を参考にしてカスタムで入れる必要があるかも。

Mt4namingrule▲この設定にしておかないと、post_1.htmlが永遠にpost-1.htmlで書き出されることに……

4. MovableTypeが稼働しているサーバで書換スクリプトを走らせる

ここまでやったら、MovableType4が設置されているサーバで、こんなPerlスクリプトを走らせる。
このスクリプトはこのままではなくて、各自の環境に合わせて、blog_idの箇所と、getの箇所を変えなきゃダメ。また、いきなり書き換えちゃうので、バックアップをとるとか、テストとして、$entry->saveの行頭に#をつけてコメントアウトしておくとか、しておくといいかも。

スクリプトの内容は、MovableTypeの操作をするライブラリ(MovableType付属)を使い、Permalinkの不統一の元となっている勝手に生成されたBasenameを、TypePad側で書き出したyamlファイルを参照して、TypePadのものに書き換えています。

Filename: mt_changebasename.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use lib '/path/to/mt/lib';
use Encode;
use LWP::Simple;
use MT;
use utf8;
use YAML;
 
my $data = get('http://example.com/title-permalink.yaml');
my $list = YAML::Load($data);
#print Dump($list);
#exit;
 
my $mt = MT->new( Config => '/path/to/mt/mt-config.cgi' );
my @entries = MT::Entry->load({
  blog_id => 99,
  status  => 2,
});
 
foreach my $entry (@entries) { # $entryには、MT::Entryオブジェクト
  my $title      = $entry->title;
  my $permalink  = $list->{decode_utf8($title)};
  (my $basename  = $permalink) =~ s{^.+/(.+)\..+}{$1};
    # PermalinkからBasenameへ
  my $o_basename = $entry->basename; # 書き換え前のBasename
  $entry->basename($basename); # MT::Entry objのBasename書換
  $entry->save or die $entry->errstr; # MT::Entry obj書込
  print "$title $o_basename->$basename\n";
}
 
exit;
 
__END__

これが終わったら、MovableTypeのblogを再構築する。

お疲れ様でした。

僕はこれをもう46回やらなくてはいけない。うげげ。

参考にした: MT::ObjectこそがMTの本質であると勝手に思っている。 - Junnama Online

おんなじじゃないんですね、TypePadとMovableTypeのMTタグ。

Movable Type と TypePad のテンプレートタグの比較 [watcher.moe-nifty.com]

TypePadでMTBlogDirnameをいっぱい使っていたのではまった。結構悩みどころです。

TypePad系(TypePad.jp、ココログプロなど)でバナー広告をローテーションさせたいとき。

インデックステンプレート: ad.inc

 
<div id="ad"
  >
  <!--#if expr="$DATE_GMT = /[0] GMT$/" -->
  <div id="ad_0">
    広告1
  </div>
  <!--#elif expr="$DATE_GMT = /[1] GMT$/" -->
  <div id="ad_1">
    広告2
  </div>
  <!--#elif expr="$DATE_GMT = /[2] GMT$/" -->
  <div id="ad_2">
    広告3
  </div>
  <!--#elif expr="$DATE_GMT = /[3] GMT$/" -->
  <div id="ad_3">
    広告4
  </div>
  <!--#elif expr="$DATE_GMT = /[4] GMT$/" -->
  <div id="ad_4">
    広告5
  </div>
  <!--#elif expr="$DATE_GMT = /[5] GMT$/" -->
  <div id="ad_5">
    広告6
  </div>
  <!--#elif expr="$DATE_GMT = /[6] GMT$/" -->
  <div id="ad_6">
    広告7
  </div>
  <!--#elif expr="$DATE_GMT = /[7] GMT$/" -->
  <div id="ad_7">
    広告8
  </div>
  <!--#elif expr="$DATE_GMT = /[8] GMT$/" -->
  <div id="ad_8">
    広告9
  </div>
  <!--#elif expr="$DATE_GMT = /[9] GMT$/" -->
  <div id="ad_9">
    広告10
  </div>
  <!--#else -->
  <!--#endif -->
</div>

上記のインデックステンプレートを用意しておき、広告を差し込みたいインデックステンプレートにて、

<!--#include virtual="/blog/ad.inc"-->

のように書きます。

動作原理は、SSIで、現在の時刻をとって、秒の1桁目が0~9で別のHTMLを返します(だから厳密に言うとランダムではない)。

実装例は今のこのブログの右サイドバーの広告。

これやると何がいいか、っていうと、ページソースをのぞいても1つの広告のソースだけしか見られないことです。結構気にしますよね。

アクセスした時刻によって表示するものを変えたいとかいうとき、TypePad.jpや、ココログプロでしたら、SSIで現在時刻から条件判断で分岐するっていうことがよくやられます。

そんで、そのときに利用する環境変数DATE_LOCALが、TypePad.jpはPDT、cocolog-nifty.comはJSTで出てくることに気づきました。さらに、SSIで<!--#include virtual="hoge.inc"-->で別ファイル差込みをして、差込みファイルの中にDATE_LOCALを使う場合、<!--#config timefmt="%S"-->とか効かない。

というわけで、TypePad.jpとココログプロの両方で動く時間判別SSIを作る場合、環境変数DATE_LOCALを使わず、環境変数DATE_GMTを使うといいということがわかりました。

<!--#echo var="DATE_LOCAL"-->
<!--#echo var="DATE_GMT"-->

実行結果:(毎回変わります)

Tuesday, 19-Mar-2024 18:28:28 JST
Tuesday, 19-Mar-2024 09:28:28 GMT

TypePad使いの方は、覚えておくといいかもしれません。

Window IE6は、XML宣言があると、後方互換モードになって、標準準拠モードの時と挙動が変わって、他のブラウザとの表示を合わせるのが大変です。

これの対処方法としては、IE6のために、XML宣言をとってしまう方法がとられていますが、この状態でAnother HTML-lintなんかにかけると、いちいちXML宣言付けろってうるさいです。

なので、ブラウザにあわせてXML宣言をいれたり隠したりする処理を入れるやり方もあります。たいてい、ブラウザのUser-Agentを見てWindowsのIE6がきたことを認識して分岐していますので、PHPなどのサーバサイドスクリプトで可能になります。

しかし、今回は、TypePad.jpだったので、サーバサイドスクリプトは使えません。そこで、TypePad.jpはSSIが有効になっていることを利用して、SSIでXML宣言を入れたり隠したりする方法をとってみました。

<!--#if expr="$HTTP_USER_AGENT != /MSIE 6.0/ ||
              $HTTP_USER_AGENT != /Windows/ " --><?xml version="1.0" encoding="UTF-8"?>
<!--#endif --><!DOCTYPE html PUBLIC
  "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
~
</html>

実際のTypePad.jpの編集画面ではこんな感じで(加工しています)。いまどきのTypePad系のテンプレートであれば、テンプレートモジュールのhead-commonをいじることになると思います。

Typepadxml3
▲TypePad.jpでの編集画面

ちなみに、TypePad.jpだけではなく、ココログプロでも動くことを確認しています。おそらく、TypePad ASP [www.sixapart.jp] で動いているところならできると思います。

たとえば都道府県分47個のblogがTypePadにあったとして、それらのblog群のカテゴリに相違がある場合、不足しているとしてレポートするPerlスクリプトです。

僕以外の誰に役立つかは知らん。

Filename: check_category.pl

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
binmode STDOUT=>':utf8';
 
my $bloglist =
{
  '愛知県'   => 1,
  '愛媛県'   => 2,
  '茨城県'   => 3,
  '岡山県'   => 4,
  '沖縄県'   => 5,
  '岩手県'   => 6,
  '岐阜県'   => 7,
  '宮崎県'   => 8,
  '宮城県'   => 9,
  '京都府'   => 10,
  '熊本県'   => 11,
  '群馬県'   => 12,
  '広島県'   => 13,
  '香川県'   => 14,
  '高知県'   => 15,
  '佐賀県'   => 16,
  '埼玉県'   => 17,
  '三重県'   => 18,
  '山形県'   => 19,
  '山口県'   => 20,
  '山梨県'   => 21,
  '滋賀県'   => 22,
  '鹿児島県' => 23,
  '秋田県'   => 24,
  '新潟県'   => 25,
  '神奈川県' => 26,
  '青森県'   => 27,
  '静岡県'   => 28,
  '石川県'   => 29,
  '千葉県'   => 30,
  '大阪府'   => 31,
  '大分県'   => 32,
  '長崎県'   => 33,
  '長野県'   => 34,
  '鳥取県'   => 35,
  '島根県'   => 36,
  '東京都'   => 37,
  '徳島県'   => 38,
  '栃木県'   => 39,
  '奈良県'   => 40,
  '富山県'   => 41,
  '福井県'   => 42,
  '福岡県'   => 43,
  '福島県'   => 44,
  '兵庫県'   => 45,
  '北海道'   => 46,
  '和歌山県' => 47,
};
 
 
my $categories_sum  = {};
my $categories_hash = {};
foreach my $blog ( keys %$bloglist) {
  my $blog_id = $bloglist->{$blog};
  my $categories = category_list($blog_id);
  foreach my $item ( @$categories ) {
    $categories_sum ->{ $item->{categoryName} }++;
    $categories_hash->{ $blog }->{ $item->{categoryName} } = 1;
  }
}
 
foreach my $blog ( sort keys %$bloglist ) {
  print "$blog\n";
  foreach my $category ( sort keys %$categories_sum ) {
    if ( !$categories_hash->{ $blog }->{ $category } ) {
      print "$category\n";
    }
  }
  print "\n";
}
 
exit;
 
sub category_list {
  my $blog_id = shift;
  my $xmlrpc = TypePadXMLRPC->new();
  $xmlrpc->set();
  # カテゴリリスト取得
  $xmlrpc->set_blogid( $blog_id );
  my $categories_list = $xmlrpc->mt_getCategoryList();
  return $categories_list;
}
 
 
package TypePadXMLRPC;
 
use XMLRPC::Lite;
sub new{
  return bless{ _DATA => { } }, shift;
}
sub dataref  { $_[0]->{ _DATA } }
sub set {
  my $self = shift;
  $self->dataref->{api}      = 'http://www.typepad.jp/t/api';
  $self->dataref->{username} = 'hogehoge';
  $self->dataref->{password} = 'fugaguga';
  return;
}
sub set_blogid {
  my $self   = shift;
  my $blogid = shift;
  $self->dataref->{blogid} = $blogid;
}
sub mt_getCategoryList {
  my $self = shift;
  my $categories_list = XMLRPC::Lite
      -> proxy( $self->dataref->{api} )
      -> call('mt.getCategoryList',
        $self->dataref->{blogid},
        $self->dataref->{username},
        $self->dataref->{password},
      )
      -> result;
  return $categories_list;
}
 
 
1;

実行結果は、もう不足を直しちゃったあとなので提示できません……

MovableTypeのXML-RPCインターフェースと同じAPIを持つblogシステムなら使えるんじゃなかろうか。

TypePad系blogサービス(ココログプロ、BOXERBLOG等)で、最初に設定されるドメイン(例:cl.cocolog-nifty.com)でblogを始めて、少ししたら独自ドメインを取ってblog用にサブドメイン(例:blog.dtpwiki.jp)を割り当てたりとかしたわけですが、結果、同じ内容のコンテンツが、2つのURLで参照できてしまいます。

http://cl.cocolog-nifty.com/dtp/
http://blog.dtpwiki.jp/dtp/

両方同じ内容。

そんで、独自ドメインのサブドメインを設定してから3年ぐらい経ちますがいまだに最初に設定されたドメインで参照している方が多い。非常に多い。

というわけで、むりくりにhttp://cl.cocolog-nifty.com/dtp/を参照している方へ、http://blog.dtpwiki.jp/dtp/にURL変わったんだよーて認識させるための方法を、TypePad系blogサービスが使っているSSI(Server Side Includes)という仕組みを使って実現します。

~~~

(注意:結構危険なので、テンプレートをガシガシいじれる方以外はやらないで下さい)
TypePadの上級テンプレートにて、

Individual Archives(コピペではダメで、あなたのblogのテンプレートに応じて変更してください)

<!--#if expr="$SCRIPT_URI = /^http:\/\/cl.cocolog-nifty.com(.*)/" -->
<!--#set var="vpath" value="$1" -->
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>古いページを見ています</title>
  </head>
  <body>
   <p> このページのアドレスはもはや古いです</p>
   <p>現在のURLは
     <a href="http://blog.dtpwiki.jp<!--#echo var="vpath" -->">
       http://blog.dtpwiki.jp<!--#echo var="vpath" --></a> です</p>
  </body>
</html>
<!--#else -->
<!DOCTYPE html PUBLIC
  "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title><$MTBlogName$>: <$MTEntryTitle remove_html="1"$></title>
...
  </body>
</html>
<!--#endif -->

同様に、Main Index Templateもやります。<!--#なんとか --> を理解してやってください。

つまり、cl.cocolog-nifty,comでアクセスしてきた人と、blog.dtpwiki.jpでアクセスしてきた人に別のhtmlを見せてやります。

これで、cl.cocolog-nifty.comでアクセスしてきた人は、blog.dtpwiki.jpに移転していることがわかるはず。

Typepadssi01
▲http://blog.dtpwiki.jp/dtp/でアクセス

Typepadssi02
▲http://cl.cocolog-nifty.com/dtp/でアクセス。これはさすがに気付くやろ

.htaccessを使う方法は封印されたと聞きましたので、今回はSSIを使う方法を採用してみました。

SSIの構文については、mod_includeで検索すると出てくる

mod_include - Apache HTTP サーバ [httpd.apache.org]

を参照のこと。ちなみに、昔SSIがつかえるということで、リムネットっていうインターネットプロバイダがすこぶる流行った時代がありました……

確かBOXERBLOG powered by TypePad®が終了するってメールが来ていたんだと思うんだけれども、

http://boxer.ne.jp/

では、その素振りをみじんも見せないのは何なんだろう。

そういや、今年はBOXERBLOGのマークが正月バージョンにならなかった気がするのです。

月別 アーカイブ

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.2.7

このアーカイブについて

このページには、過去に書かれたブログ記事のうちTypePadカテゴリに属しているものが含まれています。

前のカテゴリはScriptです。

次のカテゴリはWebです。

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