私はカスタムphpページを持っています、そして私はグローバルなポスト変数を上書きする必要があります、しかし私はそれを働かせることができません。メインのループを通過するとき、グローバルな投稿を上書きすることはできませんが、countを取得するためにhave_posts()が使用しているものはすべて上書きすることはできません。私はその場でWPオブジェクトを構築してからデフォルトのクエリから返されたデフォルトのオブジェクトをオーバーライドする必要があるので、サードパーティのAPIからデータを取得しています。私は次のコードとその動作を持っていますが、問題は私が投稿を含み、その後いくつかのnullオブジェクトを含む結果を得ることです。
require_once('../../../wp-blog-header.php');
global $post, $posts, $found_posts, $post_count;
$post->ID = 99999999999;
$post->post_content = "TEST PAGE content";
$post->post_title = "Page Title";
$post->post_name = "test";
$posts = array($post);
$post_count = 1;
$found_posts = 1;
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
var_dump($post);
}
}
上記のコードは次のような出力を生成します。私はNULLを取り除く必要があります。これを行うには、have_posts()が一度だけtrueを返すようにする必要があります。
object(WP_Post)#2975(24){["ID"] => int(99999999999)["post_author"] =>文字列(1) "1" ["post_date"] =>文字列(19) "2016-01 -21 19:50:24 "[" post_date_gmt "] =>文字列(19)" 2016-01-21 19:50:24 "[" post_content "] =>文字列(17)"テストページの内容 "[" post_title "] => string(10)"ページタイトル "[" post_excerpt "] => string(0)" "[" post_status "] => string(7)" publish "[" comment_status "] => string(6) "closed" ["ping_status"] => string(6) "closed" ["post_password"] => string(0) "" ["post_name"] => string(4) "test" ["to_ping"] = > string(0) "" ["pinged"] => string(0) "" ["post_modified"] => string(19) "2016-01-21 19:50:24" ["post_modified_gmt"] => string(19) "2016-01-21 19:50:24" ["post_content_filtered"] => string(0) "" ["post_parent"] => int(0)["guid"] => string(36 ) "" ["menu_order"] => int(0)["post_type"] =>文字列(4) "ページ" ["post_mime_type"] =>文字列(0) "" ["comment_count"] =>文字列( 1) "0" ["filter"] => string(3) "raw"} NULL NULL NULL NULL NULL NULL NULL NULL NULL
これに対する解決策が$ wp_query変数にあることがわかりました。このためにグローバル変数を取得し、その中の値をオーバーライドすることで、ページに表示される内容を完全に制御することができました。これにより、wordpress以外のデータベースから取得したWP postオブジェクトを生成することができましたが、表示させるのに困難なことは何もしなくて済みました。
これを行う方法を説明したフルガイドです http://yomotherboard.com/how-to-add-a-custom-php-page-to-wordpress-using-a-プラグイン/
ここで何をする必要があるのか理解するのはかなり難しいですが、次の点を見る必要があります。
グローバル変数をローカル変数として使用しないでください。グローバル変数が破損し、ループで問題が発生します。問題に遭遇したときにデバッグすることも非常に困難です。ローカル変数として使用されるべき唯一のグローバル変数は、setup_postdata()
を扱うときです。 setup_postdata()
には$post
グローバルが必要です。あとで$post
グローバルをリセットすることを忘れないでください。
WP_Query
内で利用可能なアクションとフィルタを使用して、特定のクエリオブジェクトからの結果を変更します。
一般に、$post_count
プロパティは$posts
内の投稿数から計算されます。投稿がカウントされる直前に、the_posts
フィルタを取得します。これにより、$posts
配列からの投稿オブジェクトの追加/削除(または投稿順の並べ替え)ができます。ここで投稿数を変更すると、 `$ post_countプロパティが変更されます。
これがWP_Query
クラスの関連コードです。
if ( ! $q['suppress_filters'] ) {
/**
* Filter the array of retrieved posts after they've been fetched and
* internally processed.
*
* @since 1.5.0
*
* @param array $posts The array of retrieved posts.
* @param WP_Query &$this The WP_Query instance (passed by reference).
*/
$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
}
// Ensure that any posts added/modified via one of the filters above are
// of the type WP_Post and are filtered.
if ( $this->posts ) {
$this->post_count = count( $this->posts );
$this->posts = array_map( 'get_post', $this->posts );
if ( $q['cache_results'] )
update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
$this->post = reset( $this->posts );
} else {
$this->post_count = 0;
$this->posts = array();
}
返された投稿の配列に投稿を追加したい場合は、これを行う場所になります。
add_filter( 'the_posts', function ( $posts, \WP_Query $q )
{
if ( !$q->is_main_query ) // Only target the main query, return if not. Add any additional conditions
return $posts;
$post_to_add = [
// Valid post properties
];
$post_to_add = array_map( 'get_post', $post_to_add );
// Add some checks to make sure our $post_to_inject is a valid.
// Add $post_to_add in front of $posts array
$posts = array_merge( $post_to_add, $posts );
// If you need to replace $posts with your object
//$posts = [$post_to_add];
return $posts;
}, 10, 2 );
$post
は$posts
配列の最初の投稿から設定されるので、それをいじる必要もありません。
$found_posts
に関しては、found_posts
フィルターを使用して投稿数を調整することができます。
add_filter( 'found_posts', function ( $found_posts, \WP_Query $q )
{
if ( !$q->is_main_query ) // Only target the main query, return if not. Add any additional conditions
return $found_posts;
$found_posts = 1; // Taken info from your question
return $found_posts;
}):
私が言ったように、私はあなたがしなければならないことを特に確信していません、しかし私はあなたが後にある点に触れたことを私は望んでいました