WordPressのthe_excerpt()をカスタマイズする
WordPressのthe_excerpt()は、抜粋を表示するためのテンプレートタグです。ここではTwenty Elevenテーマを使って、the_excerpt()の末尾に表示する内容を変更する方法を解説します。
Twenty Elevenテーマでは、検索結果の本文の一部を表示するためにthe_excerpt()を使っており、抜粋の最後に「続きを読む→」を表示しています。
デフォルトの検索結果

以下、the_excerpt()に掲載されているサンプルを拝借して、カスタマイズ方法を紹介します。それぞれのコードは利用テーマのfunctions.phpに追加してください。
1.末尾の文字列を変更する
function new_excerpt_more($more) {
return ' ..... ';
}
add_filter('excerpt_more', 'new_excerpt_more');

2.末尾に何も出力しないようにする
function new_excerpt_more($more) {
return '';
}
add_filter('excerpt_more', 'new_excerpt_more');

3.「続きを読む」のパーマリンクを設定する
function new_excerpt_more($post) {
return ' <a href="'. esc_url( get_permalink() ) . '">' . 'Read the Rest...' . '</a>';
}
add_filter('excerpt_more', 'new_excerpt_more');

4.Twenty Elevenテーマの場合
冒頭のTwenty Elevenテーマの「続きを読む→」という表示は、functions.phpに次のようなexcerpt_moreフィルタが設定することで実現しています。
function twentyeleven_continue_reading_link() {
return ' <a href="'. esc_url( get_permalink() ) . '">' . __( 'Continue reading <span class="meta-nav">→</span>', 'twentyeleven' ) . '</a>';
}
function twentyeleven_auto_excerpt_more( $more ) {
return ' …' . twentyeleven_continue_reading_link();
}
add_filter( 'excerpt_more', 'twentyeleven_auto_excerpt_more' );
5.excerpt_moreフィルタについて
excerpt_moreフィルタは、wp-includes/formatting.phpのwp_trim_excerpt()に実装されています。
function wp_trim_excerpt($text) {
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$text = strip_tags($text);
$excerpt_length = apply_filters('excerpt_length', 55);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
$words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
if ( count($words) > $excerpt_length ) {
array_pop($words);
$text = implode(' ', $words);
$text = $text . $excerpt_more;
} else {
$text = implode(' ', $words);
}
}
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
excerpt_moreフィルタでwp_trim_excerpt()を起動する定義は、default-filters.phpにあります。
add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
6.抜粋の文字数を変更する
本エントリーとは主旨が異なりますが、抜粋に表示する文字数を変更する場合は「WordPressで抜粋の文字数を変更する方法」を参照してください。
英語の場合は次のコードで実現できます。
function new_excerpt_length($length) {
return 20;
}
add_filter('excerpt_length', 'new_excerpt_length');
WordPressで抜粋の文字数を変更する方法
WordPressで抜粋の文字数を変更する方法を紹介します。WordPressは3.2.1を使っています。
1.問題点
下のスクリーンショットはTwenty Elevenテーマを使った検索結果ページです。検索結果ページではthe_excerpt()を使って(本文の)抜粋を表示するようにしていますが、日本語の場合、the_excerpt()を使っても全文が表示されてしまいます。
理由は、以下の公式ドキュメントによると、「語句の間を半角スペースで区切らない言語では判定できない」ということらしいです。
2.対策
WordPressを使っている方はすでにご存知と思いますが、同梱されている「WP Multibyte Patch」プラグインを有効化します。

これで110文字を抜粋して表示するようになります。
3.文字数を変更する
2項の設定で110文字になるのは「WP Multibyte Patch」プラグインのデフォルト設定によるものです。
文字数を変更する場合は、さらに以下の手順を踏んでください。
まず、wp-content/plugins/wp-multibyte-patch/wpmp-config-sample.phpをコピーしてwpmp-config.phpを作成します。
次に作成したwpmp-config.phpを任意のエディタで開き、下記の「110」の部分を修正します。
$wpmp_conf['excerpt_mblength'] = 110;
修正したwpmp-config.phpをwp-content配下にアップロードします。
例えば「75」に変更すると、次のようにさらに抜粋を短く表示することができます。
ということで、抜粋に任意の文字数を表示できるようになります。お試しください。
WordPress+共有SSLでFacebookページにコンテンツを表示する
「Facebookアプリ「HTTPS+OAuth2.0」の利用を義務付けへ」でお知らせしたとおり、FacebookのIFrameタブはセキュアな接続のみとなる予定です。IFrameタブのコンテンツを制作する場合、この条件は避けて通れなくなります。
このエントリーではそれにさきがけて、WordPress+共有SSLでFacebookページのIFrameタブにコンテンツを表示する実験を行ってみました。WordPressで通常のサイト(http)を運営しつつ、同時にFacebookページをWordPressを使って管理するケースを想定しています。
実験環境は次のとおりです。
- 独自ドメイン(Value Domain取得)
- さくらインターネット・マネージドサーバ+共有SSL ※スタンダードプラン以上であれば共有SSL利用可能
- WordPress 3.1
1.さくらインターネットに独自ドメインを設定する
Value Domainの管理画面で、取得したドメインのネームサーバ設定画面で、「他社提供/自前ネームサーバー」を選択してから「ns2.dns.ne.jp」「ns1.dns.ne.jp」を設定します。他に設定する項目はありません。

さくらインターネットのコントロールパネルの「ドメイン設定」→「新しいドメインの追加」をクリック。

「他社で取得したドメインを移管せずに使う~」の「ドメインの追加へ進む」をクリック。

ドメイン名を設定して「送信する」をクリック。

内容を確認して「送信する」をクリック。

追加されました。続いて「詳細設定にすすむ」をクリック。

「マルチドメインの対象のフォルダをご指定ください」の項目で、ドメインに対応するパスを設定します。ここではWordPressのインストールディレクトリのひとつ上位の階層を設定します。

