Загрузка шаблона публикации, содержащего вложенный цикл с ajax
В настоящее время я работаю над проектом, в котором загружаю сообщение с помощью ajax. Я использую get_post() для получения сообщения, setup_postdata() для настройки данных сообщения и get_template_part() для загрузки шаблона, содержащего разметку, которую я хочу. Моя функция выглядит так:
public function get_content($url) {
global $post;
$post_id = url_to_postid($url);
if($post_id){
$post = get_post($post_id);
setup_postdata( $post );
ob_start();
get_template_part('template/page', 'default');
$content = ob_get_contents();
ob_end_clean();
wp_reset_postdata();
return array('status' => 'success', 'content' => $content);
} else {
return array('status' => 'error','message'=> 'Fant ikke post til relevante url..');
}
die();
}
Мой шаблон содержит вложенный цикл для отображения меню общественного питания на основе категорий. Поэтому я использую get_categories(), чтобы получить все категории, которые имеют сообщения, а затем get_posts() для отображения сообщений для родительской категории. Мой шаблон выглядит так:
<nav class="catering-nav">
<?php
$category_args = array(
'type' => 'menus',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'catering_themes',
'pad_counts' => false
);
$categories = get_categories($category_args);
if ( $categories ) {
echo '<ul id="catering-menu" class="list-unstyled catering-menu">';
foreach ( $categories as $cat ) {
echo '<li class="has-children menu-item"><a href="' . THEME_URL . '/themes/' . $cat->slug .'/">' . $cat->name .'</a>';
$menus_arg = array(
'post_type' => 'menus',
'order' => 'ASC',
'orderby' => 'name',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'catering_themes',
'field' => 'slug',
'terms' => $cat->slug,
)
),
'posts_per_page' => -1
);
$menus = get_posts( $menus_arg );
if ( $menus ) {
echo '<ul class="list-unstyled sub-menu">';
echo '<li class="menu-item menu-item-title"><span class="catering-nav-back">Tilbake</span><span class="catering-nav-title">' . $cat->name .'</span></li>';
foreach ( $menus as $post ) : setup_postdata( $post );
echo '<li class="menu-item"><a href="' . get_the_permalink() . '">'. get_the_title() .'</a></li>';
endforeach;
wp_reset_postdata();
echo '</ul>';
}
echo '</li>';
}
echo '</ul>';
}
?>
</nav>
<!-- Title and Content from the get_post() -->
<article id="post-content">
<div class="row">
<div class="col-md-11">
<h1 class="post-title"><?php the_title(); ?></h1>
</div>
<div class="col-md-1">
<a id="content-close" class="button-close" href="#"></a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<?php the_content(); ?>
</div>
</div>
</article>
Цикл получения меню общественного питания работает отлично, но заголовок и содержимое, которые должны поступать из сообщения, загруженного с помощью get_post(), показывают данные из последнего сообщения, загруженного в цикл меню общественного питания. Знает ли какой-нибудь гений wordpress, почему это происходит?
1 answers
Ваш внутренний цикл перезаписывает содержимое $post
, поэтому любые последующие теги шаблона используют значения того, что содержалось в нем последним.
"Но я использовал wp_reset_postdata()
!" вы говорите? Что делает эта функция, так это пытается восстановить $post
из $wp_query->post
. Он предназначен для восстановления основного запроса после вторичных запросов. Здесь у вас есть два вторичных запроса, поэтому этот метод завершается неудачей.
Чтобы исправить это - либо используйте $wp_query
в качестве нового экземпляра WP_Query
для вашего внешнего цикла, что приведет к тому, что wp_reset_postdata()
будет работать должным образом, либо присвойте внешнему сообщению какое-либо другое имя переменной и не используйте теги шаблонов, которые зависят от глобального $post
.