Ermitejo - エスペラント語日本語翻訳

#BLOGO
発音関連情報の追加、他 (単語辞書引き機能 versio 0.9.1) >
2007
8/
29

分割ページへの前後リンク・ページ数リンク共存法

分類: WordPress / タグ: ,

WordPressでは、長い記事(エントリまたはポストとも呼称される)を<!--nextpage-->タグにて複数ページに分割する機能があります(カテゴリ毎に記事が沢山生じた場合のページ分割ではありません)。その場合、single.php等のテーマファイルに記述する、link_pages()またはwp_link_pages()というWordPressタグにて、それらのページへのリンクを設けることが出来ます。このWordPressタグでは、以下の表示方法を選択出来ます。

  1. 前後のページへのリンク(第三引数にnextを指定する。「前へ」「次へ」等の文字列を設定可能)
  2. 全ページへのリンク(第三引数にnumberを指定する。ページ番号等の文字列を設定可能)

ところが、簡便さを優先したと思われるため、上記は排他的にしか選べません。

ウェブサイトデザインをあまり語れたものではありませんが、こういう「ページ物」のお作法としては、「前へ / 1ページ目 / 2ページ目 / … / nページ目 / 次へ」という書式が一般的です。例えば、Googleの検索結果が複数ページにわたる場合のページリンクは、上記の通りとなっています。このように、前後リンクとページ数リンクを両方表示する、すなわち共存させる方法はないものでしょうか。

結局、テーマファイル側で手間を掛ける必要があったので、調査結果を以下の通りご案内します。

単純にlink_pages()を複数回呼べば良いか …… 否

すぐに考えつくのは、以下のようにページ番号リンクの記述を前後ページリンクの記述で挟み込む方法です。

  • link_pages('<ul>','','next') で、前後ページリンク
  • link_pages('','','number') で、ページ番号リンク
  • link_pages('','</ul>','next') で、前後ページリンク

しかし、これでは「前へ / 次へ / 1ページ目 / 2ページ目 / … / nページ目 / 前へ / 次へ」と記述されてしまいます。

ここで、リンクが張られる文字列(<a href="...">この部分</a>)をlink_pages()の引数で指定出来ることに着目して、挟み始めの前後ページリンクでは「次へ」に当たるところを空白に、挟み終わりの前後ページリンクでは「前へ」に当たるところを空白にすると、確かに一般的なGUI系ユーザエージェント(要はIE, Firefox, Opera等)での表示上は「前へ / 1ページ目 / 2ページ目 / … / nページ目 / 次へ」という結果を得られます。

ところが、実際に吐かれるHTMLコードでは、リンクは変わらず「前へ / 次へ / 1ページ目 / 2ページ目 / … / nページ目 / 前へ / 次へ」と記述されています。リンクが張られる文字列が空白なので、HTMLのお作法としても失格です(Another HTML-lintからお叱りを受けます)。

テーマファイル側でロジックを組む

上記の意図を慮って、リンクが張られる文字列に敢えて空白文字列を指定した場合には何も(リンクすらも)表示しないで欲しいのですが、その希望を実現するためには/wp-includes/post-template.phpのwp_link_pages関数に手を入れるしかありません。

流石にそれは(今後のWordPress本体の改版等の際に)不便ですので、そういったロジックはテーマファイル側で面倒を見るようにしましょう。

まず、ページリンクを記述するより前の部分に、以下のように記述します。

<?php
    $my_page_count = count($pages);
    if (1 < $my_page_count) {
        $my_prev_page = $page == 1
        $my_next_page = $page == $my_page_count ? null : $page + 1;
    }
?>

$pageは現在のページ、$pagesは現在の記事のページ番号が入った配列です。ここから、前のページ番号$my_prev_pageと次のページ番号$my_next_pageを得ています。変数名が被るのも怖いので、適当に変数名を付けています。

そして、ページリンクの記述部では、以下のように書きます。

<?php
    if ($my_prev_page || $my_next_page ) {
        echo '<ul class="pagxo">';
        if ($my_prev_page) {
            echo '<li><a href="';
            the_permalink();
            if ($my_prev_page != 1) {
                echo $my_prev_page. '/';
            }
            echo '">&lt; 前へ</a></li>';
        }
        for ($i = 1; $i <= $my_page_count; $i++) {
            if ($i == $page) {
                echo '<li>#' . $i . '</li>';
            }
            else {
                echo '<li><a href="';
                the_permalink();
                echo $i . '/">#' . $i . '</a></li>';
            }
        }
        if ($my_next_page) {
            echo '<li><a href="';
            the_permalink();
            echo $my_next_page . '/">次へ &gt;</a></li>';
        }
        echo '</ul>';
    }
?>

これで、晴れて目的の書式かつHTML的にも妥当なコードを書き出すことが出来ました。実際の例は、Realforce用メタルカスタムキットの感想の記事等でもご覧いただけます。

上記はこのブログでのテーマの記述内容であり、標準テーマファイルとはUL要素のID等が違いますが、適宜読み替えてください(例えば、ApacheでURLを書き換える設定でなければ、URL生成部はまた異なったものとなります)。ページリンクを本文の上下に書きたい場合には、もう一度上記のページリンク記述部を繰り返すだけで大丈夫です($my_next_page等を改めて得る必要はありません)。

2007/09/24追記 コードの一部修正

XHTML的に妥当でないコードが生成されることが判りましたので、上記はlink_pages()を使わないように書き改めました。ページ番号記述部をlink_pages('', '', 'number', '', '', '<li>#%</li>');とすると、a要素の中にli要素が含まれてしまう(ul要素の中にa要素が含まれてしまう)為です。従って、上記のように泥臭いコードを用いることになりました。特にページをリスト(ul要素等)で表現する必要がない場合には、link_pages()を使っても問題ありません。

WordPressを触り始めてまだ日が浅いですが、ようやくPHPでテーマファイルを書く便利さに気付きました。WordPressはまだ浅い理解ですし、PHPのお作法についてはまだ明るくないために(use strictでuse warningsなPerlだと仮定して眺めてみると)怪しい書きっぷりですので、もっと洗練されて妥当な書き方がありましたら、お教えいただければ幸いです。最善の手はプラグインに外出しすることのようなので、機会があれば取り組んでみたいと思います。

2008/01/05追記 プラグイン作成

上記で触れたプラグインへの処理外出しを行いました。「分割ページ用ページャプラグイン公開」の記事も併せてご覧ください。

#31 (2007/08/29 02:00:47), Gardejo

コメントはまだありません »

コメントはまだありません。

このコメント欄の RSS フィード トラックバック URL

コメントをどうぞ

< 脇書非表示 > 脇書表示

Ĉu vi scias?

braceleto

過去の記事

2007 年 8 月
« 7 月   9 月 »
 12345
6789101112
13141516171819
20212223242526
2728293031  

分類

最近の記事

最近のコメント

最近のトラックバック

RSS

メタ情報

Aŭtorrajto: © Organizo por Zona Servo per Sinkrona Solvo. Ĉiuj rajtoj estas rezervitaj.
Copyright: © Organization for Zonal Service with Synchronous Solution. All rights reserved.