フォーラム

[解決済み] WordPressのデフォルトの仕様では、home.phpがトップページ? (32 件の投稿)

  1. dogante
    メンバー
    4 ヶ月前の投稿 #

    WordPress2.8.4を、ブログとしてではなく、通常サイトのCMSとして使用するためにカスタマイズしています。私が現在行っているのは “存続 のテンプレート(他人が作成したテンプレート)をカスタマイズする作業ではありません。”今回の場合、私がテンプレートをほぼ初期の状態から作成していま す。

    WordPressのデフォルトの仕様(管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していない状態)では、サイトのルートURL(例:http://example.com/)にブラウザでアクセスするとまずhome.phpを探して、home.phpが存在すればその内容をサイトのトップページとして表示する仕組みになっているのでしょうか?

    この場合、home.phpに以下の例ような固定ページとしての記述をすれば、home.phpを固定ページとし(管理画面の「ページ」→「新規追加」より入力した記事を表示し)、かつ、サイトのトップページとして固定できるのでしょうか(管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していないことが前提です。)?
    固定ページとしての記述 例:

    <?php
    /*
    Template Name: 固定ページ
    */
    ?>

    よろしくお願いします。

  2. dogante
    メンバー
    4 ヶ月前の投稿 #

    上記の質問ですが、現在作成しているサイトにブログはなく固定ページだけなので、各ページのサイドバー、ヘッダー、フッターは同一となり、コンテンツ部分だけがページ毎に異なります。

    コンテンツ部分は、サイトの利用者に管理画面の「ページ」→「新規追加」より入力してもらうことになります(つまり、サイトを利用者がはじめて利用する段階では、固定ページは何も作成されていません。ここが問題となるところです。)。

    そのため、テンプレートはindex.phpのみで事足りると思いました。

    しかし、index.phpに上記コメントの例のように「固定ページとしての記述」を指定しているにもかかわらず、いざサイトのルートURL(例:http://example.com/)にアクセスするとindex.phpには投稿記事の一覧が表示されてしまいます(このサイトには、ブログはないので投稿記事は必要ありませんが、検証用に投稿記事も投稿しました。)。

    上述したとおり固定ページの記事は、サイトの利用者に管理画面より入力してもらうため、管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] で予めトップページを指定しておくことができません(ご存知のように、この機能は既に公開済みのページをトップページにするためのものだからです。)。

    そこで、公開前の固定ページをそのページに付加されこととなるページタイトル又はページの並び順等で判別し、トップページとしたいのです。

    たとえば、固定ページのページタイトルが「ホーム」であった場合にそれをトップページとする。または、固定ページのページ順が「0」(最初)であった場合にそれをトップページとするなどの具合です。

    追加質問1:
    この場合、index.phpと同じ内容のhome.phpを作成して、home.phpに<?php query_posts(‘pagename=ホーム’); ?>又は<?php query_posts(‘paged=0’); ?>などと記述し、その下にコンテンツ部分のループ(管理画面の「ページ」→「新規追加」より入力した記事を表示させたい)を記述する方法ぐらいしか思い浮かびませんが、これで解決するのでしょうか(教えて下さい。)?

    追加質問2:
    どうにかしてhome.phpを使用せず、index.phpのみでトップページに固定ページの内容を表示するようにできないでしょうか(上述したとおりコンテンツ部分は、サイトの利用者に管理画面より入力してもらうため、管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] で予めトップページを指定しておくことができません。)?

    よろしくお願いします。

  3. shokun0803
    メンバー
    4 ヶ月前の投稿 #

    追加質問1のquery_postsをindex.phpに記述すれば良いだけでは?query_postsでループを制御しているわけですからhome.phpだろうがindex.phpだろうが表示内容は制御できるはずです。

  4. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん
    ご回答、ありがとうございました。

    追加質問1のquery_postsをindex.phpに記述すれば良いだけでは?query_postsでループを制御しているわけですからhome.phpだろうがindex.phpだろうが表示内容は制御できるはずです。

    ただ、追加質問1のquery_postsをindex.phpに記述すとindex.phpにサイトのトップページ(固定ページのページタイトルが「ホーム」でのページ。または、固定ページのページ順が「0」(最初)のページ)の記載情報しかループに表示されなくなります。

    どうにかしてquery_posts又はそれ以外のタグで固定ページの情報(投稿ページの情報ではなく)しかループに表示しないようにできないでしょうか?

    よろしくお願いします。

  5. shokun0803
    メンバー
    4 ヶ月前の投稿 #

    ん~、やりたいことが見えてきません。
    index.phpだけで全てのページを制御したいということですか?

    TOPページと他のページの構成が別なのであればhome.phpに追加質問1のquery_postsを記述してindex.phpはページだけを表示するようにループを制御すれば可能ではないですか?

    質問で記述されている内容でほとんどクリアできそうな気がするんですけどね。ご自身で試してみていますか?論じるよりも試したほうが早いですし、スキルアップにもなりますよ;)

  6. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん
    ご回答、ありがとうございました。

    index.phpだけで全てのページを制御したいということですか?

    その通りです。テンプレートファイルの管理及び更新等をできるだけ簡単にするためにindex.phpだけでトップページ及びその他のページを制御しようとしています。

    TOPページと他のページの構成が別なのであればhome.phpに追加質問1のquery_postsを記述してindex.phpはページだけを表示するようにループを制御すれば可能ではないですか?

    そうなのですが、トップページとその他のページの構成が同じなのでindex.phpにまとめたいと思いまして。ちなみに、トップページもその他のページも同じデザイン(構成)の固定ページです。

    ご自身で試してみていますか?論じるよりも試したほうが早いですし、スキルアップにもなりますよ;)

    はい、色々試しています。もう、いろいろ試し始めて数日が経過しました(私のWordPressにおけるスキルの未熟さが影響しています。)。

    よろしくお願いします。

  7. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん

    まだ、私の問題は解決していませんが、色々試してみて私のquery_postsの理解が間違っていたようです。

    <?php query_posts(‘pagename=ホーム’); ?>で指定できるのは、ページタイトルでなく、ページスラッグでした。また、<?php query_posts(‘paged=0’); ?>で指定できるのは、指定した記事を表示するのではなく、対象のテンプレートに表示する記事のページ数(一つの記事が複数ページにわたる場合)を指定するものだったのです。

    また、index.php(「その他ページ」と名前を付ける)とhome.php(「フロント」と名前を付ける)を作成して、特定の固定ページの記事をhome.phpに表示させた場合、そのページにはサイトルート(http://www.example.com)でアクセスできず、サイトルートでアクセスするとデフォルトのWordPressトップページにアクセスしてしまいます。

    つまり同じ記事は自動的にhome.php及びデフォルトのWordPressトップページで表示されてしまいます。そのため、同じ内容のページが2つできてしまうことになります。
    例:
    例えば、「テストページ」というタイトルの固定ページを管理画面より新規追加し、home.php(「フロント」)のコンテンツ部分に表示します。そうすると自動的にその記事はデフォルトのWordPressトップページのコンテンツ部分にも表示されてしまいます。結果、http://www.example.comでアクセスすると、デフォルトのWordPressトップページで生成された「テストページ」というタイトルのページが表示され、http://www.example.com/?page_id=2でアクセス(この場合、「/?page_id=2」部分は例)すると、home.phpで生成された「テストページ」というタイトルのページが表示されてしまいます。

    つまり、管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していない状態でhome.phpに固定ページの記事を表示させるとデフォルトのWordPressのトップページにも同じ記事が表示されるため、同じページが2つできてしまうのです。

    そのため、shokun0803さんのご指摘のようにhome.phpとindex.phpの両方をテーマ内で使用した場合もうまく行きません(同じページが2つ生成されてしまいます。)。

    管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していない状態でこの問題を回避する方法は、あるでしょうか?

    よろしくお願いします。

  8. jim912
    メンバー
    4 ヶ月前の投稿 #

    doganteさん、こんにちは。

    [設定]→[表示設定]→[フロントページの表示]および[固定ページ]の選択状態は、それぞれ

    get_option('show_on_front')
    get_option('page_on_front')

    で取得されています。

    initあたりのフックで、post_titleが「ホーム」となっているページのIDが取得できたら、上記2つにフックし、get_option('show_on_front')の返値がpage、get_option('page_on_front')の返値が取得できたIDとなるようにしてあげれば、テンプレート側でクエリーを打ち直すことも、複数テンプレートを用意することもなくて済むはずです。

  9. shokun0803
    メンバー
    4 ヶ月前の投稿 #

    すみません、私も勉強不足でjim912さんの提示内容が完全に理解できていないのですが・・・
    doganteさんの提示している条件はwordpressが初期状態(インストール直後)でユーザーが設定を何もいじっていないことが前提だと思うのですが、jim912さんの提示している内容は[フロントページの表示]および[固定ページ]を選択していなくてもget_option('show_on_front')の内容を直接書き換えてしまうことで同じような動作を実現すると言うような内容であっていますでしょうか?
    だとすれば色々とできそうですね;)

    query_postsの問題ですが、投稿スラッグではなくタイトルで分岐するならget_postsで制御したほうがよさそうです。
    私なりに考えてみたことはpost_typeでpageだけ取得し、ループ中でタイトルで分岐すれば、例えば「ホーム」というタイトルがあり、かつis_home()ならTOPページと判断しその内容を表示、それ以外のタイトルでかつis_page()であればページの内容を表示、「ホーム」というタイトルがなく、かつis_home()である、またはページ数が0なら「ホームを作成してください」などのように表示するなどではどうでしょうか?

  10. dogante
    メンバー
    4 ヶ月前の投稿 #

    jim912さん、shokun0803さん
    ご回答ありがとうございました。

    いろいろ調べてみて、私が推測するにjim912さんが指摘されているのは以下のようなことでしょうか?

    <?php
    function init(){
    if($page_data['post_title'] == 'ホーム'){
    $page = get_page_by_title('ホーム');
    get_option('show_on_front') = page;
    get_option('page_on_front') = $page -> ID;
    }
    }
    ?>

    上記のコードを私の作成しているカスタムテーマ内のindex.phpの</html>タグの直下に以下のように記述したのですが、ブラウザーには何も表示されなくなってしまいました。

    </html>
    <?php
    function init(){
    if($page_data['post_title'] == 'ホーム'){
    $page = get_page_by_title('ホーム');
    get_option('show_on_front') = page;
    get_option('page_on_front') = $page -> ID;
    }
    }
    ?>

    何か間違ってたら、ご指摘お願いします。

    よろしくお願いします。

  11. jim912
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん、こんにちは。

    [フロントページの表示]および[固定ページ]を選択していなくてもget_option('show_on_front')の内容を直接書き換えてしまうことで同じような動作を実現すると言うような内容であっていますでしょうか?

    おっしゃるとおりです。
    トップページに表示する記事、ページリストの出力リストなどなど、[フロントページの表示]、[固定ページ]を元に出力の変更を行っている箇所は多岐にわたります。事後的にこれらの出力を改変することも不可能ではありませんが、非常に非効率的です。
    それよりは、その挙動に影響を与える根本を正してしまったほうが、漏れもありませんし、簡単ですよね。

    私の提示した内容は、データベースに格納されているデータが何であろうと、ホームというタイトルを持つページがあれば(ステータスの条件も加味せねばならないかもしれませんが)、[フロントページの表示]の選択が「固定ページ」、[フロントページ]の選択が「ホーム」となっているとデータの改変をおこなってしまうというものです。

    その他、記事の保存時に同時に2項目のアップデートを行う方法も考えられますが、記述するコードは、上記の方が圧倒的に少なくなると思います。

  12. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん
    ご回答、ありがとうございました。

    query_postsの問題ですが、投稿スラッグではなくタイトルで分岐するならget_postsで制御したほうがよさそうです。
    私なりに考えてみたことはpost_typeでpageだけ取得し、ループ中でタイトルで分岐すれば、例えば「ホーム」というタイトルがあり、かつ is_home()ならTOPページと判断しその内容を表示、それ以外のタイトルでかつis_page()であればページの内容を表示、「ホーム」というタイトルがなく、かつis_home()である、またはページ数が0なら「ホームを作成してください」などのように表示するなどではどうでしょうか?

    上記方法では、index.php(home.phpを使用せず、index.phpだけで全てのページの表示をまかなう場合)又はhome.php(index.phpのほかにhome.phpをトップページとして使用する場合)の表示内容はコントロールできるのですが、index.php(又はhome.php)以外に存続のトップページ(通常は、最新の投稿ページの一覧が表示されるページ)が出力されてしまいます。つまり、index.php(又はhome.php)と同じページがもう一つ(存続のトップページ)が出力されます。

    結果、http://www.example.comでアクセスすると、存続のトップページで生成されたページが表示され、http://www.example.com/?page_id=2でアクセス(この場合、「/?page_id=2」部分は例)すると、index.php(又はhome.php)で生成されたページが表示されてしまいます。

    つまり、私が思うに、index.php又はhome.php等のファイル内のループでの表示条件を制御してもそれはそのページに表示する内容を制御しているに過ぎず、そのページがサイトのトップページとなることはありません。index.php又はhome.php等のループ内の表示条件を制御しても、WPのトップページはindex.php(又はhome.php)を利用して別途に自動で作成されてしまいます。

    [フロントページの表示]、[固定ページ]でindex.php(又はhome.php)を利用して作成したページをサイトのトップページとして指定すると、index.php(又はhome.php)が存続のトップページと同一のもの(ページ)となります。ただ、今回はこの機能は使用しないのが前提です。

    jim912さんの指摘されている方法が有効だと思うのですが、詳細が分からず困ってます。

    よろしくお願いします。

  13. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん

    index.php(又はhome.php)以外に存続のトップページ(通常は、最新の投稿ページの一覧が表示されるページ)が出力されてしまいます。つまり、index.php(又はhome.php)と同じページがもう一つ(存続のトップページ)が出力されます。

    上記の私のコメントですが、私はindex.php(又はhome.php)以外に存続のトップページができてしまっているかどうかをwp_page_menuタグで検証しています。既にご存知かもしれませんが、wp_page_menuタグは値が「show_home=1」の場合に、wp_list_pagesと違い、サイトのトップページをリストに含めて出力できます。

    以下のようなコードを検証用にページに記載しています:
    <?php wp_page_menu('sort_column=menu_order & show_home=1'); ?>

    上記のコードの出力により、[フロントページの表示]→[固定ページ]でindex.php(又はhome.php)を利用して作成したページをサイトのトップページとして指定すると、index.php(又はhome.php)が存続のトップページと同一のもの(ページ)となるのが分かります。

  14. dogante
    メンバー
    4 ヶ月前の投稿 #

    shokun0803さん

    initあたりのフックで、post_titleが「ホーム」となっているページのIDが取得できたら、上記2つにフックし、 get_option('show_on_front')の返値がpage、get_option('page_on_front')の返値が取得できた IDとなるようにしてあげれば、テンプレート側でクエリーを打ち直すことも、複数テンプレートを用意することもなくて済むはずです。

    どうやら、jim912さんはoption-reading.phpの32行目から54行目あたりに手を加えることをいっておられると思えるのですが、jim912さんが指摘されている内容がお分かりですか?

    jim912さんがいっておられる「ページタイトルが[ホーム]の固定ページのページID」は、以下で取得できると思いますが、その先が全く分かりません。

    <?PHP
    $page = get_page_by_title('ホーム');
    echo $page -> ID;
    ?>
  15. spreadhappiness
    メンバー
    4 ヶ月前の投稿 #

    こんばんは。

    割り込みコメント失礼します。

    doganteさん、フック(アクションフック、フィルターフック)について
    先ず理解される必要があると思います。
    WordPressを拡張する時には理解必須だと思います。

    http://wpdocs.sourceforge.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API

    jim912さんが仰っているのは、具体的には、

    add_filter('option_show_on_front', '自分で作成する関数名');
    add_filter('option_page_on_front', '自分で作成する関数名');

    というように、フィルターフックしてはどうか?ということだと思います。

    フックを使えば、必要のない管理画面のメニューを本体のコードを触ることなく
    非表示かつアクセスできないようにすることも簡単にできます。

    今回されようとしていること(CMS化)にはフックは避けて通れないと思いますよ。
    色んなプラグインのソースコードを見ると参考になるところが多いと思います。

  16. spreadhappiness
    メンバー
    4 ヶ月前の投稿 #

    失礼、読み返したら、

    initあたりのフックで

    とのことですので、jim912さんは、initあたりのフックで
    update_optionで、DBの内容を書き換えてしまってはどうか?
    といってるんですよね?

    早とちり、失礼しました。

  17. dogante
    メンバー
    4 ヶ月前の投稿 #

    spreadhappinessさん
    ご教授、ありがとうございました。

    全然違う方向に行ってしまっていました。
    いろいろ勉強したいと思っているのですが、なかなか何から手をつけて、どのようにすればよいのかがわからなかった状態です。

    つまり、jim912さんがおっしゃっていることは、「簡単なプラグインを作成してはどうか」 と言うことですね?私は、てっきりテーマ自身のファイル又はWPのコアファイルを改造することを指摘されているものだとばかり思っていました。

  18. spreadhappiness
    メンバー
    4 ヶ月前の投稿 #

    doganteさん

    こんばんは。

    私は、てっきりテーマ自身のファイルを改造することを指摘されているものだとばかり思っていました。

    いえいえ。テーマでいいと思いますよ。

    WordPressは結構何でもできちゃうところが、
    わかりにくかったりするところなのかなぁとも思います・・・。

    マニュアルでは確かにプラグインAPIとして書かれているのですが、
    フックは別にテーマ内のソースから呼んでも全く問題ありません。

    私の知っている範囲では、atahualpaというテーマなんかは、
    テーマ内でいろいろやってますよ。
    参考になるところもあるんじゃないかと思います。

  19. dogante
    メンバー
    4 ヶ月前の投稿 #

    spreadhappinessさん
    ご回答、ありがとうございました。

    失礼、読み返したら、

    initあたりのフックで

    とのことですので、jim912さんは、initあたりのフックで
    update_optionで、DBの内容を書き換えてしまってはどうか?
    といってるんですよね?

    上記のspreadhappinessさんのコメントで、私には何をすればよいのか再び全く分からなくなりました。
    spreadhappinessさんが最初のコメントで指摘されている下記のリンクは、今回の要件に関してまだ役に立つのでしょうか?
    http://wpdocs.sourceforge.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API

    もしよろしければ、私は何をすればよいのか、方向性をもう少し噛み砕いて教えていただければ大変助かります(かなりこんがらがって、わからなくなっています。)。

    よろしくお願いします。

  20. dogante
    メンバー
    4 ヶ月前の投稿 #

    spreadhappinessさん
    ご回答、ありがとうございました。

    マニュアルでは確かにプラグインAPIとして書かれているのですが、
    フックは別にテーマ内のソースから呼んでも全く問題ありません。

    テーマ内のソースからフックを呼ぶ場合、今回の場合はテーマ内のindex.php内にフックを記述すればよいのでしょうか(今回はheader.php又はfooter.phpを使用していません。)?また、index.php内にフックを記述する場合、フックはindex.phpの<header></header>内に記述するものですか?

    よろしくお願いします。

  21. dogante
    メンバー
    4 ヶ月前の投稿 #

    jim912さんのおっしゃっている「initあたりのフックで」の意味がよく分からないのですが、spreadhappinessさんからご教授いただいたことを参考にすると

    init('option_show_on_front', '自分で作成する関数名');
    init('option_page_on_front', '自分で作成する関数名');

    などのフックをテーマ内の上記でお尋ねしているファイル(テーマ内のどのファイルのどの部分に記述するのか分からない状態です。)に記述すれば良いということですか?

    よろしくお願いします。

  22. spreadhappiness
    メンバー
    4 ヶ月前の投稿 #

    doganteさん

    フックはindex.phpの<header></header>内に記述するものですか?

    テーマ内のfunctions.phpに記述することになるんじゃないでしょうか?

    もしよろしければ、私は何をすればよいのか、方向性をもう少し噛み砕いて教えていただければ大変助かります。

    atahualpaというテーマのソースコードを追っかけてみてはどうでしょうか?
    方向性が見えるかもしれませんよ。
    (もちろん、WordPressのソースコードも追っかけてみては?)

    P.S.
    私もWordPressを触りだして日が浅いので勉強の日々です。
    オープンソースは色んなソースが見放題!?なので参考にできることが多く助かりますね!

  23. dogante
    メンバー
    4 ヶ月前の投稿 #

    テーマ内にfunction.phpを作成して以下のコードを記述したのですが、うまく行きません。どこか間違っていますか?

    <?php
    function change_fornt_page() {
    $page = get_page_by_title('ホーム');
    update_option('show_on_front', 'page');
    update_option('page_on_front', $page -> ID);
    }
    
    add_action('publish_page', 'change_fornt_page');//記事が公開された場合のアクション
    add_action('edit_post', 'change_fornt_page');//記事が編集された場合のアクション
    ?>

    上記のコードの

    $page = get_page_by_title('ホーム');
    update_option('show_on_front', 'page');
    update_option('page_on_front', $page -> ID);

    部分をifで囲み

    if(「ホーム」というタイトルのページが存在した場合){
    $page = get_page_by_title('ホーム');
    update_option('show_on_front', 'page');
    update_option('page_on_front', $page -> ID);
    }

    としたいのですが、[「ホーム」というタイトルのページが存在した場合]の記述方がいくら調べても見つかりません。どなたか、ご存知でしょうか?または、上記の記述自体が間違っているのでしょうか?

    最終的には、以下でよいかな????と思いますが:

    <?php
    function change_fornt_page() {
    if(「ホーム」というタイトルのページが存在した場合){
    $page = get_page_by_title('ホーム');
    update_option('show_on_front', 'page');
    update_option('page_on_front', $page -> ID);
    } else {
    return false;
    }
    }
    
    add_action('publish_page', 'change_fornt_page');//記事が公開された場合のアクション
    add_action('edit_post', 'change_fornt_page');//記事が編集された場合のアクション
    ?>

    どなたか査定できる方、おられます?現時点では、動作しないので方向性が正しいのかさえ不明です。

    よろしくお願いします。

  24. jim912
    メンバー
    4 ヶ月前の投稿 #

    doganteさん、spreadhappinessさん、こんにちは。

    概ねspreadhappinessさんの理解で正しいです。ただ、他の方法も書いてしまったため、紛らわせてしまいました。

    まずinitのタイミングですが、wp-settings.phpのほぼ最後に

    // Everything is loaded and initialized.
    do_action('init');

    という記述あります。これが、initに登録されていたアクションフックが実行されるタイミングになります。ここのタイミングですが、コメントされているとおり全ての設定の読み込みと初期化が完了が完了した時になります。
    つまりこの後にリクエストを元にして記事の取得が行われる訳です。

    ここで、「ホーム」というタイトルを持つページのIDを探して、存在していたらget_option('show_on_front')、get_option('page_on_front')のフィルターフックを登録しておくのです。

    function check_home_page() {
    	global $wpdb;
    
    	$home_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    	if ( $home_id ) {
    		add_filter( 'pre_option_show_on_front', 'set_page_show_on_front' ) );
    		add_filter( 'pre_option_page_on_front', 'set_home_page_on_front' ) );
    	}
    }

    ※ get_page_by_titleは使いません。それは、この関数が上記同等のクエリーでIDを取得した後に、get_pageでページのデータを取得しているため、不要なクエリーが増えてしまうためです。
    ※ 公開ページのみの指定としたい場合は、上記のクエリーにAND post_status = 'publish'を追加する必要があります。

    で、get_option('show_on_front')、get_option('page_on_front')のフィルターフックとして登録したset_page_show_on_frontとset_home_page_on_frontですが、下記のようになります。

    function set_page_show_on_front( $pre ) {
    	return 'page';
    }
    
    function set_home_page_on_front( $pre ) {
    	return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    }

    で、最後にinitでcheck_home_pageが実行されるようフックの登録をしておきます。

    add_action( 'init', 'check_home_page' );

    これをテーマのfunctions.phpに記述して完了としたい所ですが、set_home_page_on_frontの実行内容が、check_home_pageの実行内容と一部同じで馬鹿っぽいですし、第一、データベースへのクエリーは時間コストが高いのでなるべく少なくしてしまいたいです。

    $home_idをグローバル変数としてしまう手もありますが、今後の改変の際にうっかり変数を上書きされてしまう恐れもあります。そこでクラス化してしまうことにします。

    class auto_home {
    
    var $home_id;
    
    function __construct() {
    	add_action( 'init', array( &$this, 'check_home_page' ) );
    }
    
    function auto_home() {
    	$this->__construct();
    }
    
    function check_home_page() {
    	global $wpdb;
    
    	$this->home_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    	if ( $this->home_id ) {
    		add_filter( 'pre_option_show_on_front', array( &$this, 'set_page_show_on_front' ) );
    		add_filter( 'pre_option_page_on_front', array( &$this, 'set_home_page_on_front' ) );
    	}
    }
    
    function set_page_show_on_front( $pre ) {
    	return 'page';
    }
    
    function set_home_page_on_front( $pre ) {
    	return $this->home_id;
    }
    
    }
    $auto_home = new auto_home();

    これをテーマのfunctions.phpに記述しておけば、思い通りの挙動になるかと思います。

  25. spreadhappiness
    メンバー
    4 ヶ月前の投稿 #

    jim912さん

    素晴らしすぎる!!
    素晴らしくわかりやすいご返答に敬服です!

    pre_option_~ なんですね。
    option_~ だど余計なコードを実行してしまいますね。。。
    勉強になりました!
    ありがとうございます。

  26. dogante
    メンバー
    4 ヶ月前の投稿 #

    jim912さん
    ご回答、ありがとうございました。

    大変参考になりました。どのようにして通常の処理がクラス化されオブジェクトが作成されるかなどもとても勉強になりました。

    以下のリンクは、私が上記のjim912さんのクラス化の理解のために参考にしたサイトです。
    分かり易くクラス化やオブジェクトの作成の仕方(上記でjim912さんが行っていること)が説明されていますので、上記のjim912さんの説明と共に皆さんも参考にできるように追加しておきます。
    クラスとオブジェクト/PHP入門:
    http://www.scollabo.com/banban/php/php_11.html

    ところで、jim912さんが処理をクラス化されたことにより
    add_action( 'init', 'check_home_page' );
    の部分は、
    add_action( 'init', '$auto_home->check_home_page' );
    へと変更しないとだめなんですよね?

    あれ、add_action内の$auto_home->check_home_pageは、コーテーションマークで囲む必要ありましたっけ?

  27. jim912
    メンバー
    4 ヶ月前の投稿 #

    doganteさん、こんにちは。

    __constructメソッドに記述してあるように

    function __construct() {
    	add_action( 'init', array( &$this, 'check_home_page' ) );
    }

    でクラス化への対応はしてありますです。

  28. dogante
    メンバー
    4 ヶ月前の投稿 #

    jim912さん
    ご返答、ありがとうございました。

    __constructメソッドに記述してあるように

    function __construct() {
    add_action( 'init', array( &$this, 'check_home_page' ) );
    }

    でクラス化への対応はしてありますです。

    上記の件、了解しました。

    ところで、上記のjim912さんのクラス化する前のコード及びクラス化後のコードを両方ためしているのですが、クラス化する前のコード(以下)

    <?php
    function check_home_page() {
    	global $wpdb;
    
    	$home_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    	if ( $home_id ) {
    		add_filter( 'pre_option_show_on_front', 'set_page_show_on_front' ) );
    		add_filter( 'pre_option_page_on_front', 'set_home_page_on_front' ) );
    	}
    }
    
    function set_page_show_on_front( $pre ) {
    	return 'page';
    }
    
    function set_home_page_on_front( $pre ) {
    	return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    }
    
    add_action( 'init', 'check_home_page' );
    ?>

    をfunctions.phpに記述して(上記以外にfunctions.phpには、何も記述していません。)サーバのテーマ内にアップロードすると、サイトが何も表示されなくなります(ブラウザーの表示は、真っ白)。

    また、クラス化した後のコード(以下)

    <?php
    class auto_home {
    
    var $home_id;
    
    function __construct() {
    	add_action( 'init', array( &$this, 'check_home_page' ) );
    }
    
    function auto_home() {
    	$this->__construct();
    }
    
    function check_home_page() {
    	global $wpdb;
    
    	$this->home_id = $wpdb->get_var( "SELECT ID FROM <code>$wpdb->posts</code> WHERE <code>post_title</code> = 'ホーム' AND <code>post_type</code> = 'page'" );
    	if ( $this->home_id ) {
    		add_filter( 'pre_option_show_on_front', array( &$this, 'set_page_show_on_front' ) );
    		add_filter( 'pre_option_page_on_front', array( &$this, 'set_home_page_on_front' ) );
    	}
    }
    
    function set_page_show_on_front( $pre ) {
    	return 'page';
    }
    
    function set_home_page_on_front( $pre ) {
    	return $this->home_id;
    }
    
    }
    $auto_home = new auto_home();
    ?>

    をfunctions.phpに記述して(上記以外にfunctions.phpには、何も記述していません。)サーバのテーマ内にアップロードしても、index.phpと存続のWPのトップページは別々のページとして表示され、同一のぺーじになりません(管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] で予めトップページをページタイトルが「ホーム」のページと指定したような状態になりません。)。

    私の検証では、クラス化する前のコード及びクラス化後のコードも両方正しく動作していないようですが、なぜでしょうか?spreadhappinessさん又は誰か他の方で検証された方、おられます?

    よろしくお願いします。

  29. jim912
    メンバー
    4 ヶ月前の投稿 #

    doganteさん、すみません。

    クラス化する前のコード(以下)

    をfunctions.phpに記述して(上記以外にfunctions.phpには、何も記述していません。)サーバのテーマ内にアップロードすると、サイトが何も表示されなくなります(ブラウザーの表示は、真っ白)。

    add_filterの行の)が1つ多くなってしまっています。。。
    クラス化して動いていたものを改めて戻したコードにしたときの消し忘れです。。。

    また、クラス化した後のコード(以下)

    をfunctions.phpに記述して(上記以外にfunctions.phpには、何も記述していません。)サーバのテーマ内にアップロードしても、index.phpと存続のWPのトップページは別々のページとして表示され、同一のぺーじになりません

    $this->home_id = $wpdb->get_var( "SELECT ID FROM <code>$wpdb->posts</code> WHERE <code>post_title</code> = 'ホーム' AND <code>post_type</code> = 'page'" );

    の<code>と</code>を消してくださいな。
    クエリーのフィールド部分はバックティックでクォートするのですが、私はこれを記述するするのが常となっています。これをそのままフォーラムに投稿するとcodeタグに変換されてしまうのです。

    一旦投稿した後、気づいて編集はしたのですが、遅かったようです。。。

  30. dogante
    メンバー
    4 ヶ月前の投稿 #

    jim912さん
    ご返答、ありがとうございました。

    jim912さんのご指摘を受け、上記の編集を適用後jim912さんのクラス化する前のコード及びクラス化後のコードを再度両方ためしているのですが、クラス化した後のコードはご指摘の修正で動作するようになりました。

    しかし、jim912さんの上記でご指摘の修正後、クラス化する前のコードをfunctions.phpに記述してサーバのテーマ内にアップロードすると、以前と同じでサイトが何も表示されなくなります(ブラウザーの表示は、真っ白)。

    念のため、現在検証中のクラス化する前のコード(jim912さんの上記のご指摘を適用後のコード)を以下へ張っておきます(動作しないコードです。)。
    クラス化する前のコード(以下):

    <?php
    function check_home_page() {
    	global $wpdb;
    
    	$home_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    	if ( $home_id ) {
    		add_filter( 'pre_option_show_on_front', 'set_page_show_on_front' );
    		add_filter( 'pre_option_page_on_front', 'set_home_page_on_front' );
    	}
    }
    
    function set_page_show_on_front( $pre ) {
    	return 'page';
    }
    
    function set_home_page_on_front( $pre ) {
    	return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" );
    }
    
    add_action( 'init', 'check_home_page' );
    ?>

    どこか、まだ不適当な部分などありますでしょうか(こちらでも念入りに確認はしているのですが、わかりません。)?

    ところで、一つお尋ねしたいのですが、現在動作しているクラス化後のコードをfunctions.phpに記述してサーバにアップロード後、WPの管理画面でページを3つ作成するとします。一つ目のページのタイトルは「ホーム」、二つ目のページのタイトルは「ページ2」、三つ目のページのタイトルは「ページ3」とします。ページは、全てindex.phpのみで出力されています。

    そして以下のようなコードでページタイトルのリストを表示すると
    <?php wp_page_menu('sort_column=menu_order & show_home=1'); ?>
    以下のようにブラウザーに出力されます。
    ●ホーム←トップページと固定ページが同じページとして出力されている
    ●ページ2
    ●ページ3

    その後、管理画面の「ページ」→「編集」画面でページタイトルが「ホーム」のページを削除するとします。そして再び以下のようなコードでページタイトルのリストを表示すると
    <?php wp_page_menu('sort_column=menu_order & show_home=1'); ?>
    以下のようにブラウザーに出力されます。
    ●ホーム←固定ページは削除され、トップページのみが出力されている
    ●ページ2
    ●ページ3

    この場合、
    <?php wp_list_pages('sort_column=menu_order & depth=1 & title_li='); php>
    などで表示すると以下のように「●ホーム」は表示されないため、固定ページは削除されており、wp_page_menuの場合に表示される「●ホーム」はトップページであるのが分かります。
    ●ページ2
    ●ページ3

    しかし、なぜページタイトルが「ホーム」の固定ページが管理画面の「ページ」→「編集」画面で削除された後もトップページのタイトルは「ホーム」のまま残るのでしょうか?一旦、固定ページのタイトルがトップページのタイトルに適用された後は、それが別のページタイトルで上書きされるまで、トップページのタイトルはそのまま(当該の固定ページが削除されても)データベースに保管され続けるということですか?

    なお、上記の現象によるWP使用上の不都合は現在のところありません。また、jim912さんのコードをしようせず、代わりに管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] で「ホーム」というページタイトルのページをフロントページに選択した場合も上記と同じ現象は起こりますので、jim912さんのコードがおかしいというわけでもないと思います。ただ、少し疑問に思ったのでお尋ねしました。

    理由をご存知であれば、ご教授いただければ幸いです。

    よろしくお願いします。

返信 »

ログイン しなければ投稿できません。

About this Topic

Tags

タグ はまだありません。