Wordpress Wp_query object with 2 posts prints only one - php

I need to display the latest post from 3 categories and two posts from this last one with another HTML formatting. The problem is the last category prints only one post and stops with a var_dump() on the object I can see the two posts.
Check the functions here:
function destaques( $atts ) {
extract( shortcode_atts( array(
'id' => 0,
), $atts ) );
$id = array(6,16,10,4);
$posts = array();
$nomesCat = array();
foreach ($id as $key => $value) {
if ($value == 4){
//this is the categorie with two posts
$posts[] = new WP_Query( array('posts_per_page' => 2, 'category__in' => array($value)));
} else {
$posts[] = new WP_Query( array('posts_per_page' => 1, 'category__in' => array($value)));
}
$nomesCat[] = get_category($value);
}
$html = '<ul class="destaques">';
foreach ($posts as $key => $value) {
if ($value->have_posts()){
while($value->have_posts()){
$value->the_post();
if ($nomesCat[$key]->cat_name == 'Colunistas') {
// check for the categorie name, then call another
// function, passing the wp_query object
$html .= auxiliarColunistas($value);
break;
} else {
//lots of html formatting code
$html .= '</li>';
}
}
}
}
$html .= '</ul>';
return $html;
This is the helper function:
function auxiliarColunistas ($posts) {
$html = '<li class="last">';
/*var_dump($posts); this returns two posts!
die;*/
$html .= '<h2>Colunistas</h2>';
if ($posts->have_posts()){
while ($posts->have_posts()) {
$posts->the_post();
//more html formatting code
}
}
$html .= '</li>';
return $html; }
Why does the loop print just one post and stops?

Try doing it like this
foreach ($id as $key => $value) {
if ($value == 4){
//this is the categorie with two posts
$posts_query = new WP_Query( array('posts_per_page' => 2, 'category__in' => array($value)));
} else {
$posts_query = new WP_Query( array('posts_per_page' => 1, 'category__in' => array($value)));
}
$nomesCat[] = get_category($value);
}
$html = '<ul class="destaques">';
while($posts_query->have_posts()){
if ($nomesCat[$key]->cat_name == 'Colunistas') {
// check for the categorie name, then call another
// function, passing the wp_query object
$html .= auxiliarColunistas($posts_query->the_post());
break;
} else {
//lots of html formatting code
$html .= '</li>';
}

I could solve it changing this line:
if ($value == 4){
//this is the categorie with two posts
$posts_query = new WP_Query( array('posts_per_page' => 2, 'category__in' => array($value)));
to
if ($value == 4){
//this is the categorie with two posts
$posts_query = new WP_Query( array('posts_per_page' => 3, 'category__in' => array($value)));
but I still don't understand why the while loop is not getting the last post.

Related

How to display an alphabetically sorted list of post withe Php (WordPress )

I would like to create a glossary overview page on wordpress via PHP, which can be used via a shortcode. I would like that always the initial letter is displayed and then the individual topics (posts) which begin with this.
Example:
A
Apple
Apricot
B
Banana
Blackberry
and so on...
To implement this I use the following code:
// get glossary
function glossary($post_id) {
$all_posts = new WP_Query(
array(
'posts_per_page' => -1,
'post_type' => 'glossar',
'orderby' => 'title',
'order' => 'ASC',
));
echo '<ul>';
if( $all_posts->have_posts()){
foreach( range( 'A', 'Z' ) as $letter ) {
echo '<div class="group_letter"><div class="letter">' . $letter. '</div>';
while( $all_posts->have_posts() ){
$all_posts->the_post();
$title = get_the_title();
$name = get_post_field( 'post_name', get_post() );
$initial = strtoupper( substr( $title, 0, 1 ) );
if( $initial == $letter ){
echo '<li><a class="glossary-listing" href="/glossar/'. $name . '">' . $title . '</a></li>';
}
}
$all_posts->rewind_posts();
}
}
echo '</ul>';
}
add_shortcode( 'glossary', 'glossary' );
So far it works, but now it shows letters for which there are no posts. This is how it looks now
I have tried to do it with an if query, but so far, I am stuck. Can someone help me?
Best regards and thank you!
Sort the array using PHP sort() function then loop through the result
<?PHP
$list=['apples','popsicles','Zinger','donkeys','bananas','joe',
'Locusts','gazelles','Angels','Popsicle','Dongle','jump','cocoa'
];
//convert all elements to same case
//sorting will sort by case
$list =array_map('strtolower', $list);
//sort the array
sort($list);
$last_letter=null;
foreach($list as $item){
$current_letter=substr($item,0,1);
if($last_letter!=$current_letter){
?>
<div style="margin:1rem;padding:1rem;background:#f5f5f5;">
<?=$current_letter?>
</div>
<?php
$last_letter=$current_letter;
}
?>
<div style="margin:1rem;padding:1rem;background:#f5f5f5;">
<?=$item?>
</div>
<?PHP
}
?>
I am sure there is a better solution besides running 26 times through the while loop. Anyway, here is what you are looking for.
// get glossary
function glossary($post_id) {
$all_posts = new WP_Query(
[
'posts_per_page' => -1,
'post_type' => 'glossar',
'orderby' => 'title',
'order' => 'ASC',
]
);
echo '<ul>';
if ($all_posts->have_posts()) {
foreach (range('A', 'Z') as $letter) {
$foundPostable = false;
while ($all_posts->have_posts()) {
$all_posts->the_post();
$title = get_the_title();
$name = get_post_field( 'post_name', get_post() );
$initial = strtoupper(substr($title, 0, 1));
if ($initial === $letter) {
if ($foundPostable === false) {
$foundPostable = true;
echo '<div class="group_letter"><div class="letter">' . $letter. '</div>';
}
echo '<li><a class="glossary-listing" href="/glossar/'. $name . '">' . $title . '</a></li>';
}
}
$all_posts->rewind_posts();
}
}
echo '</ul>';
}
add_shortcode( 'glossary', 'glossary' );
As for improvement, something like this might work as well.
// get glossary
function glossary($post_id) {
$all_posts = new WP_Query(
[
'posts_per_page' => -1,
'post_type' => 'glossar',
'orderby' => 'title',
'order' => 'ASC',
]
);
echo '<ul>';
$startLetter = '';
while ($all_posts->have_posts()) {
$all_posts->the_post();
$title = get_the_title();
$name = get_post_field( 'post_name', get_post() );
$initial = strtoupper(substr($title, 0, 1));
if ($initial !== $startLetter) {
$startLetter = $initial
echo '<div class="group_letter"><div class="letter">' . $letter . '</div>';
}
echo '<li><a class="glossary-listing" href="/glossar/'. $name . '">' . $title . '</a></li>';
}
echo '</ul>';
}
add_shortcode('glossary', 'glossary');

how to show all testimonial on single page via shortcode in wordpress?

i have created shortcode to show all testimonial on one page.
i have created custom post type to add each testimonial.
can anybody tell me how to show all testimonial on single page .
this code is used to create sshortcode
below i m mentioning code :-
function fn_testimonials_block()
{
$args = array(
'post_type'=> 'testimonials',
'order' => 'ASC'
);
$the_query = new WP_Query( $args );
$pages = $the_query->posts;
//echo "<pre>";
//print_r($pages);
//echo "</pre>";
//exit;
$output = '';
$count = 1;
foreach($pages as $page) {
//-----------------
$author = $page->post_title;
$testimonial = $page->post_content;
$page_url = get_page_link( $page->ID );
$author_image = get_the_post_thumbnail_url( $page->ID, 'thumbnail' );
if ($count%2 == 1)
{
$output .= '<div>';
}
$output .= '<div>
<p>'.$testimonial.'<br>
<img src="'.$author_image .'"> <span>'.$author.', </span></p>
</div>';
if ($count%2 == 0)
{
$output .= '</div>';
}
$count++;
}
if ($count%4 != 1){
$output .= '</div>';
}
return $output;
}
I think you will have to pass 'posts_per_page' key in $args array. So your $args array will look like this
$args = array(
'post_type'=> 'testimonials',
'order' => 'ASC',
'posts_per_page' => '-1'
);
I am not sure about the $count variable you are using. I suppose you are trying to implement logic for pagination there but since your question is about showing all testimonials on single page, I won't get into that part.
Making changes in $args will return all testimonials objects.

How to query the first 2 posts in this function but call them separately?

Can someone show me how to add 2 posts separately using a single query? For example when calling the code: { $content_block[2] .= (fphp_get_related_posts() ); show a post, then { $content_block[4] .= (fphp_get_related_posts() ); show the next post (offset by 1). How can I do this?
At the moment I know I have set 'max' => '1' I'm no php warrior, I was thinking you could 'max' => '2' and call each post like this: (fphp_get_related_posts(1) or (fphp_get_related_posts(2) but that is not right..
//Insert Related Posts Into Content Function
add_filter('the_content', 'mte_add_incontent_post');
function mte_add_incontent_post($content)
{ if(is_single()){
$content_block = explode('<p>',$content);
if(!empty($content_block[2]))
{ $content_block[2] .= (fphp_get_related_posts() );
}
if(!empty($content_block[4]))
{ $content_block[4] .= (fphp_get_related_posts() );
}
for($i=1;$i<count($content_block);$i++)
{ $content_block[$i] = '<p>'.$content_block[$i];
}
$content = implode('',$content_block);
}
return $content;
}
function fphp_get_related_posts($atts) {
$atts = shortcode_atts( array(
'max' => '1',
), $atts, 'relatedposts' );
$reset_post = $post;
global $post;
$post_tags = wp_get_post_tags($post->ID);
if ($post_tags) {
$post_tag_ids = array();
foreach($post_tags as $post_tag) $post_tag_ids[] = $post_tag->term_id;
$args=array(
'tag__in' => $post_tag_ids,
'post__not_in' => array($post->ID),
'posts_per_page' => $atts['max'],
'orderby' => 'DESC'
);
$related_query = new wp_query( $args );
if (intval($related_query->post_count) > 0) {
$html = '<div class="related_post"><b>SEE ALSO:</b>';
while( $related_query->have_posts() ) {
$related_query->the_post();
$html .= '<a rel="external" href="'. get_the_permalink(). '">';
$html .= get_the_title() . '</a>';
}
}
$post = $reset_post;
wp_reset_query();
$html .= '</div>';
return $html;
}
}
Would appreciate your help so I can understand how to do this.

Insert a post type every x posts in custom loop

I was hoping someone could help me with this problem.
I'm trying to make a loop in wordpress with two different post types ('product' and 'outfits')
The code below is working fine, this outputs a list of the two post types ordered by newest to older.
$loop = new WP_Query( array(
'post_type' => array( 'product', 'outfits' ),
'posts_per_page' => 15
) );
$counter = 0;
?>
<?php if ( $loop->have_posts() ) { while ( $loop->have_posts() ) { $loop->the_post();
$counter++; ?>
<?php $loop->is_home = false; ?>
<?php
$large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large');
$titulo = get_the_title();
$content = apply_filters ('the_content', $post->post_content); ?>
<div class="caja-<?php echo $counter; ?>">
<?php if ( $post->post_type == "product" ) {
//some stuff
<?php } else {
//some stuff
} ?>
</div>
<?php } } wp_reset_postdata();
What I would like to do is to insert a product post type after X number of outfits.
I was trying to merge a similar solution I've found in other question with no luck. I'm not a php expert so any help is appreciated
<?php
$args = array('post_type'=>'post', 'posts_per_page'=>9, 'category_name'=>'news');
$posts = get_posts($args);
$args = array('post_type'=>'testimonials', 'posts_per_page'=>3);
$testimonials = get_posts($args);
// see how many of the regular posts you got back //
$post_count = count($posts);
// see how many testimonials you got back //
$testimonial_count = count($testimonials);
// add them up to get the total result count //
$total_count = $post_count + $testimonial_count;
// Loop through the total number of results //
for($i = 1; $i <= $total_count; $i++){
// assuming you want to show one testimonial every third post //
if($i % 3 == 0){
// this means you're on the a third post, show a testimonial //
setup_postdata($testimonials[$i]);
}
else{
/** show a regular post */
setup_postdata($posts[$i]);
}
/** and now handle the output */
?><h1><?php the_title();?></h1><?php
} ?>
$x = 3;
$products = get_posts(array(
'post_type' => 'product',
'posts_per_page' => -1
));
$outfits = get_posts(array(
'post_type' => 'outfit',
'posts_per_page' => -1
));
foreach ($outfits as $num => $outfit) {
if ( ($num+1) % $x == 0) {
if (isset($products[($num+1)/$x - 1])) {
array_splice( $outfits, $num, 0, array($products[($num+1)/$x - 1]) );
}
}
}
foreach ($outfits as $outfit) {
$posts_id[] = $outfit->ID;
}
$query = new wp_query(array(
'post_type' => array('outfit', 'product'),
'post__in' => $posts_id,
'posts_per_page' => 15,
'orderby' => 'post__in'
));

cycle next page wordpress order by post title

I'm using Cycle jquery for my website.
I've added a php code do get a link at the end of my slideshow to go to the next page.
I want my pages to be sorted alphabetically but it's not working...
I've added "orderby=post_title" but still not working...
anybody can help me with this ?
here is my PHP code :
function dbdb_next_page_link() {
global $post;
if ( isset($post->post_parent) && $post->post_parent > 0 ) {
$children = get_pages('&orderby=menu_order&order=ASC&child_of='.$post->post_parent.'&parent='.$post->post_parent);
}
//print_r($children);
// throw the children ids into an array
foreach( $children as $child ) { $child_id_array[] = $child->ID; }
$next_page_id = relative_value_array($child_id_array, $post->ID, 1);
$output = '';
if( '' != $next_page_id ) {
$output .= ''. get_the_title($next_page_id) . ' ยป';
}
return get_page_link($next_page_id);
}
and a jsfiddle link : http://jsfiddle.net/KvBRV/
....
I have the same problem with a "select type" menu, my pages are not sorted alphabetically, I don't know why, here is my php code :
<div class="styled-select">
<?php
if(!$post->post_parent){
$children = get_pages(array(
'child_of' => $post->ID,
'post_type' => 'page',
'post_status' => 'publish',
'sort_order' => 'ASC',
'sort_column' => 'post_title',
));
}else{
$children = get_pages(array(
'child_of' => $post->post_parent,
'post_type' => 'page',
'post_status' => 'publish',
'sort_order' => 'ASC',
'sort_column' => 'post_title',
));
}
if ($children) {
echo '<select name="" onchange="location = this.options[this.selectedIndex].value;">';
echo '<option>'. 'A - Z' .'</option>';
function getInitials($name){
//split name using spaces
$words=explode(" ",$name);
$inits='';
//loop through array extracting initial letters
foreach($words as $word){
$inits = strtoupper(substr($word,0,1));
break;
}
return $inits;
}
$currval = "";
foreach($children as $child){
//print_r($child);
$permalink = get_permalink($child->ID);
$post_title = strtoupper($child->post_title);
$initial = getInitials($child->post_title);
if($initial!='' && $currval != $initial ) {
$currval = $initial;
echo '<optgroup label="'.$initial.'""></optgroup>';
}
echo '<option value="'.$permalink.'">'.$post_title.'</option>';
}
echo '</select>';
} ?>
<!-- FIN MENU DEROULANT A-Z -->
</div>
and a jsfiddle link : http://jsfiddle.net/Zp3Lt/
thanks a lot for your help !
Mattieu
get_pages doesnt accept any arg called orderby or order instead sort_column and sort_order is used ..
so your code would be
if ( isset($post->post_parent) && $post->post_parent > 0 ) {
$children = get_pages('sort_column=post_title&sort_order=ASC&child_of='.$post->post_parent.'&parent='.$post->post_parent);
}
Refer Here
Get Pages

Categories