個別アーカイブに「続きを読む」を導入
エントリー・アーカイブに適用される場合はエントリー・アーカイブの追記文章の折りたたみ(改)を参照ください。
デフォルトテンプレートではメインページは追記部分がリンクで隠されており、他のアーカイブページでは追記を含めて全てを一斉に表示するようになってます。
このサイトでは途中からダジャレのオチを追記に隠すよう各アーカイブページを変更したのですが、修正もれで個別アーカイブにジャンプするとネタが最初から見えてしまっていたので(笑)、こちらも追記を隠すように変更しました。
ということで以下、メインページ以外のアーカイブページで追記を隠すように修正する手順を記します。
なおデフォルト状態でメインページにある「続きを読む」をクリックするとPermalink(デフォルトの設定であれば個別アーカイブ)へジャンプします。これは他のアーカイブページが追記を含め一括表示されることが前提になっているからです。
実は個別アーカイブページ以外の修正方法は以前こちらの記事に記していたのですが、まとめて修正できるよう再掲しておきます。テンプレートの名称は3.11ベースで書いてますので3.01の場合は適宜読み替えてやってください。
まずテンプレート(メインページ/カテゴリー・アーカイブ/個別エントリーアーカイブ/日付アーカイブ/)の <head>~</head> の間に下記を追加します。
<script type="text/javascript">
<!--
function showHide(entryID, entryLink, htmlObj) {
extTextDivID = ('Text' + (entryID));
extLinkDivID = ('Link' + (entryID));
if( document.getElementById ) {
if( document.getElementById(extTextDivID).style.display ) {
if( entryLink != 0 ) {
document.getElementById(extTextDivID).style.display = "block";
document.getElementById(extLinkDivID).style.display = "none";
htmlObj.blur();
} else {
document.getElementById(extTextDivID).style.display = "none";
document.getElementById(extLinkDivID).style.display = "block";
}
} else {
location.href = entryLink;
return true;
}
} else {
location.href = entryLink;
return true;
}
}
//-->
</script>
3.01や3.11の場合は、直接埋め込むよりもテンプレートモジュールにした方がスッキリすると思います。その場合の手順は、管理メニューの「テンプレート」をクリック→次ページの一番下の右にある「新しいテンプレートモジュールを作る」をクリック→次ページで下記を設定
- テンプレートの名前:ShowHide(←何でもいいです)
- このテンプレートにリンクするファイル:何も設定しない
- モジュールの中身:上記のスクリプトを丸ごとコピー
として保存&再構築。そして各テンプレートの <head>~</head> の間に
<MTInclude module="ShowHide">
を記述すればOKです。
次に同じく、各テンプレートの下記の赤色部分を青色部分に入れ替えます。
メインページ修正前
<MTEntryIfExtended>
<p(またはspan) class="extended"><a href="<$MTEntryPermalink$>#more">続きを読む "<$MTEntryTitle$>"</a></p(またはspan)>
</MTEntryIfExtended>
カテゴリー・アーカイブ/日付アーカイブ修正前
<MTEntryIfExtended>
<$MTEntryMore$>
</MTEntryIfExtended>
個別エントリーアーカイブ修正前
<$MTEntryMore$>
修正後
<MTEntryIfExtended>
<div id="Link<$MTEntryID$>">
<a href="<$MTEntryPermalink$>" name="<$MTEntryID pad="1"$>" onclick="showHide(<$MTEntryID$>,'<$MTEntryPermalink$>',this);return false;">続きを読む ≫</a>
</div>
<div id="Text<$MTEntryID$>" style="display: none">
<$MTEntryMore$>
<a href="<$MTEntryPermalink$>" name="<$MTEntryID pad="1"$>" onclick="showHide(<$MTEntryID$>,0,this);return false;">≪ 続きを隠す</a>
</div>
</MTEntryIfExtended>
以上です。
2006.04.04 追記
リストから language 属性を削除しました(HTML4.01/XHTMLで非推奨あるいは廃止されているため)。
6週目のカレンダー枠が表示されない不具合修正
左上の月送りカレンダーで6週目が本日になる場合、枠線の下の線が表示されていませんでした。設定ミスです。すいません。
(既に修正されていると思いますが)同様の設定をされている方はメインページやカテゴリーアーカイブ等の各テンプレートのカレンダー表示の高さ設定を、下記の赤色から青色に変更後、再構築することで正常に表示されるようになります。表示されない場合はピクセル数を少しずつ増やして再構築してみてください。
修正前
<div align="center" class="side">
<iframe name="cal-iframe" src="<MTBlogURL>archives/calendar/<MTDate format="%Y/%m/index">.php" width="160" height="112" scrolling="NO" frameborder="0" marginwidth="0" marginheight="0"></iframe>
</div>
修正後
<div align="center" class="side">
<iframe name="cal-iframe" src="<MTBlogURL>archives/calendar/<MTDate format="%Y/%m/index">.php" width="160" height="115" scrolling="NO" frameborder="0" marginwidth="0" marginheight="0"></iframe>
</div>サイドメニュー折りたたみの動作遅延対処
2004.12.06 追記
サイドメニュー折りたたみのエントリーを書き直しましたので
を参照ください。
以前公開したサイドメニュー折りたたみ(改)でリンクリスト等の表示までに時間がかかるメニューがあると、一時的にメニューが開いた状態になってしまいます。これは折りたたみ状態保持スクリプトを適用している場合も同様で、HTML表示を実行した一番最後に折りたたみ用のJavaScriptを起動し、メニューの折りたたみ状態を追加しているためです。
これを解消するため、HTMLの最後にJavaScriptを実行するのではなく、HTMLの任意の位置で数回に分けてこのJavaScriptを実行するように変更しました。このサイトで更新ボタンをクリックして頂ければ実際の折りたたみ動作をご覧いただけます(メニューが全て閉じた状態であればさらに○)。
これはfacet-diversさんのサイドバー折り畳み2:動作遅延対策のアイデアを元に修正させて頂きました。個人的にはこの記事のおかげでサイドメニュー折りたたみがほぼ完成型になったと思っています。
この場をお借りして改めてお礼申し上げます。本当にありがとうございました。
以下、上記エントリーからの変更手順です。なお万が一に備えて以前の状態に戻せるようmenufolder.jsおよび各テンプレートのバックアップは保存してから作業を行われることをお勧めします。
1.menufolder.jsより下記の赤字部分(InitFlodNaviとその起動箇所)を削除
function InitFoldNavi() {
FoldNavigation('newentry','off',true); // 最新エントリー
FoldNavigation('monthly','off',true); // 月別アーカイブ
FoldNavigation('category','on',true); // カテゴリー別アーカイブ
FoldNavigation('comment','on',true); // 最新コメント
FoldNavigation('trackback','on',true); // 最新トラックバック
FoldNavigation('link','on',true); // リンク
}
function FoldNavigation(idName,initMode,viewNum) {
var openMark = '[+]'; /* 閉じている場合に開くためのマーク */
var closeMark = '[?]'; /* 開いている場合に閉じるためのマーク */
:
(省略)
:
}
InitFoldNavi(); // ナビゲーションの折り畳み
削除部分のFoldNavigation…という行は後でそのまま使います。またファイルを保存する際には文字コードにお気をつけください。
2.各テンプレートの一番下に配置していた
<script type="text/javascript" src="<$MTBlogURL$>menufolder.js"></script>
を <head>~</head> の間に移動
3.各テンプレートの、折りたたみを指定している各メニューの下に下記のスクリプトを追加
<script type="text/javascript">
<!--
FoldNavigation('xxxxx','on',true);
//-->
</script>
真中の FoldNavogation? は1項で削除した行をそのまま使います。"xxxxx"の部分に直前のメニューに指定したid属性のものが割り当てられるようにします。例えば、カテゴリーリストメニュー用のid属性に"category"を指定している場合、カテゴリリストメニューの直下には、
<script type="text/javascript">
<!--
FoldNavigation('category','on',true);
//-->
</script>
を配置してください。
なお上記のスクリプトはメニュー対し1対1に細かく分割しなくても構いません。要するに遅延しないメニュー用と遅延するメニュー用のJavaScriptに分割できればよいので、例えばBlogPeople等のリンクリストの直前までの(遅延しない)メニュー分をまとめてリンクリスト(タイトル)の直前に、
<script type="text/javascript">
<!--
FoldNavigation('category','on',true);
FoldNavigation('monthly','on',true);
FoldNavigation('newentry','off',true);
//-->
</script>
と記述して配置し、BlogPeopleやMyBlogList等のリンクリスト用のJavaScriptのみを
<script type="text/javascript">
<!--
FoldNavigation('link1','on',true);
//-->
</script>
と書いてリンクリストの直下にそれぞれ配置してもOKです。
この対処はメニューの途中に遅延するメニューが存在する場合はあまり効果的でありません(遅延するメニュー以降のメニューは遅延します)ので予めご了承ください。
TypeKeyでサイン・インしても表示が変わらない問題を対処
現状の公開テンプレートでは個別アーカイブからTypeKeyにサイン・インした後、サイン・イン状態の画面になりません。実は以前からそういう状態だったのですが「そういうものか…」と思って解決に向かっての行動を怠ってました(他のサイトでTypeKeyサイン・インをしないもので…)が、mayutanさんからのご質問でやはり不具合であることが判明しました。すいません…。
ちなみに現状のテンプレートではサイン・イン後に確認画面に移動、またはリロードするとサイン・インされた状態が表示されます。
個別アーカイブからTypeKeyのサイン・インを行う時の画面遷移は下記の通りです。
- 個別アーカイブの「TypeKey ID を使って サイン・イン してください。」のリンク部分をクリック
- TypeKeyログイン画面にジャンプするのでサイン・イン、または登録(サイン・イン情報をcookieに保持)
- サイン・インが成功すればサイン・イン画面から個別アーカイブにリダイレクト(cookieよりサイン・イン情報を取得してサイン・イン状態表示)
この中の、一番下のcookieの取得が正常に行えていないようです。
この問題解決にあたって参考させて頂いたサイトです。ありがとうございました。
以下、上記サイトからの引用です。
この問題は個別アーカイブの下記の赤色部分(2ヶ所)を青色部分に置き換えることで解決します。
修正前
<script type="text/javascript" src="<MTCGIPath><MTCommentScript>?__mode=cmtr_name_js"></script>
修正後
<script type="text/javascript">
<!--
var commenter_name = getCookie("commenter_name");
// -->
</script>
上記の対処とは別にTypeKeyサイトの「コメンターの設定」にある「ニックネーム」が日本語の場合、文字が化けが発生するようですので、下記の対処も併せて実施する必要があります。個別アーカイブ・コメントプレビュー・コメントリスト・コメントエラー上部にあるJavaScriptの赤色部分をそれぞれ青色のスクリプトに置き換えます。
2004.10.27 追記:3.11-ja以降の場合は「Remember Me」というテンプレートモジュールが修正対象です。注:修正後は再構築が必要です。
修正前
function setCookie (name, value, expires, path, domain, secure) {
var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
}
function getCookie (name) {
var prefix = name + '=';
var c = document.cookie;
var nullstring = '';
var cookieStartIndex = c.indexOf(prefix);
if (cookieStartIndex == -1)
return nullstring;
var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length);
if (cookieEndIndex == -1)
cookieEndIndex = c.length;
return unescape(c.substring(cookieStartIndex + prefix.length, cookieEndIndex));
}
修正後
function setCookie (name, value, expires, path, domain, secure) {
var curCookie = name + "=" + (window.encodeURIComponent ? encodeURIComponent(value) : escape(value)) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
}
function getCookie (name) {
var prefix = name + '=';
var c = document.cookie;
var nullstring = '';
var cookieStartIndex = c.indexOf(prefix);
if (cookieStartIndex == -1)
return nullstring;
var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length);
if (cookieEndIndex == -1)
cookieEndIndex = c.length;
var value = c.substring(cookieStartIndex + prefix.length, cookieEndIndex);
return window.decodeURIComponent ? decodeURIComponent(value) : unescape(value);
}
私のニックネームを半角英数から全角に変更して試したところ、正常に表示されることを確認しました。
これに伴い、公開中のテンプレートを修正致しました(またかよ…って感じですが)。修正したのは、
- MT 3カラム テンプレート(サイズ固定) Individual Entry Archive(1カラム・3カラム) コメント・プレビュー(1カラム・3カラム) コメント・エラー(1カラム・3カラム) コメント保留(getCookieのみ)
- Movable Type 3.01D-ja 個別アーカイブテンプレート
です。それ以前のテンプレートについてはTypeKey対応でないバージョンを考慮して変更していません(というかTypeKey対応のタグがそもそもありませんでしたね…)。
各テンプレートのサイン・インおよびサイン・アウトにつきましては一通り確認致しましたが不具合等ございましたらご連絡ください。
トラックバック表示方法変更&テンプレート修正
世間は Movable Type 3.11で盛り上がってますが(私もか(笑))、自サイトのトラックバック表示をポップアップ画面から同一画面で開くように変更しました。
ブログを始めた当初はコメントやトラックバックがポップアップで開くサイトに憧れて(?)カスタマイズしたのですが、コメントはマルチカラム化との整合性の面でポップアップから同一画面表示に変更し、トラックバックも同一画面で開く方に傾いてきていたので修正しました。
修正のきっかけは当テンプレートご利用の198さんからのご質問です。私がサイトで表示を確認していたところ、トラックバック部分のデザインがきちんとできていないことに気がつき、直しました。
それに伴い公開中のテンプレートも勝手ながら一部修正致しました。修正したのはMT 3カラム テンプレート(サイズ固定)の個別アーカイブ(1カラム・3カラムとも)および、Movable Type 3.01D-ja 個別アーカイブテンプレートです(こちらは3カラム用を追加しました)。MT 3カラム テンプレートの変更は今回見送りました。
スタイルシートの変更はありません。
どのように表示されるかは、このサイトの任意のエントリーでご確認ください(横着ですいません)。オリジナルのテンプレートにある表示内容も下記のように修正しました。
- トラックバックURLとトラックバックの表示を分割。トラックバックがないエントリーはトラックバックURLのみ表示します
- 「このリストは?を参照しています」という文言を削除しました
テンプレートの修正内容は下記の通りです。
Individual Entry Archive の
<div class="blogbody">
:
(40行くらい)
:
<MTEntryIfAllowComments>
の部分を下記のものにごっそり取り替えれば(多分)OKです(修正前のコードはエントリーによってタグの位置やコメントの文言等が異なっていたので割愛させて頂きました)。
<div class="blogbody">
<h3 class="title">●<$MTEntryTitle$></h3>
<$MTEntryBody$>
<div id="a<$MTEntryID pad="1"$>more"><div id="more">
<$MTEntryMore$>
</div></div>
<div class="posted">投稿者 <$MTEntryAuthor$> : <$MTEntryDate$>
<!-- トラックバックを別ウィンドウに表示する場合ここから
<MTEntryIfAllowPings>
| <a href="<$MTCGIPath$><$MTTrackbackScript$>?__mode=view&entry_id=<$MTEntryID$>" onclick="OpenTrackback(this.href); return false">トラックバック</a>
</MTEntryIfAllowPings>
トラックバックを別ウィンドウに表示する場合ここまで -->
</div><!-- posted -->
</div><!-- blogbody -->
<!-- トラックバックを同一ウィンドウに表示する場合ここから -->
<MTEntryIfAllowPings>
<a name="trackbacks"></a>
<div class="comments-head">トラックバックURL</div>
<div class="comments-body">
<p class="techstuff">このエントリーのトラックバックURL:<br />
<$MTEntryTrackbackLink$></p>
</div>
<MTIfNonZero tag="MTEntryTrackbackCount">
<div class="comments-head">トラックバック</div>
<MTPings>
<div class="comments-body">
<p id="p<$MTPingID$>">
≫ <a href="<$MTPingURL$>"><$MTPingTitle$></a> from <$MTPingBlogName$><br />
<$MTPingExcerpt$> <a href="<$MTPingURL$>">[続きを読む]</a>
</p>
<div class="comments-post">トラックバック時刻: <$MTPingDate$></div>
</div><!-- comments-body -->
</MTPings>
</MTIfNonZero>
</MTEntryIfAllowPings>
<!-- トラックバックを同一ウィンドウに表示する場合ここまで -->
<MTEntryIfAllowComments>
以上です。ご参考になれば幸いです。
10月19日?20日に3カラムテンプレート(固定)をご利用になった方へ
一部の方にお知らせです。
昨日、公開中のMT 3カラム テンプレート(サイズ固定)の個別アーカイブテンプレート(Individual Entry Archive:1カラム・3カラム)の一部を改良しておりましたが、修正の際にTypeKey部分のタグを欠落させてしまっていたことが判明致しました。
つきましては10月19日から20日の現時刻にかけてテンプレートをご利用になった方につきましては、TypeKey機能が有効にならない可能性があります(コメントは正常に投稿できます)ので、大変申し訳ございませんが個別アーカイブテンプレートを差し替えくださいますようお願い致します。
2004.10.21 追記
TyprKey機能部分に不具合があり、さらに先程修正致しました。正常に動作しない場合、テンプレートの既知の不具合かも知れませんのでお手数ですがご連絡いただけますでしょうか(現在手元に3.01D-jaの原本がないため、対処に時間がかかるかも知れません)。
Trackbackの連続投稿を受け付けない
Movable Typeでは同一IPからの連続したコメントおよびTrackbackを受け付けない設定になっています。
#今頃気づきました…
といってもデフォルトでは「20秒間受け付けない」という設定になっているので、Trackbackについてはほぼ無条件に受け付けているようなものでしょう。
ということで任意の秒数を設定することができます。例えば10分(=600秒)間受け付けない設定にする場合は、mt.cfg の48行目
# ThrottleSeconds 20
の赤字部分とその横の半角空白を削除して
ThrottleSeconds 600
とします。
この変更に際しては注意点が2点あります。
まず、この値はコメントとTrackbackで共用しているので、秒数を長くし過ぎると異なるコメントを連続投稿する場合に影響が出てしまいます。
これを回避するための作戦として、エレガントではありませんが
- lib/MT/App/Comments.pm
の136行目
my $throttle_period = $app->{cfg}->ThrottleSeconds;
を
my $throttle_period = $app->{cfg}->ThrottleSeconds / 10;
のように割算の式を追加すればコメントのタイミングだけ短くすることができます。ThrottleSeconds に600(秒)を指定しているのであれば、この例では10で割っているので60秒となります。
もう一点ですが、このプログラムでは送信IPアドレス(厳密にはblog_idも?)しかチェックしていないため、他の記事への異なるコメントやTrackbackも受け付けられません。
トラックバックのタイムアウトについて
エントリーを投稿してトラックバックを送信した時、トラックバックの失敗を促すエラーが時々発生します。これはトラックバックping送信処理のタイムアウトが主な原因のようです。
例えばAサイトからBサイトにトラックバックを送信すると、Bサイトの mt-tb.cgi が起動されます。Bサイトではトラックバック受信処理を行い、成功すれば処理が正常に完了したことをAサイトに返送します。AサイトではBサイトからの応答を一定のタイミングで待ってまして、このBサイトからの返送が遅いとAサイトでトラックバックタイムアウトが発生します。
タイムアウトになっても相手サイトにトラックバックは正常に送信されていますので再送の必要はありません。送信サイトの表示を更新して確認されると良いでしょう。
タイムアウトにしたくない場合、タイムアウト時間を送信サイト側で変更することで多少回避することができます。変更箇所は Movable Type 3.01D-ja /3.1x の場合、mt.cfg の259行目です。3.2 では mt-config.cgi の300行目辺りです。
# PingTimeout 20
先頭の "#" と半角空白を削除して、値を
PingTimeout 30
等の任意の秒数に変更します。エントリーの登録時間に影響しますのであまり長くしないようにしましょう。デフォルトでは15秒に設定されています。
タイムアウトが発生した場合、ログを確認することでどのサイトへのpingが成功しなかったかが分かります。エントリー登録完了画面でpingタイムアウトが発生していたらログへのリンクが表示されます。それをクリックすると下記のようなログが表示されます。
2004.10.xx 15:12:23 xxx.xxx.xxx.xxx Ping 'http://rpc.weblogs.com/RPC2' failed: HTTP error: 500 read timeout
2004.10.xx 15:12:24 xxx.xxx.xxx.xxx Ping 'http://ping.blo.gs/' failed: HTTP error: 500 read timeout
上記2サイトは、「管理メニュー」→「ウェブログの設定」→「ウェブログの設定」(3.2 では「設定」→「新規投稿」)の真中辺りにある「広報 / リモートインターフェイス / トラックバック」(3.2 では「更新Ping/トラックバックの設定」)で「Movable Typeが自動的に通知するサイト」の
- blo.gs
- weblogs.com
にチェックボックスがつけられた場合に送信されます(3.2 では technorati.com もあります)。個人的には(多分)上記2サイトのエラーしか発生したことがありません。
エントリー登録時以外にログを参照したい場合は、メインメニュー画面右下にある「Movable Type のログの確認」というリンクをクリックすれば表示されます。3.2 ではメインメニュー画面右下にある「ログ」または、各ブログの管理メニューに「ログ」で確認できます。
参考サイトは下記です。ありがとうございました。
2006.05.23 追記
3.2 の記述を追加しました。また「Trackback」を「トラックバック」に統一しました。
エントリーにpタグとbrタグが入る仕組み(その3:textareaにbrタグを挿入しない)
その2では特定のタグに対して常に改行タグを挿入する方法について述べましたが、今回は逆に改行タグを挿入しない方法について記します。
エントリーに <textarea>~</textarea> や <pre>~</pre> 等、内部情報に改行タグを挿入したくないタグを使用する場合があります。が現状の動作では、例えばpreタグは改行タグが挿入されないよう、
- lib/MT/Util.pm
の html_text_transform の条件式に
sub html_text_transform {
my $str = shift;
$str ||= '';
my @paras = split /\r?\n\r?\n/, $str;
for my $p (@paras) {
if ($p !~ m@^</?(?:h1|h2|h3|h4|h5|h6|table|ol|dl|ul|menu|dir|p|pre|center|form|blockquote|fieldset|address|div|hr)@) {
$p =~ s!\r?\n!<br />\n!g;
$p = "<p>$p</p>";
}
}
join "\n\n", @paras;
}
としっかり設定(青色部分)されていますが、直前の行が空行でなければ期待する動作になりません。textareaタグは条件式に設定すらされていないので一律挿入されます。
こういう時のため(?)に、エントリー編集画面の下に「テキストフォーマット」が用意されているようで、この選択を「Convert Line Breaks」から「なし」に変更することでエントリーには改行タグが一律設定されなくなります。
しかし逆に他のテキスト行に改行タグを自前で付与しなければならず、結構面倒です。また「なし」にしなければならない設定を「Convert Line Breaks」のまま登録してしまい、textarea内をbrタグだらけにしてしまうという失敗もやらかしました。
できればどのエントリーも「Convert Line Breaks」のまま記述でき、なおかつ特定のタグに括られた部分は改行タグを挿入したくないところです。
ということで対処してみました。前回までのような鬱陶しい説明はございません(というか既に十分長い前置きですが(笑))。
先の html_text_transform の
$p = "<p>$p</p>";
の次の行に
$p =~ s!((?:\G|<textarea>)[^<]*?)<br />!$1!g;
を追加すれば <textarea>~</textarea> 間にある改行タグを削除します。条件式にも一応 "textarea" を追加おくと良いでしょう。
なお textarea タグに属性を付与する場合は上記の <textarea> にも属性を記述して、文字列が完全にマッチするように修正してください。例えば <textarea cols="50" rows="10" readonly> というタグを記述されのであれば、スクリプトを
$p =~ s!((?:\G|<textarea cols="50" rows="10" readonly>)[^<]*?)<br />!$1!g;
とする必要があります。
他のタグを追加する場合は、追加した行の "textarea" を "(" と ")" で括り、該当のタグ文字を "|" で区切って追加します(下記はpreを追加する例です)。
$p =~ s!((?:\G|<(textarea|pre)>)[^<]*?)<br />!$1!g;
なお該当のタグ内に別のタグ(というか"<")が存在する(例えば <textarea>~<hoge>~</hoge>~</textarea>)場合は正常に動作しませんので予めご容赦ください。
このシリーズは以上です。
2004.10.23 追記
3.11-ja での動作実績が下記エントリーにて報告されています。
2005.03.10 追記
textareaに属性を設定する場合の説明を追加しました。
テンプレート修正
まずスタイルシート(サイズ可変・固定とも)に、先日話題になった半角文字の折り返し対処を盛り込みました(忘れていました(爆))。本文・コメントとサイドバーのリスト部分に挿入しています。
なおサイズ固定の3カラムで半角文字が折り返さない文字列が存在するとカラムがずれて表示される可能性があります。発生した場合は本対処か、<wbr> タグで折り返す等でご対処ください。
修正イメージは下記の通りです。青色部分が追加になります。
styles-site.css
/* 各エントリー */
.blogbody {
background:#ffffff;
:
margin-bottom:15px;
word-break: break-all;
}
:
/* 「検索」「コメント」「エントリー」「カテゴリ」「リンク」等 */
.side {
font-family: Verdana, Arial, sans-serif;
:
margin-bottom:25px;
word-break: break-all;
}
:
/* 「コメント」の段落 */
.comments-body {
font-size:12px;
:
margin-bottom:0px;
word-break: break-all;
}
また3カラム用インデックステンプレート、アーカイブテンプレート(固定サイズ除く)の表示順序を
- 中央→右→左
から
- 中央→左→右
に変更しました。前者の順序になっていたのは、初期にいくつかのサイトからテンプレートを拝借して修正いた頃の名残みたいです。大変失礼致しました。
表示の遅いリンクリスト等がある場合を考慮して中央カラムを最初に表示するようにしていますが、サイズ可変のテンプレートにつきましてはどの順序で配置しても正常に表示されます。
上記はこれまでのテンプレート関連の各エントリーに盛り込みました(多分)。
エントリーにpタグとbrタグが入る仕組み(その2:blockquoteにbrタグを挿入)
現状の Movable Type の振る舞いでは、エントリーのblockquote開始タグの直前の行に
- 何もない(=エントリーの先頭)
- 文字がある(=段落の途中にblockquoteが存在)
- 空行が1行ある
- 空行が2行ある
という状態によってpタグおよびbrタグの与えられ方が変化します。
上記のケース順に記した下記のエントリーがあるとします。
<blockquote>あいうえお
あいうえお
あいうえお</blockquote>
←空行
かきくけこ
<blockquote>かきくけこ
かきくけこ
かきくけこ</blockquote>
←空行
<blockquote>さしすせそ
さしすせそ
さしすせそ</blockquote>
←空行
←空行
<blockquote>たちつてと
たちつてと
たちつてと</blockquote>
これを保存すると、pタグおよびbrタグは次のように付与されます。
<blockquote>あいうえお
あいうえお
あいうえお</blockquote>
←空行
<p>かきくけこ<br />
<blockquote>かきくけこ<br />
かきくけこ<br />
かきくけこ</blockquote></p>
←空行
<blockquote>さしすせそ
さしすせそ
さしすせそ</blockquote>
←空行
<p><br />
<blockquote>たちつてと<br />
たちつてと<br />
たちつてと</blockquote></p>
2と4の場合は期待する結果になりますが、1と3の場合は改行が付与されません。いずれもエントリーにpタグとbrタグが入る仕組み(その1)に記した通りの動作です。
空行が2行の場合について補足致しますと、段落は連続した改行("\n\n"または"\r\n\r\n")で区切られるため、3つめの改行は段落内の文字として認識されます。つまりblockquoteタグの前に(空の)文字が存在する状態になるため改行タグが付与されます。2行あった空行は、後の1行が段落内の文字として扱われるため1行になります。空行下の <p><br /> に変換されている部分が昔、空行だった行です。
余談ですがこのロジックでは空行が偶数であれば改行タグが一律付与され、奇数の空行の場合は(条件に記されたタグは)付与されないという現象が発生します。
Movable Type における改行タグの挿入方法は、HTMLを記述する際に「タグの直前に空行が存在する」というお作法が前提になっていますが、エントリーに挿入した改行と同じ位置に改行タグの挿入を期待するユーザにとっては混乱を招く原因になっているように思われます。
改行を挿入する方法は他のサイトでも紹介されていますが、個人的には "blockquote" を条件式から除外別の条件式を作って br タグのみ付与する方法を採っています。
具体的には、lib/MT/Util.pmのhtml_text_transform(下記)
for my $p (@paras) {
if ($p !~ m@^</?(?:h1|h2|h3|h4|h5|h6|table|ol|dl|ul|menu|dir|p|pre|center|form|fieldset|blockquote|address|div|hr)@) {
$p =~ s!\r?\n!<br />\n!g;
$p = "<p>$p</p>";
}
}
に青色部分の
for my $p (@paras) {
if ($p !~ m@^</?(?:h1|h2|h3|h4|h5|h6|table|ol|dl|ul|menu|dir|p|pre|center|form|fieldset|blockquote|address|div|hr)@) {
$p =~ s!\r?\n!<br />\n!g;
$p = "<p>$p</p>";
} elsif ($p =~ m@^</?(?:blockquote)@) {
$p =~ s!?r??n!<br />?n!g;
}
}
を追加する方法を推奨します。
blockquote タグは p タグで括ることが禁止されているブロック要素ですが、この方法であれば、p タグで括られずに br タグを付与することができます。
同様に br タグのみを付与したいタグがあれば、blckquote と同様、上記の追加コードに該当のタグ名を追加してください。同様に、brタグを一律付与したいタグは条件から外すのが手っ取り早いと思います。(つづく)
2004.10.23 追記
3.11-ja での動作実績が下記エントリーにて報告されています。
2006.08.13 追記
blockquote 改変方法を変更しました。
エントリーにpタグとbrタグが入る仕組み(その1:コード解析)
我楽さんのBlockquoteタグにデフォルトで改行が入るようにする。(のそれた話)がきっかけという訳ではないのですが、私もエントリーのblockquoteタグに改行が入ったり入らなかったりすることがあり、Movable Typeにおけるbrタグ挿入の振る舞いについて前々から調べてました(時間かかりすぎ?)。
ということで書けそうなレベルまでなんとか到達しましたので、シリーズもので書きます(単なるネタ増やしです(笑))。ほとんどPerl&正規表現メモになってしまいました。Perlプログラマの方には既知の部分しかありませんので予めご容赦ください。また認識誤り等ございましたらお許しください。「難しい」という方は最後のまとめだけお読み頂ければ幸いです。
エントリー入力画面で、下にある「テキストエリア」というセレクトボックスが「Convert Line Breaks」になっている場合、「保存」または「確認」をクリックすると改行部分には自動的に <p>~</p> または <br /> が挿入されます。
この処理を行っているのが
- lib/MT/Util.pm
の html_text_transform という下記の関数です。
1:sub html_text_transform {
2: my $str = shift;
3: $str ||= '';
4: my @paras = split /\r?\n\r?\n/, $str;
5: for my $p (@paras) {
6: if ($p !~ m@^</?(?:h1|h2|h3|h4|h5|h6|table|ol|dl|ul|menu|dir|p|pre|center|form|fieldset|blockquote|address|div|hr)@) {
7: $p =~ s!\r?\n!<br />\n!g;
8: $p = "<p>$p</p>";
9: }
10: }
11: join "\n\n", @paras;
12:}
処理は行番号毎に下記のようになっています。
- 引数であるエントリー文字列をローカル変数 $str に保持(他の処理から"@_"という省略された変数で引き継いでいます)。
- $str が空き、つまりエントリーが空きでなければ取得(この文は $str = '' || $str; と同義でしょうか)。
- $str を改行二つ(つまり空行)が入っている箇所で分割します。例えばエントリーに空行が3ヶ所あれば4つの(いわゆる)段落に分割されます。分割されたものは @paras という配列に保存されます。改行文字は文字コード(Shift_JIS、EUC等)によって "\r\n" と "\n" の2種類があり、
- \r?\n\r?\n
- \r\n\r\n または \n\n
- 分割された単位で下記の処理を繰り返します。この行では @paras から一段落分ずつ取り出し、変数 $p に設定しています。
- 該当するタグ(ここではh1、h2、h3?hr)にマッチしないか判定。
まず "m@?@" という構文はパターンマッチを表しており、段落中に "?" にある文字列が含まれていれば処理結果は「真」、つまり以降の処理を実施します。パターンマッチはPerlでは、
- /正規表現/
- m@正規表現@
- "<?" または "</?"
以上をまとめると、各段落の先頭が"<h1"、あるいは"</h1"等、条件式に書かれている開始・終了タグにマッチしないことが、この行の条件となります。マッチしなければ次の行を実行します。 - 改行文字を "\n<br />\n" に変換。雰囲気で変換しているのは分かりますが先と同様、"?" を\rの直後に用いることで "\r\n" または "\n" を対象としているのが分かります。また文字列置換は、
- s/置換前の文字列/置換後の文字列/g;
- s!置換前の文字列!置換後の文字列!g;
- 段落の最初と最後に <p>~</p> を挿入
- 分割した段落を "\n\n"(空行)で結合して元に戻す
処理内容は以上です。まとめると、
- pタグ:段落の先頭と最後に挿入(空行で区切られたものが「段落」となります)
- brタグ:段落内の改行部分に挿入。ただし条件式にかかれている文字列にマッチしない場合は挿入されない
ということになります。図に単純な例を示します。文章の前後には改行はないものとします。リスト内の「←空行」は便宜上の表示ですので文章には含まれません
【変換前】
あいうえお
←空行
かきくけこ
さしすせそ
【変換後】
<p>あいうえお</p>
←空行
<p>かきくけこ<br />
さしすせそ</p>
タグを用いた例については次回に記します。(つづく)
月送りカレンダー状態保持スクリプト
左上のカレンダーを月送りに変更しまして、ジャンプ先の日別アーカイブページにも月送りカレンダーを配置しているのですが、クリックするとジャンプ先のカレンダーが今月に戻ってしまうので、いつものようにcookieを利用した状態保持機能を追加しました。
この機能を利用することで、他のページにジャンプしてもカレンダーは常に同じ月を表示します。cookieの生存期間はセッション単位ですのでブラウザを新たに起動した場合は今月が表示されます。
下記の月送りカレンダーを使われていることが前提です。またあまりスッキリしたカスタマイズではございませんが予めご容赦ください。
以下カスタマイズ手順です。
1.JavaScriptファイルの設定
下記を"calendar.js"というファイル名でローカル・サイト・パスに保存してください。念のためblogと同じ文字コードで保存してください。
var name = "blogCalendar";
// This function is quoted from Styleswitching JavaScript
// http://jemimap.freeshell.org/style/scripts.html#styleswitcher
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
var yearmonth = readCookie(name);
if (yearmonth) {
var iframe = this.document.getElementsByTagName('iframe');
iframe[0].setAttribute("src","archive-URL/calendar/" + yearmonth + "/index.php");
}
archive-URLの部分は、管理画面の「基本設定」で設定した「アーカイブのURL」を設定してください。例えばアーカイブURLが
http://www.koikikukan.com/archives/
であれば上記のスクリプトは
iframe[0].setAttribute("src","http://www.koikikukan.com/archives/calendar/" + yearmonth + "/index.php");
となります。
本当は <$MTBlogURL$>archives/calendar/ という指定ができればいいのですが、calendar.js を外部ファイルにしているためMTタグはURLに変換されません。そういう訳で直接URLを記述します。
2.カレンダーテンプレート修正
まずカレンダーテンプレートの <head>~</head> の間に下記のJavaScriptを追加します。
<script type="text/javascript">
// This function is quoted and reconstructed from Styleswitching JavaScript
// http://jemimap.freeshell.org/style/scripts.html#styleswitcher
function setMonth(value) {
var name = "blogCalendar";
expires = "";
document.cookie = name+"="+value+expires+"; path=/";
document.location.href = "<$MTBlogURL$>archives/calendar/" + value + "/index.php";
}
</script>
次にカレンダー表示タグの赤色部分を青色部分に置き換えてください。これは先のJavaScriptを起動するための変更です。
<caption class="calendarhead">
<MTArchivePrevious>
<a href="<$MTBlogURL$>archives/calendar/<MTArchiveDate format="%Y/%m/index">.php"><</a>
</MTArchivePrevious>
<$MTArchiveDate format="%B %Y"$>
<MTArchiveNext>
<a href="<$MTBlogURL$>archives/calendar/<MTArchiveDate format="%Y/%m/index">.php">></a>
</MTArchiveNext>
</caption>
<caption class="calendarhead">
<MTArchivePrevious>
<a href="#" onclick="setMonth('<MTArchiveDate format="%Y/%m">');return false;">«</a>
</MTArchivePrevious>
<$MTArchiveDate format="%B %Y"$>
<MTArchiveNext>
<a href="#" onclick="setMonth('<MTArchiveDate format="%Y/%m">');return false;">»</a>
</MTArchiveNext>
</caption>
3.各テンプレートの修正
カレンダーを表示する各テンプレートの、カレンダータグのすぐ下あたり(または</body>の前でもOKと思います)に下記のcalendar.jsを起動するためのタグを追加します。"calendar"のスペルにご注意ください。
<div align="center" class="side">
<iframe name="cal-iframe" src="<MTBlogURL>archives/calendar/<MTDate format="%Y/%m/index">.php" ・・・></iframe>
</div>
<script type="text/javascript" src="<$MTBlogURL$>calendar.js"></script>
以上です。ブラウザ表示時の動作順序は、
- 今月のカレンダーを表示
- その後すぐにcalendar.jsが起動されてcookieより年月取得
- 年月が取得できればその年月のカレンダーを表示
- 年月が取得できなければ何もしない(今月のカレンダーを表示)
です。
またカレンダー切り替え時の動作は、
- カレンダーの月切り替えリンクをクリックした時にJavaScriptのsetMonthが起動されてcookieに年月保存
となってます。
月送りのリンクマークは"</>"から"«/»"に変更しています(文字コードを指定しているにもかかわらず履歴ボタンを使用した時に文字化けが発生するケースがあったので)。ただし私のサイトでは"</>"で正常に動作しているみたいですので適宜お試しください。
またスタイルシート切り替え用スクリプトで styleswitcher.js を利用されている方はJavaScript関数readCookieを削除されても問題ありません。ただし各テンプレートで calendar.js とペアで設定されていることが前提です。
2004.12.06 追記
calendar.js の配置先を「mt.cgiと同じディレクトリ」から「ローカル・サイト・パス」に変更(私の環境は自宅サーバでどちらも同じディレクトリですが、レンタルサーバユーザさんに誤解を与える記述でしたので修正致しました)。
2004.12.27 追記
「1.JavaScriptファイルの設定」で calendar.js のパス設定の説明を修正致しました。
半角文字を折り返す
#ブラウザに依存すると思われる話題ですので認識誤り等ありましたら予めご容赦ください。
エントリーに半角文字を連続させて書いた場合、幅を狭くした時に右にはみだしてしまいます。途中にスペースがあればそこで折り返されるみたいですがスペースがないと折り返されません。
上記確認ブラウザはIE6.0・Netscape7.1・Sleipnir1.66です。Opera7.23では独自仕様で"/"や"-"等で折り返されました。
ということで下記の2通りがありました。
まず、折り返したい部分でHTMLタグの <wbr> を埋め込めば折り返されるようです。検索した記事では「折り返したくない部分を <nobr> ? </nobr> で括り、その中の折り返したい部分に <wbr> を用いる」と記されています。
下の文字列は何もしないと折り返されませんが、hoge5とhoge6の間に <wbr> を挿入してみました。いかがでしょうか(Operaでは折り返されないようですが…)。
hoge1hoge2hoge3hoge4hoge5hoge6hoge7hoge8hoge9hoge10
もうひとつはスタイルシートのblogbody等に
word-break: break-all;
を入れておくという手で、上記は「改行方法を表示範囲に併せて改行する」という設定です。W3C審議中でIEが独自採用したもの(検索結果からの引用)で、ブラウザで動作しないのもありますがIE・Sleipnirでは良好でした。このサイトにも設定してみましたので幅を変更して動作をお試しください(上記のhoge?は動作確認のため <nobr>~</nobr> で括りました)。
下のhoge?でご確認ください(nbrは非設定)。
hoge1hoge2hoge3hoge4hoge5hoge6hoge7hoge8hoge9hoge10
ということで両者を併せて設定しておけばかなり改善されるのではないでしょうか。
参考記事:HTMLクイックリファレンス
アーカイブの設定について
注:本エントリーは 3.1x までの情報です。
管理メニューにある「アーカイブの設定」の意味がよく分かってないので調べてみました(だから分かったという訳でもありませんが…)。
以下、既知の分も含めてメニュー項目別に調査結果を記してみました。
新しく、テンプレートとアーカイブを関連付ける。
テンプレートを新しく作成する時、テンプレートはアーカイブと関連付ける必要があります。
テンプレートにアーカイブの種類を与えることでその中で使用するMovable Typeタグの意味が決まります。例えば<$MTArchiveTitle$>というタグを使っている場合、「カテゴリー」に属していればカテゴリー名、「個別」に属していればエントリーのタイトルに変換されます。つまり、Movable Typeで使用するタグ(のほとんど)の意味はアーカイブの種類に依存するということです。
このフォームで新たに作成した関連付けは次の「アーカイブ」欄に反映されます。例えばカレンダー用テンプレート「Calendar」を新たに作った場合、それを月別アーカイブとして関連付ける場合にこのフォームを使用します。その結果「アーカイブ」の月別欄の「テンプレート」部分に「Calendar」が追加されます。
アーカイブ
おおざっぱに言うとここでアーカイブ(=HTMLページ)生成方法を設定します。
アーカイブの種類
アーカイブの種類(そのままか…)を表示しており、チェックボックスで使用する・しないを設定します。チェックされているアーカイブは再構築の対象になります。他のアーカイブページからリンクされていてチェックされていないと 404 File Not Found エラーになります。
| 個別 | エントリー別のページを作成します。コメント入力フォームはこのアーカイブに属します(と思います)。 |
| 日別 | 日別のページを作成します。カレンダーからのリンクで使う時に便利です。 |
| 週別 | ある週に属するエントリーを一括表示するページを作成します。(作ったことありません…) |
| 月別 | ある月に属するエントリーを一括表示するページを作成します。 |
| カテゴリー | あるカテゴリーに属するエントリーを一括表示するページを作成します。 |
テンプレート
アーカイブを生成(再構築)する際に用いられるテンプレートを表示しています。
アーカイブ・ファイルのテンプレート
意味がわかりにくいのですが、「アーカイブファイル名(のため)のテンプレート」です。Movable Typeタグを利用して、テキストエリアに設定する(=テンプレートとなる)ことでアーカイブファイルに任意のディレクトリやファイル名を与えることができます。
現状の私の設定は下記のようになっています。
個別
<$MTArchiveDate format="%Y/%m/%d-%H%M%S"$>.php
日別
<$MTArchiveDate format="%Y/%m/%d"$>-index.php
月別
<$MTArchiveDate format="%Y/%m/"$>index.php
カテゴリー
cat_<$MTCategoryID$>.php
優先
前述の通り、一つのアーカイブは複数のテンプレートを持つことができます。その場合、それぞれのテンプレートを使ったアーカイブファイルが生成されますが、例えばそのアーカイブへリンクを生成する場合、リンク先を一つに決めなければいけないため、この「優先」を用いてどのテンプレートを使用したアーカイブファイルへリンクを生成するかを決定します。
以上です。なおアーカイブに複数のテンプレートを与えて優先動作の確認をしてみたのですが、思ったような振る舞いが行われませんでした。設定方法自体良くなかったのかどうかは?です。
ページ分割のカスタマイズ修正&追記
Cool Gaming ! weBlogさんのカテゴリ、月別アーカイブのページ分割を拝見して、私の元記事に考慮もれがありましたので追記致しました。またファイル名にMTCategoryDescriptionが使用できること・PHPバージョンについて制限があること等、参考になりましたので併せて元記事に説明およびリンクを設定させて頂きました。ありがとうございました。
ちなみに私はこちらの記事に基づいてカテゴリーファイル名にMTCategoryIDを用いていましたが、その点について反映がもれておりました。m(__)m
テンプレート・モジュールの利用
ここではタイトル下にメニューを与える方法についてのメモです。参考サイトは下記です。ありがとうございました。デザインが合うようにスタイルシートは若干修正致しました。
なおこちらのサイトは訳ありで閉鎖されるようで残念です。
今回はMTIncludeというタグを使ってのモジュール化です。PHPを利用したモジュール化もありますので、Magic WhiteさんのPHP利用のテンプレートモジュール化をご覧ください(他のサイトでJavaScriptを使ったのもありました)。
1.新しいモジュールの追加
管理メニューより「テンプレート」をクリック。次の画面で一番下右の「新しいテンプレート・モジュールを作る」をクリック。
次画面で以下の情報を設定(URLは私のサイト用になってますので適宜変更ください)。
- テンプレートの名前:globalnavi
- モジュールの中身:下記
<div id="globalnavi">
<li><a href="<$MTBlogURL$>">Home</a></li>
<li><a href="<$MTBlogURL$>site.html">About</a></li>
<li><a href="<$MTBlogURL$>about.html">Profile</a></li>
</div>
2.スタイルシートの追加
下記をStylesheetに追加(場所はどこでもOK)
#globalnavi {
padding-top: 10px;
}
#globalnavi li {
padding-left: 0px;
padding-right: 10px;
display: inline;
}
#globalnavi li a,
#globalnavi li a:link,
#globalnavi li a:visited {
font-family: Verdana, Arial, sans-serif;
font-size: 12px;
text-decoration: none;
}
#globalnavi li a:hover {
font-family: Verdana, Arial, sans-serif;
font-size: 12px;
text-decoration: underline;
}
3.テンプレートにモジュールを引き込む設定の追加
各テンプレートのタイトル部分(下記)の該当位置に青色の記述を追加してください。
<div id="banner">
<h1><a href="<$MTBlogURL$>" accesskey="1"><$MTBlogName$></a></h1>
<h2><$MTBlogDescription$></h2>
<$MTInclude module="globalnavi"$>
</div>
4.スタイルシート修正
上記の設定を行ったあと再構築を実施すれば表示されると思いますが、メニュー配置位置がタイトルのパディングに依存するのとバナー部分が広がることでサイドバーのレイアウトが影響を受けますので、必要に応じて下記の部分を修正してください。
#banner {
padding-bottom:15px; ← バナー下からリンクまでのパディング
}
#links-right{
top : 95px ; ← 右サイドバーのトップからの開始位置
}
#links-left{
top : 95px ; ← 左サイドバーのトップからの開始位置
}
![]() | 図は上記のカスタマイズを行った結果です。こんな感じでタイトルの下にリンクメニューが表示されます。 |
