WordPressのデフォルトの仕様では、home.phpがトップページ?
-
WordPress2.8.4を、ブログとしてではなく、通常サイトのCMSとして使用するためにカスタマイズしています。私が現在行っているのは “存続 のテンプレート(他人が作成したテンプレート)をカスタマイズする作業ではありません。”今回の場合、私がテンプレートをほぼ初期の状態から作成していま す。
WordPressのデフォルトの仕様(管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していない状態)では、サイトのルートURL(例:http://example.com/)にブラウザでアクセスするとまずhome.phpを探して、home.phpが存在すればその内容をサイトのトップページとして表示する仕組みになっているのでしょうか?
この場合、home.phpに以下の例ような固定ページとしての記述をすれば、home.phpを固定ページとし(管理画面の「ページ」→「新規追加」より入力した記事を表示し)、かつ、サイトのトップページとして固定できるのでしょうか(管理画面の[設定]→[表示設定]→[フロントページの表示]項目→[固定ページ] でトップページを指定していないことが前提です。)?
固定ページとしての記述 例:<?php
/*
Template Name: 固定ページ
*/
?>よろしくお願いします。
-
spreadhappinessさん
ご教授、ありがとうございました。全然違う方向に行ってしまっていました。
いろいろ勉強したいと思っているのですが、なかなか何から手をつけて、どのようにすればよいのかがわからなかった状態です。つまり、jim912さんがおっしゃっていることは、「簡単なプラグインを作成してはどうか」 と言うことですね?私は、てっきりテーマ自身のファイル又はWPのコアファイルを改造することを指摘されているものだとばかり思っていました。
doganteさん
こんばんは。
私は、てっきりテーマ自身のファイルを改造することを指摘されているものだとばかり思っていました。
いえいえ。テーマでいいと思いますよ。
WordPressは結構何でもできちゃうところが、
わかりにくかったりするところなのかなぁとも思います・・・。マニュアルでは確かにプラグインAPIとして書かれているのですが、
フックは別にテーマ内のソースから呼んでも全く問題ありません。私の知っている範囲では、atahualpaというテーマなんかは、
テーマ内でいろいろやってますよ。
参考になるところもあるんじゃないかと思います。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もしよろしければ、私は何をすればよいのか、方向性をもう少し噛み砕いて教えていただければ大変助かります(かなりこんがらがって、わからなくなっています。)。
よろしくお願いします。
spreadhappinessさん
ご回答、ありがとうございました。マニュアルでは確かにプラグインAPIとして書かれているのですが、
フックは別にテーマ内のソースから呼んでも全く問題ありません。テーマ内のソースからフックを呼ぶ場合、今回の場合はテーマ内のindex.php内にフックを記述すればよいのでしょうか(今回はheader.php又はfooter.phpを使用していません。)?また、index.php内にフックを記述する場合、フックはindex.phpの<header></header>内に記述するものですか?
よろしくお願いします。
jim912さんのおっしゃっている「initあたりのフックで」の意味がよく分からないのですが、spreadhappinessさんからご教授いただいたことを参考にすると
init(‘option_show_on_front’, ‘自分で作成する関数名’);
init(‘option_page_on_front’, ‘自分で作成する関数名’);などのフックをテーマ内の上記でお尋ねしているファイル(テーマ内のどのファイルのどの部分に記述するのか分からない状態です。)に記述すれば良いということですか?
よろしくお願いします。
doganteさん
フックはindex.phpの<header></header>内に記述するものですか?
テーマ内のfunctions.phpに記述することになるんじゃないでしょうか?
もしよろしければ、私は何をすればよいのか、方向性をもう少し噛み砕いて教えていただければ大変助かります。
atahualpaというテーマのソースコードを追っかけてみてはどうでしょうか?
方向性が見えるかもしれませんよ。
(もちろん、WordPressのソースコードも追っかけてみては?)P.S.
私もWordPressを触りだして日が浅いので勉強の日々です。
オープンソースは色んなソースが見放題!?なので参考にできることが多く助かりますね!テーマ内に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');//記事が編集された場合のアクション ?>
どなたか査定できる方、おられます?現時点では、動作しないので方向性が正しいのかさえ不明です。
よろしくお願いします。
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に記述しておけば、思い通りの挙動になるかと思います。
jim912さん
素晴らしすぎる!!
素晴らしくわかりやすいご返答に敬服です!pre_option_~ なんですね。
option_~ だど余計なコードを実行してしまいますね。。。
勉強になりました!
ありがとうございます。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
は、コーテーションマークで囲む必要ありましたっけ?doganteさん、こんにちは。
__constructメソッドに記述してあるように
function __construct() { add_action( 'init', array( &$this, 'check_home_page' ) ); }
でクラス化への対応はしてありますです。
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さん又は誰か他の方で検証された方、おられます?
よろしくお願いします。
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タグに変換されてしまうのです。一旦投稿した後、気づいて編集はしたのですが、遅かったようです。。。
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さんのコードがおかしいというわけでもないと思います。ただ、少し疑問に思ったのでお尋ねしました。
理由をご存知であれば、ご教授いただければ幸いです。
よろしくお願いします。
doganteさん、こんにちは。
念のため、現在検証中のクラス化する前のコード(jim912さんの上記のご指摘を適用後のコード)を以下へ張っておきます(動作しないコードです。)。
またまたすみません。
function set_home_page_on_front( $pre ) { return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" ); }
に$wpdbのグローバル宣言が抜けていました。
function set_home_page_on_front( $pre ) { global $wpdb; return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'ホーム' AND post_type = 'page'" ); }
それから、画面が真っ白になってしまって何もできないようでは、後々大変ですので、開発時や不具合が発生した場合はエラーを表示させるようにすると良いです。
表示させる方法としては、.htaccessに
php_flag display_errors On
を記述するのが簡単かと思いますが、サーバによっては.htaccessでの変更を禁止している場合があります。このあたりはサーバのマニュアルを良く読んで対応方法を確認しておいてください。
wp_page_menuについては、show_home=1が指定されると、それがページでなくとも出力する仕様になっていますね。これについては、ソースを見ればわかるかと思います。wp-includes/post-template.php line808-(ver2.8.4)
- トピック「WordPressのデフォルトの仕様では、home.phpがトップページ?」には新たに返信することはできません。