2.共有SSLを設定する
注:この作業は、1項の作業を終えて30分ほど待ってから行ってください。
共有SSLを設定するには、1項の設定画面にある「共有SSLの利用をお選びください」から「共有SSLを利用する」を選択。

非推奨の旨のダイアログが表示されるので「OK」をクリック。

正常に反映されると、ドメイン一覧の「共有SSL」欄に「表示」のリンクが表示されます。クリックすれば、SSLでアクセスします。さくらで共有SSLを利用する場合のURLは「https://securexxxxx.sakura.ne.jp/独自ドメイン/」となります。
![]()
1項の作業直後に共有SSLを設定しても「このドメインでは利用できません」というエラーではじかれるので、焦らず、時間を空けて再度実行してください。

共有SSLを設定した状態での、httpとhttps(SSL)でWordPressのトップページにアクセスした画面を比べておきます。
httpでアクセス(http://独自ドメイン/)
![]()
httpsでアクセス(https://securexxxxx.sakura.ne.jp/独自ドメイン/)
![]()
httpsでアクセスしたときにスタイルが反映されないのは、link要素のhref属性がhttpsになっていないためです(この対処は後で実施します)。
3.WordPressの画面をFacebookアプリのIFrameタブとして設定する
注:Facebookアプリの作成方法は割愛しますので、「FacebookページにMovable TypeやWordPressの最近のブログ記事を表示する」の2項を参照してください。
登録したFacebookアプリの「Facebook Integration」→「Secure Tab URL」に任意の記事ページのセキュアURLを設定します。この後Facebookページにアプリを追加するのですが、現状は「タブのURL」にも通常のURLを設定しておかないと、IFrameタブをFacebookページに表示する設定が行えないようです。

これでFacebookアプリを追加したFacebookページのIframeタブからアクセスすると、次のように表示されます(実験ですのでレイアウトは無視してください)。これはFirefox 3.6/4での表示です。
![]()
ただし、IE9では次のようにスタイルが適用されません。
![]()
ちなみに、IFrameタブにアクセスするときのFcebookアカウント設定の「アカウントのセキュリティ」→「セキュアな接続(https)」は、次のようにチェックをしています。

4.スタイルを適用できるようにする
2011.06.01 プラグイン作りました。プラグインを利用すれば本項の設定は不要です。
ということで、IEでもスタイルを適用できるようにする方法を紹介します。これはWebデザイナーの口田さんから教えて頂いたサイト情報「WordPress で URL をすべて相対 URL にする方法」のコードを元にしています。
対処方法は、利用しているテーマのfunctions.phpの最後に、以下のコードを設定します。
class relative_URI {
function relative_URI() {
add_action('get_header', array(&$this, 'get_header'), 1);
add_action('wp_footer', array(&$this, 'wp_footer'), 99999);
}
function replace_relative_URI($content) {
$home_url = trailingslashit(get_home_url('/'));
return str_replace($home_url, 'https://securexxxxx.sakura.ne.jp/独自ドメイン/', $content);
}
function get_header(){
ob_start(array(&$this, 'replace_relative_URI'));
}
function wp_footer(){
ob_end_flush();
}
}
if ($_SERVER['HTTPS']) {
new relative_URI();
}
元情報のコードと異なる部分は以下です。
- httpsでアクセスがあった場合のみ追加コードを起動するように変更(青色部分)
- 元のコードではスタイルが反映されなかったため、赤色部分(変更前は'/')をセキュアURLに変更
実際の運用では、IFrameタブで利用する特定のページのみ起動するようにした方が良いでしょう。
WordPressでFacebookページのコンテンツを作る方法は、7月刊行予定の「Facebookページプロフェッショナルガイド」に掲載しています(宣伝)。

毎日コミュニケーションズ
5.注意事項
今回の実験結果は他のレンタルサーバでも同様に表示されることを保障するものではありません。予めご了承ください。
6.関連情報
WordPressやMovable Typeで作ったサイトを日本語ドメインで運用する
WordPressやMovable TypeなどのCMSで制作したウェブサイトを、日本語ドメインで運用するTipsです。MTQに日本語ドメインに関する質問があったのでまとめてみました。
1.日本語ドメインとは
いまさらですが、日本語ドメインとは「http://日本語.jp/」など、ドメイン部分に日本語を使ったものを指します。日本語.jpのリンク先に日本語ドメインのサイトが色々掲載されています。
2.Punycodeとは
日本語ドメインにはPunycodeが深く関わっています。以下、WikiPediaからの引用です。
Punycode(ピュニコード)とは、国際化ドメイン名で使われる文字符号化方式で、RFC 3492で定義されている。Unicodeで書かれた文字列をDNS内の制限された文字コード空間でも使えるようにするための方式で、ユーザーエージェントの実装に依存する。
以下はRFC3492の抜粋で、「3年B組金八先生」をUnicodeに変換し、さらにPunycodeに変換した例です。
3年B組金八先生
u+0033 u+5E74 U+0042 u+7D44 u+91D1 u+516B u+5148 u+751F
Punycode: 3B-ww4c5e180e575a65lsy2b
変換ロジックは、最初に文字列の中からASCII文字だけを抜き出し先頭に並べます。ASCII文字以外の文字がある場合は、ASCII文字の直後にハイフンを付与します。その後の変換ロジックについては「一般化可変長整数」などを使用しますが、説明が面倒なので割愛します。詳しくはWikipediaや次のサイトを参照してください。
Punycodeをドメインとして利用する場合、先頭に識別子として「xn--」を付与し、その後に先程の符号化された文字が続く形式になります。よって日本語ドメイン「3年B組金八先生.jp」のPunycodeによる表現は、
http://xn--3B-ww4c5e180e575a65lsy2b.jp/
となります。
3.Movable Typeに日本語ドメインを設定する
Movable Typeで日本語ドメインを利用する場合、「設定」→「全般」メニューの「サイトURL」に、Punycodeで日本語ドメインを設定します。サイトパスは何でも構いません。

日本語を設定すると、次のように「有効なサイトURLを指定してください。」という警告が出ます。

あとは日本語ドメインを取得するだけです。ここではさくらインターネットが取得した独自ドメインを利用し、
http://ムーバブルタイプ.jeez.jp/
というサブドメインを取得した例で示しています。さくらインターネットでサブドメインを取得する場合、入力文字は半角英数字(a~z、0~9)およびハイフン(-)のみという制約があるので、サブドメイン名はPunycodeで設定します。
下の画像は「http://ムーバブルタイプ.jeez.jp/」でアクセスしたMTのトップページです。アドレスバーの部分が日本語で表示されているのが分かります。
4.WordPressに日本語ドメインを設定する
WordPressでは「サイトのアドレス (URL)」に設定します。WordPressでは日本語の設定が許容されていますが、いくつか調べたところではPunycodeを設定するようです(動作確認できていないので違っていたらご指摘ください)動作確認できました。
下の画像は「http://ワードプレス.jeez.jp/」でアクセスしたWordPressのトップページです。アドレスバーの部分が日本語で表示されているのが分かります。
WordPressでは、日本語ドメインを利用すると、JavaScriptからアドレスバーに表示された日本語を取得するとエラーになる事象があるようです。
この場合、(クライアントの使用するブラウザに依存しますが)アドレスバーに日本語ドメインを表示させないことで対処可能です。
5.ブラウザのアドレスバーにPunycodeでURLが表示される事象について
ブラウザのアドレスバーに日本語のまま表示されず、Punycodeで表示される事象についてはブラウザ依存の動作です。Firefoxではトップドメインが「jp」であれば、日本語ドメインのまま表示されますが、「com」などではPunycodeに変換されます。下の画像は、
http://ムーバブルタイプ.sakuraweb.com/
というさくらインターネット独自ドメインのサブドメインで表示させたものです。アドレスバーのURLがPunycodeで表示されています。
Google Chromeでは、PunycodeのURLを設定しても日本語で表示されるようです。
WordPress 3.0にMovable Typeのタグをインポートする
WordPress 3.0にMovable Typeの記事をインポートする際、Movable Typeのタグをインポートする方法を紹介します。WordPress 3.0でしか試していませんが、WordPress 2.xでも可能かもしれません。
1.概要
WordPress 3.0にMovable Typeの記事をインポートするには、「Movable Type and TypePad Importer」というプラグインを利用しますが、このプラグインでは次の機能しか提供されていません。
- Movable TypeのキーワードフィールドをWordPressの記事のタグとしてインポート
- Movable Typeのタグフィールドはインポート対象外
理由は、MTの途中のバージョンから、インポートフォーマットに「TAGS」というタグを示すフィールドが追加(タグ自体も途中のバージョンから追加)され、「Movable Type and TypePad Importer」プラグインがその仕様に追従していないためと思われます。
本エントリーのカスタマイズを行えば、次のようにMovable Typeのインポート形式のフォーマットに設定されたタグ(青色部分)を、WordPressにインポートすることができます。
Movable Typeのインポートフォーマット(サンプル)
AUTHOR: mtbook
TITLE: モバイルサイトオープン
BASENAME: post-9
STATUS: Publish
ALLOW COMMENTS: 0
CONVERT BREAKS: __default__
ALLOW PINGS: 1
PRIMARY CATEGORY: 子カテゴリ1
CATEGORY: イベント
CATEGORY: 子カテゴリ1
DATE: 09/13/2010 05:46:27 PM
TAGS: モバイル,キャンペーン
…後略…
インポート後の記事一覧画面

このカスタマイズでは、キーワードフィールドの内容をタグにインポートしない制御もあわせて行います。
2.プラグインのインストール
管理画面より「ツール」→「インポート」をクリックして、「Movable Type と TypePad」をクリック。

ダイアログが開くので、右上の「いますぐインストール」をクリック。
「Movable Type and TypePad Importer x.x のインストールが完了しました。」が表示されればインストール完了です。この状態では有効化されていないので、「プラグインを有効化してインポートツールを実行」をクリックするか(この段階ではインポートは実行しません)、プラグイン一覧画面でMovable Type and TypePad Importerを有効化します。
3.プラグインファイルの編集
wp-content/movabletype-importer配下にある、movabletype-importer.phpを編集します。まず、save_post関数の中にある2行を書き換えます。
変更前(赤色部分が変更対象)
function save_post(&$post, &$comments, &$pings) {
$post = get_object_vars($post);
$post = add_magic_quotes($post);
$post = (object) $post;
if ( $post_id = post_exists($post->post_title, '', $post->post_date) ) {
echo '<li>';
printf(__('Post <em>%s</em> already exists.', 'movabletype-importer'), stripslashes($post->post_title));
} else {
echo '<li>';
printf(__('Importing post <em>%s</em>...', 'movabletype-importer'), stripslashes($post->post_title));
if ( '' != trim( $post->extended ) )
$post->post_content .= "\n<!--more-->\n$post->extended";
$post->post_author = $this->checkauthor($post->post_author); //just so that if a post already exists, new users are not created by checkauthor
$post_id = wp_insert_post($post);
if ( is_wp_error( $post_id ) )
return $post_id;
// Add categories.
if ( 0 != count($post->categories) ) {
wp_create_categories($post->categories, $post_id);
}
// Add tags or keywords
if ( 1 < strlen($post->post_keywords) ) {
// Keywords exist.
printf('<br />'.__('Adding tags <em>%s</em>...', 'movabletype-importer'), stripslashes($post->post_keywords));
wp_add_post_tags($post_id, $post->post_keywords);
}
}
…中略…
}
変更後(青色部分が変更後のソースコード)
function save_post(&$post, &$comments, &$pings, &$tags) {
$post = get_object_vars($post);
$post = add_magic_quotes($post);
$post = (object) $post;
if ( $post_id = post_exists($post->post_title, '', $post->post_date) ) {
echo '<li>';
printf(__('Post <em>%s</em> already exists.', 'movabletype-importer'), stripslashes($post->post_title));
} else {
echo '<li>';
printf(__('Importing post <em>%s</em>...', 'movabletype-importer'), stripslashes($post->post_title));
if ( '' != trim( $post->extended ) )
$post->post_content .= "\n<!--more-->\n$post->extended";
$post->post_author = $this->checkauthor($post->post_author); //just so that if a post already exists, new users are not created by checkauthor
$post_id = wp_insert_post($post);
if ( is_wp_error( $post_id ) )
return $post_id;
// Add categories.
if ( 0 != count($post->categories) ) {
wp_create_categories($post->categories, $post_id);
}
// Add tags or keywords
if ( 1 < strlen($tags) ) {
// Keywords exist.
printf('<br />'.__('Adding tags <em>%s</em>...', 'movabletype-importer'), stripslashes($tags));
wp_add_post_tags($post_id, $tags);
}
}
…中略…
}
もうひとつ、process_postという関数を修正します。
変更前(赤色部分が変更対象)
function process_posts() {
global $wpdb;
$handle = $this->fopen($this->file, 'r');
if ( $handle == null )
return false;
$context = '';
$post = new StdClass();
$comment = new StdClass();
$comments = array();
$ping = new StdClass();
$pings = array();
echo "<div class='wrap'><ol>";
while ( $line = $this->fgets($handle) ) {
$line = trim($line);
if ( '-----' == $line ) {
// Finishing a multi-line field
if ( 'comment' == $context ) {
$comments[] = $comment;
$comment = new StdClass();
} else if ( 'ping' == $context ) {
$pings[] = $ping;
$ping = new StdClass();
}
$context = '';
} else if ( '--------' == $line ) {
// Finishing a post.
$context = '';
$result = $this->save_post($post, $comments, $pings);
if ( is_wp_error( $result ) )
return $result;
$post = new StdClass;
$comment = new StdClass();
$ping = new StdClass();
$comments = array();
$pings = array();
} else if ( 'BODY:' == $line ) {
$context = 'body';
} else if ( 'EXTENDED BODY:' == $line ) {
$context = 'extended';
} else if ( 'EXCERPT:' == $line ) {
$context = 'excerpt';
} else if ( 'KEYWORDS:' == $line ) {
$context = 'keywords';
} else if ( 'COMMENT:' == $line ) {
$context = 'comment';
} else if ( 'PING:' == $line ) {
$context = 'ping';
} else if ( 0 === strpos($line, "AUTHOR:") ) {
$author = trim( substr($line, strlen("AUTHOR:")) );
if ( '' == $context )
$post->post_author = $author;
else if ( 'comment' == $context )
$comment->comment_author = $author;
} else if ( 0 === strpos($line, "TITLE:") ) {
$title = trim( substr($line, strlen("TITLE:")) );
if ( '' == $context )
$post->post_title = $title;
else if ( 'ping' == $context )
$ping->title = $title;
} else if ( 0 === strpos($line, "STATUS:") ) {
$status = trim( strtolower( substr($line, strlen("STATUS:")) ) );
if ( empty($status) )
$status = 'publish';
$post->post_status = $status;
} else if ( 0 === strpos($line, "ALLOW COMMENTS:") ) {
$allow = trim( substr($line, strlen("ALLOW COMMENTS:")) );
if ( $allow == 1 )
$post->comment_status = 'open';
else
$post->comment_status = 'closed';
} else if ( 0 === strpos($line, "ALLOW PINGS:") ) {
$allow = trim( substr($line, strlen("ALLOW PINGS:")) );
if ( $allow == 1 )
$post->ping_status = 'open';
else
$post->ping_status = 'closed';
} else if ( 0 === strpos($line, "CATEGORY:") ) {
$category = trim( substr($line, strlen("CATEGORY:")) );
if ( '' != $category )
$post->categories[] = $category;
} else if ( 0 === strpos($line, "PRIMARY CATEGORY:") ) {
$category = trim( substr($line, strlen("PRIMARY CATEGORY:")) );
if ( '' != $category )
$post->categories[] = $category;
…中略…
}
}
…中略…
}
変更後(青色部分が変更後または追加となるソースコード)
function process_posts() {
global $wpdb;
$handle = $this->fopen($this->file, 'r');
if ( $handle == null )
return false;
$context = '';
$post = new StdClass();
$comment = new StdClass();
$comments = array();
$ping = new StdClass();
$pings = array();
$tags = '';
echo "<div class='wrap'><ol>";
while ( $line = $this->fgets($handle) ) {
$line = trim($line);
if ( '-----' == $line ) {
// Finishing a multi-line field
if ( 'comment' == $context ) {
$comments[] = $comment;
$comment = new StdClass();
} else if ( 'ping' == $context ) {
$pings[] = $ping;
$ping = new StdClass();
}
$context = '';
} else if ( '--------' == $line ) {
// Finishing a post.
$context = '';
$result = $this->save_post($post, $comments, $pings, $tags);
if ( is_wp_error( $result ) )
return $result;
$post = new StdClass;
$comment = new StdClass();
$ping = new StdClass();
$comments = array();
$pings = array();
$tags = '';
} else if ( 'BODY:' == $line ) {
$context = 'body';
} else if ( 'EXTENDED BODY:' == $line ) {
$context = 'extended';
} else if ( 'EXCERPT:' == $line ) {
$context = 'excerpt';
} else if ( 'KEYWORDS:' == $line ) {
$context = 'keywords';
} else if ( 'COMMENT:' == $line ) {
$context = 'comment';
} else if ( 'PING:' == $line ) {
$context = 'ping';
} else if ( 0 === strpos($line, "AUTHOR:") ) {
$author = trim( substr($line, strlen("AUTHOR:")) );
if ( '' == $context )
$post->post_author = $author;
else if ( 'comment' == $context )
$comment->comment_author = $author;
} else if ( 0 === strpos($line, "TITLE:") ) {
$title = trim( substr($line, strlen("TITLE:")) );
if ( '' == $context )
$post->post_title = $title;
else if ( 'ping' == $context )
$ping->title = $title;
} else if ( 0 === strpos($line, "STATUS:") ) {
$status = trim( strtolower( substr($line, strlen("STATUS:")) ) );
if ( empty($status) )
$status = 'publish';
$post->post_status = $status;
} else if ( 0 === strpos($line, "ALLOW COMMENTS:") ) {
$allow = trim( substr($line, strlen("ALLOW COMMENTS:")) );
if ( $allow == 1 )
$post->comment_status = 'open';
else
$post->comment_status = 'closed';
} else if ( 0 === strpos($line, "ALLOW PINGS:") ) {
$allow = trim( substr($line, strlen("ALLOW PINGS:")) );
if ( $allow == 1 )
$post->ping_status = 'open';
else
$post->ping_status = 'closed';
} else if ( 0 === strpos($line, "CATEGORY:") ) {
$category = trim( substr($line, strlen("CATEGORY:")) );
if ( '' != $category )
$post->categories[] = $category;
} else if ( 0 === strpos($line, "TAGS:") ) {
$tags = trim( substr($line, strlen("TAGS:")) );
} else if ( 0 === strpos($line, "PRIMARY CATEGORY:") ) {
$category = trim( substr($line, strlen("PRIMARY CATEGORY:")) );
if ( '' != $category )
$post->categories[] = $category;
…中略…
}
}
…中略…
}
4.インポートの実行
管理画面より「ツール」→「インポート」をクリックして、「Movable Type と TypePad」をクリック。

インポートするファイルを選択して「ファイルをアップロードしてインポート」をクリック。
ユーザーを選択して「Submit」をクリック。
記事がインポートされ、タグがある場合は「Adding tags」が表示されます。

記事の一覧でタグがインポートされていることが分かります。
記事編集画面でもインポートされていることが分かります。

2010.09.24
save_post修正後のソースコードに修正もれがあったので、追記しました。
WordPress 3.0 で廃止された非推奨グローバル変数一覧
WordPress 2.xから3.0で廃止された非推奨グローバル変数一覧です。
赤色が非推奨グローバル変数で、青色は非推奨変数に代わる、本来のデータ取得方法です。過去のプラグインで正常に動作しないものがある場合、この変数を利用していないか確認するとよいでしょう。
先日エントリーした「WordPress 3.0 で「Commented entry list」プラグインが正常に動作しない不具合の対処」もこれに該当しました。
/**
* The name of the Posts table
* @global string $tableposts
* @deprecated Use $wpdb->posts
*/
$tableposts = $wpdb->posts;
/**
* The name of the Users table
* @global string $tableusers
* @deprecated Use $wpdb->users
*/
$tableusers = $wpdb->users;
/**
* The name of the Categories table
* @global string $tablecategories
* @deprecated Use $wpdb->categories
*/
$tablecategories = $wpdb->categories;
/**
* The name of the post to category table
* @global string $tablepost2cat
* @deprecated Use $wpdb->post2cat;
*/
$tablepost2cat = $wpdb->post2cat;
/**
* The name of the comments table
* @global string $tablecomments
* @deprecated Use $wpdb->comments;
*/
$tablecomments = $wpdb->comments;
/**
* The name of the links table
* @global string $tablelinks
* @deprecated Use $wpdb->links;
*/
$tablelinks = $wpdb->links;
/**
* @global string $tablelinkcategories
* @deprecated Not used anymore;
*/
$tablelinkcategories = 'linkcategories_is_gone';
/**
* The name of the options table
* @global string $tableoptions
* @deprecated Use $wpdb->options;
*/
$tableoptions = $wpdb->options;
/**
* The name of the postmeta table
* @global string $tablepostmeta
* @deprecated Use $wpdb->postmeta;
*/
$tablepostmeta = $wpdb->postmeta;
これらのグローバル変数は、2.xのwp-includes/deprecated.phpにあったものです。このファイルには非推奨の関数も掲載されています。3.xでも非推奨となっている関数があります。
WordPress の the_date を変更して記事ごとに日付を表示する
WordPress で the_date() という関数を使っていると、同じ日に複数の記事がある場合でも、次のように日付が一回した表示されません(最新バージョンの挙動は未確認です)。

という質問を頂きましたので、本エントリーでは、次のように記事ごとに日付を出力するように変更する方法を紹介します。

方法は簡単で、the_date() を the_time() に変更します。
以下は当サイトで配布しているWordPress テーマの変更箇所です。
変更前
…前略…
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="entry" id="post<?php the_ID(); ?>">
<?php the_date('Y.m.d', '<p class="date">', '</p>') ?>
<h2 class="entry-header"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>の記事ページへ"><?php the_title(); ?></a></h2>
…後略…
変更後
…前略…
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="entry" id="post<?php the_ID(); ?>">
<p class="date"><?php the_time('Y.m.d'); ?></p>
<h2 class="entry-header"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>の記事ページへ"><?php the_title(); ?></a></h2>
…後略…
修正するテンプレートは以下の2つです(多分)。
- メインインデックスのテンプレート (index.php)
- アーカイブ (archive.php)
著作権表示の年号を自動更新するプラグイン V1.1 for WordPress
先日公開した、WordPress で著作権表示の年号(西暦表示)を自動更新するプラグイン wp-copyright を、リアルタイム版に変更しました。

変更箇所は、著作権表示の年号の最終年を、最新の公開記事の投稿年ではなく、ページ表示時のタイムスタンプから取得するようにしました。ご利用のサーバのタイムスタンプに狂いがなければ年が明けたと同時に著作権表示の年号が切り替わります。
プラグインのダウンロードは下記のリンクからどうぞ。
著作権表示の年号を自動更新するプラグイン for WordPress
WordPress で、著作権表示の年号(西暦表示)を自動更新するプラグインです。

最初の公開記事の投稿年と最新の公開記事の投稿年(V1.1 はページ表示時刻より年を取得)を取得し、著作権表示の年号として表示します。単一年の時と複数年の時で表示を下記のように切り替えます。
- 単一年の時:ex. 2007
- 複数年の時:開始年と最終年をハイフンで表示 ex. 2005-2007
1.プラグインのダウンロード
下記のリンクよりプラグインアーカイブ wp-copyright.zip をダウンロードしてください。
- wp-copyright.zip(V1.0)
- wp-copyright.zip(V1.1 最終年をリアルタイムに取得)
プラグイン開発やサポート等にご支援・ご賛同くださる方からの寄付をお待ち申し上げます。下記の「寄付」のリンクをクリックすると Paypal によるお支払いページにジャンプします。
2.プラグインのインストール
プラグインアーカイブを解凍し、中にある wp-copyright.php を wp-content/plugins ディレクトリにアップロードします。
アップロード後、ブログ管理画面の「プラグイン」より「Copyright」の「有効化」をクリックして緑色にしてください。

3.使用方法
このプラグインでは下記のタグで著作権表示用の年号を取得します。
<?php wp_get_copyright_year(); ?>
設定例は、
<p>Copyright © <?php wp_get_copyright_year(); ?> <?php bloginfo('name'); ?> All rights reserved.</p>
で、冒頭のスクリーンショットのような表示にすることができます。
2007.12.30
V1.1を追加しました。
2008.01.01
V1.1のリンクを修正しました。
WordPress でステータスコード 404(Not Found)を返却するエラーページを作る
WordPress のサイトで、「指定された URL が存在しない場合、テーマ(テンプレート)で用意した 404 エラーページ(404.php)の内容を返却します」というようなことが関連書籍等に記されていますが、サーバの設定によっては 404 エラーページを表示したにもかかわらず、HTTP レスポンスにステータスコード 200(OK)を付与してしまうケースがあります。
また、「指定された URL が存在しない場合」についてもバリエーションがあり、例えば、WordPress が解釈できるクエリー文字列が付与され、かつ存在しない URL であれば、適正なサーバの設定を行っても 404 エラーページが表示されない可能性が高いです。
このエントリーでは、指定された URL が存在しない場合、可能な限り 404 エラーページを返却させると同時に、スクリーンショットのように HTTP レスポンスのステータスコードに 404( Not Found)を返却する方法を紹介します。

この内容は 2.1.x から、先日リリースされた WordPress 2.2 まで確認しています。また内容について認識不足・認識誤り等ありましたらご指摘ください。適宜修正したいと思います。
1.ステータスコード 200 と 404 について
基礎知識として、HTTP レスポンスのステータスコード 200(OK)は「リクエストは成功」を意味しますので、404 エラーページを返却する場合は「リクエストURIと一致するリソースが見つけられなかった」ことを意味する 404(Not Found)を付与する必要があります。
ちなみに 404 は 4xx レスポンス(クライアントエラー)に含まれます。
2.ステータスコード 404 を返却する・対処その1(.htaccess の作成)
下記の内容を .htaccess の先頭に記述します。
ErrorDocument 404 /index.php?error=404
ドキュメントルート以外の場所に WordPress をインストールしている場合は、 "/" の前にドキュメントルートからのディレクトリを記述します。
下記のようにした場合は、エラーページの URL によって若干動作が異なります。
ErrorDocument 404 /404.php
「WordPress標準ガイドブック―導入&基本操作からフルチューンまで」では、クエリーによる設定(前者)が推奨されています。
![]() | WordPress標準ガイドブック―導入&基本操作からフルチューンまで マクラケン 直子 WordPress Japan 毎日コミュニケーションズ 2006-09 売り上げランキング : 14469 Amazonで詳しく見る by G-Tools |
3.ステータスコード 404 を返却する・対処その2(テーマ修正)
.htaccess をアップロードしてエラーの動作を確認したところ、存在しない URL を指定すると 404.php がハンドリングされるようになりました。しかしながら、例えばデフォルト設定の個別ページやカテゴリーページの URL の末尾の数字に、存在しない ID を指定した場合は、そのテンプレートに記述したエラー処理の内容が表示されます。
例えば、個別記事の URL(デフォルト)は、末尾に "?p=記事番号" というクエリーが付与されますが、
http://user-domain/?p=10000
と、記事が存在しない URL を指定した場合は、404.php が起動されるのではなく、正しいクエリー文字が URL に含まれていると判断してシングルポスト(single.php)がハンドリングされます。
次に、起動されたシングルポストのテンプレートが下記の構造になっていると仮定します。
<?php get_header(); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
:
(記事がある場合はここに記述されたテンプレートが展開)
:
<?php endwhile; else: ?>
:
(記事がない場合はここに記述されたテンプレートが展開)
:
<?php endif; ?>
<?php get_footer(); ?>
つまり、記事が存在しない ID が付与された正しいクエリーの URL で、上記の構造になっているテンプレートでは、「記事がない場合」の部分(赤色)が実際に処理されることになります。
ここには2つの問題があります。
- テンプレートを正常に処理しているので、ステータスコード 200(OK)を返却する
- 404 エラーであるにもかかわらず 404 エラー用テンプレートがハンドリングされない
この事象は、アーカイブ(archive.php)やページ(page.php)も同様です。アーカイブとして認識されるクエリーが URL に付与されると、アーカイブテンプレート内のエラー処理が起動します。
ステータスコード 404 を返却したいのはもちろんですが、できればエラーページについてはエラーとなる URL に関わらず、一意のページ、つまり 404.php に処理を委ねた方が良い場合もあるのではないでしょうか(例えば 404 エラーページをカスタマイズしたい場合)。
この認識が間違っていないという前提で、下記にそれぞれの対処案を示します。
3.1 ステータスコード 404 を付与する
テーマファイルに含まれる、
- シングルポスト(
single.php) - アーカイブ(
archive.php) - ページ(
page.php)
の先頭に、下記の青色の内容を追加します。
<?php if (!have_posts()) {
header("HTTP/1.1 404 Not Found"); } ?>
<?php get_header(); ?>
:
この設定は、処理すべき記事が存在しない場合、ステータスコード 404 を付与し、その後テンプレート後方に出現するエラー処理(前出リストの赤色部分)が実施されます。
3.2 404 エラー用テンプレートをハンドリングする
ここでは2つの方法を提示していますが、基本的に3.2.1を実施してください。
3.2.1 テンプレートを修正する(推奨)
3.1 項の修正内容と一部重複しますが、テーマファイルに含まれる
- シングルポスト(
single.php) - アーカイブ(
archive.php) - ページ(
page.php)
の先頭に、下記の青色の内容を追加します。
<?php if (!have_posts()) {
header("HTTP/1.1 404 Not Found");
include (TEMPLATEPATH . '/404.php');
return; } ?>
<?php get_header(); ?>
:
この行を加えることで、処理すべき記事が存在しない場合は、テンプレートの通常処理を実行する前にレスポンスヘッダに 404 を付与し、404.php に処理を移します。
3.2.2 ソースコードを修正する(非推奨)
今回のカスタマイズは、WordPress のソースコードを解析していて、先にこの方法に辿りつき、それからテンプレートに記述する案が思いつきました。
この方法を用いればテンプレートの修正をせずに、404.php の内容を表示することができます。が、これは覚え書きレベルですので、実際には3.2.1項の修正を推奨します。
/wp-includes/classes.php を任意のエディタで開き、下記の青色部分を追加します。
function handle_404() {
global $wp_query;
// Issue a 404 if a permalink request doesn't match any posts. Don't
// issue a 404 if one was already issued, if the request was a search,
// or if the request was a regular query string request rather than a
// permalink request.
if ( (0 == count($wp_query->posts)) && !is_404() && !is_search() && ( $this->did_permalink || (!empty($_SERVER['QUERY_STRING']) && (false === strpos($_SERVER['REQUEST_URI'], '?'))) ) ) {
$wp_query->set_404();
status_header( 404 );
nocache_headers();
} elseif( !have_posts() ) {
$wp_query->set_404();
status_header( 404 );
} elseif( is_404() != true ) {
status_header( 200 );
}
}
4.まとめ
WordPress でエラーとなる URL でリクエストされた場合に、正しいレスポンスを返却するためには、.htaccess の設定と、テンプレートの修正が必要です。どの部分の修正がどこに適用されるかについては下記の表を参考にしてください。
| 存在しない URL | あり得るクエリーの URL | ||
|---|---|---|---|
| .htaccess なし |
テンプレート修正 なし | サーバ依存 | 200 OK |
| テンプレート修正 あり | サーバ依存 | 404 Not Found | |
| .htaccess あり |
テンプレート修正 なし | 404 Not Found | 200 OK |
| テンプレート修正 あり | 404 Not Found | 404 Not Found | |
「サーバ依存」の部分は、自宅サーバとレンタルサーバで結果が異なったため、このような表記にしています。
5.その他
エラーページの表示に、常に 404.php を利用するのであれば、各テンプレートの構造は(おおざっぱですが)、
<?php if (!have_posts()) {
header("HTTP/1.1 404 Not Found");
include (TEMPLATEPATH . '/404.php');
return; } ?>
<?php get_header(); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
:
(記事がある場合はここに記述されたテンプレートが展開)
:
<?php endwhile; endif; ?>
<?php get_footer(); ?>
と、エラー処理を省略したフォーマットで統一できそうな気がします。
また上記までの修正で、ステータスコード 404 が付与されるようになりますが、レスポンスヘッダ全体を眺めた場合、X-PingBack ヘッダが付与されることついては懸念が残ってます。
WordPress に Movable Type 風の「Syndicate this site」を表示する
WordPress に、Movable Type の以前のバージョンで表示されていた RSS フィードのリンク「Syndicate this site」を表示する方法です。ご質問を頂きましたので、大変遅くなりましたが本エントリーにて紹介致します。
スクリーンショットは WordPress Default テーマへの設定例です。
1.サイドバーの修正
1.1 WordPress Default テーマの場合
テーマエディタでサイドバーの編集画面を開き、最後の方に下記の青色部分を追加します。
<?php } ?>
<li class="syndicate"><a href="<?php bloginfo('rss2_url'); ?>">Syndicate this site (XML)</a></li>
</ul>
</div>
1.2 当サイト配布テーマの場合
テーマエディタでサイドバーの編集画面を開き、最後の方に下記の青色部分を追加します。
</li>
<li style="margin-top:25px"><a href="<?php bloginfo('rss2_url'); ?>">Syndicate this site (XML)</a></li>
<li><a href="http://www.koikikukan.com/"><img src="<?php echo get_settings('home'); ?>/wp-content/themes/koikikukan3/images/koikikukan.gif" alt="koikikukan" title="koikikukan" width="128" height="22" /></a></li>
</ul>
</div>
</div>
2.スタイルシートの設定
WordPress Default テーマの場合、テーマエディタでスタイルシート編集画面を開き、最後の方に下記のスタイルを設定します。
.syndicate {
margin-top: 25px;
}
WordPress における日付/時間の表示とフォーマット変更方法
WordPress への記事投稿日の日付および時間の表示方法と、日付/時刻フォーマットを変更するカスタマイズをご紹介します。
このエントリーのきっかけは、当サイトで配布しているテーマに表示される記事投稿時間を24時間表記に変更する方法についてのご質問だったのですが、それだけでは何なので一通り調べてみました。
1.概要
テンプレートの記事投稿時間を表示したい位置に
<p><?php the_time() ?></p>
を設定すると、下のように時刻情報に変換されてページに表示されます。
<p>21:07:51<p>
2.テンプレートタグ
日付表示用テンプレートタグには次の2つがあります。
2.1 the_time
記事の投稿時間を表示します。書式は次の通りです。
<?php the_time('format') ?>
format には2項以降に示す「表示フォーマット」を設定します。
カッコ内を省略すると、4項の管理画面に設定した表示フォーマットが適用されます。
2.2 the_date
記事の投稿時間を表示します。書式は次の通りです。
<?php the_date('format', 'before', 'after', echo) ?>
the_time との違いは、
- 同一日に複数記事がある場合は最初の記事にだけ表示
- 日付/時間の前後に表示するテキストの指定が可能
- PHPの変数として取得可能(その場合、表示されません)
が挙げられます。特に一つ目の振る舞いが大きな違いですので、使用する場所に応じて使い分けると良いでしょう。
format は3項以降に示す「表示フォーマット」を設定します。before は日付/時間の前に表示するテキスト、after は日付/時間の後に表示するテキスト、echo は、日付/時間を表示する場合は true、変数として取得する場合は false を設定します。
変数として取得する場合のサンプルを以下に示します。
<?php $my_date = the_date('', '', '', false); ?>
カッコ内を全て省略すると、4項の管理画面に設定した表示フォーマットが適用されます。
管理画面に設定した表示フォーマットを適用し、なおかつ日付/時間の前後にテキスト(ここでは p 要素をサンプルとして設定)を表示したい場合は、次のようにします。
<?php the_date('', '<p>', '</p>') ?>
このタグのパラメータに前後のテキストが設定できる理由は、仮にタグの外側に HTML タグを設定した場合、(同一日付のエントリーが複数あると)このタグが表示されないことがあり、外側に設定した HTML タグが残ってしまいます。これを避けるためにパラメータとしてタグを設定できるようにしています。
3.表示フォーマット
表示フォーマットは、時間を表示するフォーマット文字(後述)と、任意の文字列で構成されます。
1項のように the_time を利用して
<p>21:07:51</p>
という表示にしたい場合は、時分秒のフォーマット文字「h」「i」「s」と、それぞれを区切る文字「:」で、
<p><?php the_time('h:i:s') ?></p>
というフォーマットをパラメータに設定します。
4.フォーマット設定方法
フォーマットは次のいずれかの方法で設定することができます。
- 管理画面の [オプション] - [一般設定] - [日付のフォーマット/時間のフォーマット]
- テンプレートタグに直接記述
「テンプレートタグに直接記述」というのは、2.1項の例では
<?php the_time('h:i:s') ?>
という風に、カッコ内にパラメータとして表示フォーマットを設定することを指します。
管理画面での設定箇所は下のスクリーンショットの通りです。「日付のフォーマット:」フィールドの内容が the_date、「時刻のフォーマット:」フィールドの内容が the_time に対応しています。

フィールドに設定されたフォーマットを利用するには、2項に記した通り、テンプレートタグの the_date 、the_time のパラメータが空きであることが条件となります。
当サイトで配布しているテーマでは日付フォーマットを直接テンプレートに埋め込んでますので、管理画面から設定できるようにするには、テンプレートの下記の部分をそれぞれ変更してください。
日付表示(変更前) *1
<?php the_date('Y.m.d', '<p class="date">', '</p>') ?>
日付表示(変更後)
<?php the_date('', '<p class="date">', '</p>') ?>
時間表示(変更前)
Posted at <?php the_time('h:i') ?>
時間表示(変更後)
Posted at <?php the_time() ?>
5.フォーマット文字一覧
PHP:date より、よく使われそうなフォーマット文字を抜粋し、下記にまとめてみました。
なお、日本語版 WordPress の場合、表中の月表示および曜日表示は日本語になります(英語表記にする場合の変更方法は「WordPress の月・曜日を英語表記にする」を参照)。
| 単位 | フォーマット文字 | 意味 | 表示例 |
|---|---|---|---|
| 年 | Y | 4桁の数字 | 1999, 2003 |
y | 2桁の数字 | 99, 03 | |
| 月 | m | 2桁の数字 | 01 - 12 |
n | 1桁または2桁の数字 | 1 - 12 | |
F | フルスペル | January - December | |
M | 3文字の省略形式 | Jan - Dec | |
| 日 | d | 2桁の数字 | 01 - 31 |
j | 1桁または2桁の数字 | 1 - 31 | |
| 曜日 | D | 3文字の省略形式 | Mon - Sun |
l | フルスペル | Sunday - Saturday | |
| 午前/午後 | a | 小文字 | am / pm |
A | 大文字 | AM / PM | |
| 時 | h | 2桁の数字・12時間表示 | 01 - 12 |
g | 1桁または2桁の数字 12時間表示 | 1 - 12 | |
H | 2桁の数字・24時間表示 | 00 - 23 | |
G | 1桁または2桁の数字 24時間表示 | 0 - 23 | |
| 分 | i | 先頭にゼロをつける | 00 - 59 |
| 秒 | s | 先頭にゼロをつける | 00 - 59 |
以下は年月日・時分秒の設定早見表です。
| 年 | 月 | 日 | 設定例 | 表示 | |||
|---|---|---|---|---|---|---|---|
| 4桁 | Y | 2桁 | m | 2桁 | d | Y/m/d | 2007/01/01 |
| 0なし | j | Y/m/j | 2007/01/1 | ||||
| 0なし | n | 2桁 | d | Y/n/d | 2007/1/01 | ||
| 0なし | j | Y/n/j | 2007/1/1 | ||||
| 2桁 | y | 2桁 | m | 2桁 | d | y/m/d | 07/01/01 |
| 0なし | j | y/m/j | 07/01/1 | ||||
| 0なし | n | 2桁 | d | y/n/d | 07/1/01 | ||
| 0なし | j | y/n/j | 07/1/1 | ||||
| 時 | 分 | 秒 | 設定例 | 表示 | |||
|---|---|---|---|---|---|---|---|
| 12時間表記・2桁 | h | 2桁 | i | 2桁 | s | h:i:s | 01:02:03 |
| 12時間表記・0なし | g | g:i:s | 1:02:03 | ||||
| 24時間表記・2桁 | H | H:i:s | 13:02:03(01:02:03) | ||||
| 24時間表記・0なし | G | G:i:s | 13:02:03(1:02:03) | ||||
6.参考・関連リンク
2007.03.13 追記
テンプレート改修に伴い、4項の記述を修正しました。
*1:2007.03.13 以前にテンプレートをダウンロードされた場合、メインページ/アーカイブページについては下記の変更を行ってください。
日付表示(変更前)
<p class="date"><?php the_time('Y.m.d') ?></p>
日付表示(変更後)
<p class="date"><?php the_date() ?></p>

