Одно тело и 2 конструкции цикла. Как?

Ewsen

Гуру форума
Регистрация
26 Июл 2008
Сообщения
163
Реакции
59
Практически не имея знаний в PHP я намудрил такое
PHP:
if ( условие ) {
	while ( $cat_posts->have_posts() )
	{
		$cat_posts->the_post();
                // тело цикла
        }
} else {
        foreach ($cat_posts as $post){
                setup_postdata($post);
                // тело цикла
}
}
// тело цикла(одинаковое) - Достаточно большой кусок кода. Можно ли как-то сделать, чтобы тело цикла в коде было 1 раз, но применялось в разных конструкциях цикла.

Или может другой вариант:
в первом случае while ( $posts->have_posts() )
$cat_posts формируется таким запросом
PHP:
$cat_posts = new WP_Query ...
Я не могу понять что это за тип данных и как его можно перевести в массив, чтобы можно было использовать только только одну конструкцию цикла foreach ($cat_posts as $post)
 
Я не могу понять что это за тип данных и как его можно перевести в массив, чтобы можно было использовать только только одну конструкцию цикла foreach ($cat_posts as $post)
это стандартный запрос вордпресса

вообще в вп содержится куча готовых функций, которые покрывают 80-90% потребностей начинающих разработчиков - возможно для вашей задачи уже существует готовый велосипед?
попробуйте в гугле вбить codex wordpress

// тело цикла(одинаковое) - Достаточно большой кусок кода. Можно ли как-то сделать, чтобы тело цикла в коде было 1 раз, но применялось в разных конструкциях цикла.

можно предположить что вы хотите сделать для одних рубрик/страниц один вывод инфы, а для других - другой
это можно сделать гораздо проще без условий - просто вписав код в разных файлах - например index.php и category.php
 
это стандартный запрос вордпресса
вообще в вп содержится куча готовых функций, которые покрывают 80-90% потребностей начинающих разработчиков - возможно для вашей задачи уже существует готовый велосипед?
попробуйте в гугле вбить codex wordpress

можно предположить что вы хотите сделать для одних рубрик/страниц один вывод инфы, а для других - другой
это можно сделать гораздо проще без условий - просто вписав код в разных файлах - например index.php и category.php

У меня есть многофункциональная тема для ВП со своими виджетами в functions.php Там очень удобно настраивается вывод постов с превью (за отображение отвечает тело цикла и оно большое, т. к. там предусмотрен вывод в несколько колонок, с тайтлом/без, с превью/без, дата, автор, описание и т.п.:(
-вывод новых
-вывод новых из категории
-вывод новых текущей категории
-рандомный вывод
и все это до цикла с выводом собирается запросом
PHP:
$cat_posts = new WP_Query ...
проблема этого в том что всегда происходит сортировка постов либо по возрастанию либо по убыванию
Но я хочу сделать еще вывод похожих новостей который очень умно выводит предидущие посты из текущей категории, а если их не хватает, то добирает первые из той же категории и при этом сортировки не происходит. То что мне и надо.
Вот эта функция, которая возвращает массив с нужными постами:
PHP:
function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num) {

$num = 0;
global $wpdb;

$sql = "SELECT wposts.*
FROM $wpdb->posts wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = '$the_category_id'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
AND wposts.ID < '$the_post_id'
ORDER BY wposts.ID DESC
LIMIT $post_num";

$result = $wpdb->get_results($sql, OBJECT);
global $post;

foreach ($result as $post) {
setup_postdata($post);
$cat_posts[] = $post;
$num++;
$save_ids[] = $post->ID;
}
if ( $num < $post_num || !$result ) {
$need_more = $post_num-$num;
$save_ids[] = $the_post_id;
$save_ids = join (',', $save_ids);
$more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
foreach ($more_posts as $post){
setup_postdata($post);
$cat_posts[] = $post;
}
}
return $cat_posts;
}

Вопрос только как сделать чтобы при одном условии в цикле выводить посты собранные этой функцией, а при другом
PHP:
$cat_posts = new WP_Query ...

На этом сайте как раз рассмотрены 2 способа вывода похожих записей как у меня

В каждом из способов использованы разные конструкции циклов (в первом foreach ($more_posts as $post), во втором while ($my_query->have_posts())), а тело вывода постов можно сказать одинаковое (<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>)

Только в моем случае тело вывода постов намного сложнее. Вот я и хочу объединить эти 2 способа поставив условие для применения одного или другого при этом тело цикла для вывода постов применить в коде 1 раз
 
Звучит глупо, но нельзя ли вынести тело обоих циклов в функцию раз оно одинаковое?
 
Звучит глупо, но нельзя ли вынести тело обоих циклов в функцию раз оно одинаковое?
Вот что значит перемудрил... Как я раньше до этого не додумался. Это то что надо. Спасибо
 
проблема этого в том что всегда происходит сортировка постов либо по возрастанию либо по убыванию
проблема этого в том что вы элементарно ленитесь последовать совету

если бы вбили в гугле фразу codex wordpress (или wordpress codex), то уже знали бы что в WP_Query() можно использовать кучу аргументов, например
PHP:
$query = new WP_Query( 'author=123' );
выведет посты чувака с ником 123
PHP:
$query = new WP_Query("cat=4&orderby=rand");
выведет рандомно посты из категории с ид 4
и так далее (примеры оттуда)...

а если желаете пользоваться "своей" функцией - то в вашем примере сортировка это ORDER BY wposts.ID DESC
можете просто ее менять в зависимости от условий - к примеру ORDER BY wposts.post_date DESC отсортирует по дате, а "волшебное" слово RANDOM дернет посты без сортировки
 
Здесь я не соглашусь. Я перечитал информацию отсюда
WP_Query не заменит эту функцию
PHP:
<?php
function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num) {
 
$num = 0;
global $wpdb;
 
$sql = "SELECT wposts.*
FROM $wpdb->posts wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = '$the_category_id'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
AND wposts.ID < '$the_post_id'
ORDER BY wposts.ID DESC
LIMIT $post_num";
 
$result = $wpdb->get_results($sql, OBJECT);
global $post;
?>
<ul>
<?php
foreach ($result as $post) {
setup_postdata($post);
?>
<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
$num++;
$save_ids[] = $post->ID;
}
if ( $num < $post_num || !$result ) {
$need_more = $post_num-$num;
$save_ids[] = $the_post_id;
$save_ids = join (',', $save_ids);
$more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
foreach ($more_posts as $post){
setup_postdata($post);
?>
<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
}
}
?>
</ul>
<?php } ?>
 
<?php
$the_cat = get_the_category();
$the_cat_id = $the_cat[0]->cat_ID;
show_previous_posts_from_category($post->ID, $the_cat_id, 5);
wp_reset_query();
?>
т. к. она выводит именно предидущие посты
PHP:
AND wposts.ID < '$the_post_id'
а если их не хватает, то добирает из той же категории
PHP:
$more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
и при этом не сортирует полученный массив

В итоге в похожих новостях не будет мелькать постоянно свежая новость из категории
 
Назад
Сверху