私は私が以下を印刷することを可能にする解決策を探しています:
Cat 1 Cat 2 Cat 3
Post 1 Post 1 Post 1
Post 2 Post 2 Post 2
Post 3 Post 3
Post 4
_編集_
one databaseクエリだけが必要なものを探しています。あなたのコードにforeach
とそれに続くnew WP_Query
があるなら、それは私が探しているものではありません(私はこれを私のウェブサイトのホームページに載せることを計画しています)。
EDIT REVISIT NO 2
私が_MikeSchinkelで この記事 の中で答えを見たときまで、私は Transient API に触れたことがありませんでした。これは私がもう一度この記事を見直すように促しました。いくつかのテストの後、私は以下のことを思いついた。
実行時間が約0.07秒から約0.002秒に減少しました
データベースのクエリ時間が約半分になりました
一時的には、2 dbクエリだけが実行されます。
コードのしくみ( _ revisit _ の元のコードからの変更点について説明します)。
ステップ1
$q
の値を一時的なものに保存する必要があります。これは投稿タイトルのあるカテゴリリストを保持する値です。
ステップ2
まずトランジェントが存在するかどうかを確認し、存在しない場合はトランジェントを作成します。トランジェントが存在する場合は、その情報を取得します
ステップ3
この情報はforeach
ループを介して渡され、カテゴリ名と投稿タイトルを含むリストを印刷します。
ステップ4
現状では、トランジェントは12時間ごとに更新されます。これはニーズに合わせて設定できます。ただし、投稿のステータスが変わるたびにトランジェントを削除して再作成する必要があります。これはドラフトからパブリッシュ、パブリッシュされている新しい投稿、またはゴミ箱に入れられている投稿のいずれかです。これを行うには、投稿のステータスが変化するたびにトリガーされるdelete_transient
にフックされる transition_post_status
を使用する必要があります。
これが完全なコードです。
Functions.phpで
add_action( 'transition_post_status', 'publish_new_post', 10, 3 );
function publish_new_post() {
delete_transient( 'category_list' );
}
あなたのテンプレートであなたがあなたのリストを表示する必要があるところ
<?php
if ( false === ( $q = get_transient( 'category_list' ) ) ) {
$args = array(
'posts_per_page' => -1
);
$query = new WP_Query($args);
$q = array();
while ( $query->have_posts() ) {
$query->the_post();
$a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';
$categories = get_the_category();
foreach ( $categories as $key=>$category ) {
$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';
}
$q[$b][] = $a; // Create an array with the category names and post titles
}
/* Restore original Post Data */
wp_reset_postdata();
set_transient( 'category_list', $q, 12 * HOUR_IN_SECONDS );
}
foreach ($q as $key=>$values) {
echo $key;
echo '<ul>';
foreach ($values as $value){
echo '<li>' . $value . '</li>';
}
echo '</ul>';
}
?>
_再訪問_
私は最近、与えられた他の可能な解決策よりはるかに速い非常に軽量の解決策を思いつきました。私のテストサイトでは、 Query Monitor によると、合計生成時間はたったの0.07秒で、6 dbクエリしかありませんが、他の方法では、生成時間は0.35秒〜50 db余分なクエリになります。
これが私の方法の内訳です。
ステップ1
最初にすべての公開された投稿を取得するために WP_Query
でカスタムクエリを作成する必要があります
$args = array(
'posts_per_page' => -1
);
$query = new WP_Query($args);
$q = array();
while ( $query->have_posts() ) {
}
/* Restore original Post Data */
wp_reset_postdata();
ステップ2
get_the_category
を使用して、投稿が属するすべてのカテゴリのリストを取得します。
$categories = get_the_category();
foreach ( $categories as $key=>$category ) {
$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';
}
ステップ3
投稿のタイトルと投稿のカテゴリに変数を割り当てる
$a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';
そして
$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';
ステップ4
これら2つの変数を組み合わせて多次元配列を形成します
$q[$b][] = $a;
配列で何が起こっているのかを見るためには、単にvar_dump
を実行してください。
?><pre><?php var_dump($q); ?></pre><?php
ステップ5
foreach
ループを使用して、カテゴリ別に投稿リストを作成する
foreach ($q as $key=>$values) {
echo $key;
echo '<ul>';
foreach ($values as $value){
echo '<li>' . $value . '</li>';
}
echo '</ul>';
}
すべて一緒に今すぐ!
これが完全なコードです。
<?php
$args = array(
'posts_per_page' => -1
);
$query = new WP_Query($args);
$q = array();
while ( $query->have_posts() ) {
$query->the_post();
$a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';
$categories = get_the_category();
foreach ( $categories as $key=>$category ) {
$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';
}
$q[$b][] = $a; // Create an array with the category names and post titles
}
/* Restore original Post Data */
wp_reset_postdata();
foreach ($q as $key=>$values) {
echo $key;
echo '<ul>';
foreach ($values as $value){
echo '<li>' . $value . '</li>';
}
echo '</ul>';
}
?>
この質問から派生した私のソリューションを追加したいだけです 私は持っていました。これにより、カテゴリのクエリがキャッシュされ、各カテゴリの投稿コンテンツを含む投稿もキャッシュされます。初めてキャッシュがいっぱいになったときには通常のデータベースクエリがありますが、いっぱいになるとキャッシュされたカテゴリと投稿が配信されるため、これ以上データベースクエリは行われません。
// Transients API all categories and all posts
$query_categories = get_transient('cached_categories');
if ( false === $query_categories){
$args_cat = array(
// order by category name ascending
'orderby' => 'name',
'order' => 'ASC',
// get only top level categories
'parent' => 0
);
// Instead of caching a WP Query I cache 'get_categories()'.
$query_categories = get_categories($args_cat);
// var_dump($query_categories);
set_transient('cached_categories', $query_categories, DAY_IN_SECONDS );
}
// Full posts query
// if there are categories filled with posts
if (!empty ($query_categories) && !is_wp_error( $query_categories )) {
foreach ($query_categories as $category) {
// var_dump($category);
$query_category_posts = get_transient('cached_posts_' . $category->slug );
if ( false === $query_category_posts ){
// Query all posts by slug inside each category
$args_category_posts = array(
'post_type' => 'post',
// The category slug and category name we get from the foreach over all categories
'category_name' => $category->slug
);
// Here I cache the WP_Query, though this runs for all categories.
// Because of that the '$category->slug' is used to serve a string and not an object.
$query_category_posts = new WP_Query($args_category_posts);
set_transient( 'cached_posts_' . $category->slug , $query_category_posts, DAY_IN_SECONDS );
}
if ($query_category_posts->have_posts()) {
while ($query_category_posts->have_posts()) {
$query_category_posts->the_post(); ?>
<article class="<?php echo $category->slug ?>-article">
<h2 class="<?php echo $category->slug ?>-article-title">
<a href="<?php echo get_permalink() ?>"><?php echo get_the_title() ?></a>
</h2>
<p class="<?php echo $category->slug ?>-post-info">
<?php the_time('d. m. Y') ?>
</p>
<div <?php post_class() ?> >
<?php the_content(); ?>
</div>
</article> <?php
}
} // end loop
} // end foreach
wp_reset_postdata() ;
} // end if there are categories filled with posts
今すぐこのコードを試してください
$cat_ids=array();
foreach (get_categories() as $cat)
{
array_Push($cat_ids, $cat->cat_ID);
}
$the_query = new WP_Query(array('post_type'=>'post', array('category__and' => $cat_ids) ) );
if( $the_query->have_posts() ):
while ( $the_query->have_posts() ) : $the_query->the_post();
echo the_title();
endwhile;
endif;
wp_reset_query();