I'm trying to achieve a 3x3 grid view of all the WordPress posts on the "blog" page (index.php). I'm building the site based on Bootstrap 3.
Therefore the loop has to create the columns and rows with PHP.
I'd like to have it set up in rows, so that potential height differences are being reset every row. The bootstrap grid would look like this:
<div class="row">
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
</div>
<div class="row">
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
</div>
<div class="row">
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
<div class="col-sm-4">content</div>
</div>
Lacking the PHP skills for setting up the loop properly, I tried hacking my way around, coming up with 3 times this (modifying the offsets):
<?php query_posts('posts_per_page=1&offset=0'); while (have_posts()) : the_post(); ?>
<div class="row">
<div class="col-sm-4 blog-post thumb">
<?php get_template_part('templates/content', get_post_format()); ?>
</div>
<?php endwhile; ?>
<?php query_posts('posts_per_page=1&offset=1'); while (have_posts()) : the_post(); ?>
<div class="col-sm-4 blog-post thumb">
<?php get_template_part('templates/content', get_post_format()); ?>
</div>
<?php endwhile; ?>
<?php query_posts('posts_per_page=1&offset=2'); while (have_posts()) : the_post(); ?>
<div class="col-sm-4 blog-post thumb">
<?php get_template_part('templates/content', get_post_format()); ?>
</div>
</div>
<?php endwhile; ?>
It has obvious disadvantages:
a lot of unnecessary PHP requests/loops
filtering by categories, tags, etc doesn't work
Could you help me out with creating the PHP loop?
The most related question I found is this, but the column layout is somehow skewed!
Thanks a lot! Philipp
The easiest would be to use one container and put all the contetn items in it, then equal their height via js like that.
PHP
<?php query_posts('posts_per_page=9');while (have_posts()) : the_post();?>
<div class="col-sm-4 blog-post thumb">
<?php get_template_part('templates/content', get_post_format()); ?>
</div>
<?php endwhile?>
JS:
function equalHeight(group) {
tallest = 0;
group.each(function() {
thisHeight = $(this).height();
if(thisHeight > tallest) {
tallest = thisHeight;
}
});
group.each(function() { $(this).height(tallest); });
}
$(document).ready(function() {
equalHeight($(".thumb"));
});
If thats no option, you could do sth. like that:
PHP
<div class="row">
<?php
$count=0;
query_posts('posts_per_page=9');
while (have_posts()) : the_post();
?>
<div class="col-sm-4 blog-post thumb">
<?php get_template_part('templates/content', get_post_format()); ?>
</div>
<?php
$count++;
if($count == 3 || $count == 6 ) echo '</div><div class="row">';
endwhile;
?>
</div>
Every three post objects must be contained within a row. So it will be like <div class="row"> <!-- post - post - post -> </div> <div class="row"> <!-- post - post - post -> </div>
If you would like to do this in php, and still maintain proper 'rowage' your code could look something like this:`
<div class="container">
<?php
$countturtle = 0 ;
$countbang = 0 ;
$count_posts = wp_count_posts( 'portobello' )->publish;
$args = array( 'post_type' => 'portobello', 'posts_per_page' => 32 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php $countbang++ ?>
<?php if ( $countbang >= 2 ) {
$countturtle = $countturtle + 1 ; } ?>
<?php if ( $countbang == 1 ) {
echo '<div class="row first-training">'; } elseif ( ( $countturtle % 3 ) == 0 ) {
echo '<div class="row">'; } ; ?>
<div id="post-<?php the_ID(); ?>" class="training-block <?php echo $countbang; ?>-block-training col-sm-4" >
<header class="entry-header training-header">
<h1 class="entry-title train">
<?php the_title(); ?>
</h1>
</header><!-- .entry-header -->
<div class="entry-imogin">
ddd
</div><!-- .entry-imogin -->
</div><!-- #post -->
<?php if ( $countbang % 3 == 0 ) {
echo '</div>'; }
elseif ( $countposts == $countbang ) { echo '</div>';} ; ?>
<?php endwhile; ?>
</div>
Here a solution for 3 columns
layout :
1 | 2 | 3
4 | 5 | 6
7 | 8 | 9
...
<div class="row">
<div class="col-sm-4">
<?php $i = 1 ?>
<?php $posts = get_posts(array(
'post_type' => 'news',
'posts_per_page' => -1
));
foreach ($posts as $post) : start_wp(); ?>
<?php if ($i == 1): ?>
<h2><?php the_title(); ?></h2>
<?php endif; ?>
<?php if($i == 3){$i = 1;} else {$i++;} ?>
<?php endforeach; ?>
</div>
<div class="col-sm-4">
<?php $i = 1 ?>
<?php $posts = get_posts(array(
'post_type' => 'news',
'posts_per_page' => -1
));
foreach ($posts as $post) : start_wp(); ?>
<?php if ($i == 2): ?>
<h2><?php the_title(); ?></h2>
<?php endif; ?>
<?php if($i == 3){$i = 1;} else {$i++;} ?>
<?php endforeach; ?>
</div>
<div class="col-sm-4">
<?php $i = 1 ?>
<?php $posts = get_posts(array(
'post_type' => 'news',
'posts_per_page' => -1
));
foreach ($posts as $post) : start_wp(); ?>
<?php if ($i == 3): ?>
<h2><?php the_title(); ?></h2>
<?php endif; ?>
<?php if($i == 3){$i = 1;} else {$i++;} ?>
<?php endforeach; ?>
</div>
</div>
Related
I'm having an ACF repeater inside a custom post type loop with a counter that makes a row around every two col-md-6's. This works great when I have an even number of col's but not when it's uneven. When a post has an uneven number of col's the counter somehow remembers that for the next post and only displays one col in the first row.
Down here you'll find the current code and a little picture of what is happening.
Somehow I need to reset the counter after each post loop but can't figure it out. wp_reset_postdata doesn't seem to work.
<?php $args = array( 'post_type' => 'posttypename', 'posts_per_page' => '-1' ); $the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<div>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1><?php the_title(); ?></h1>
</div>
</div>
<?php if( have_rows('row') ): ?>
<div class="row">
<?php while( have_rows('row') ): the_row(); $text = get_sub_field('text'); ?>
<div class="col-md-6">
<?php echo $text; ?>
</div>
<?php $counter++; if($counter % 2 === 0) : echo '</div> <div class="row">'; endif; ?>
<?php endwhile; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
Just a small change. You need to make sure that your counter is reset to 0 before the loop for the acf starts.
<?php $counter = 0; //Initialize your Counter here before the Loop Starts for each Post ?>
<?php if( have_rows('row') ): ?>
<div class="row">
<?php while( have_rows('row') ): the_row(); $text = get_sub_field('text'); ?>
<div class="col-md-6">
<?php echo $text; ?>
</div>
<?php $counter++; if($counter % 2 === 0) : echo '</div> <div class="row">'; endif; ?>
<?php endwhile; ?>
</div>
<?php endif; ?>
My problem is that for some reason pages title and content prints upside down. And it prints searchbar twice. Can you please take look at coede bwlow
<?php get_header(); ?>
<div class="row">
<div class="col-xs-12 col-sm-8">
<div class="row text-center no-margin">
<?php
$currentPage = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array('posts_per_page' => 3,'post_type'=>'post', 'paged' => $currentPage);
new WP_Query($args);
if( have_posts() ): $i = 0;
while( have_posts() ): the_post(); ?>
<?php
if($i==0): $column = 12; $class = '';
elseif($i > 0 && $i <= 2): $column = 6; $class = ' second-row-padding';
elseif($i > 2): $column = 4; $class = ' third-row-padding';
endif;
?>
<?php the_content(); ?>
<div class="col-xs-<?php echo $column; echo $class; ?> blog-item">
<?php if( has_post_thumbnail() ):
$urlImg = wp_get_attachment_url( get_post_thumbnail_id( get_the_ID() ) );
endif; ?>
<div class="blog-element" style="background-image: url(<?php echo $urlImg; ?>);">
<!--<?php the_title( sprintf('<h1 class="entry-title">', esc_url( get_permalink() ) ),'</h1>' ); ?> -->
<h1 class="entry-title"><?php the_title(); ?></h1>
<small><?php the_category(' '); ?></small>
</div>
</div>
<?php $i++; endwhile; ?>
<div class="col-xs-6 text-left">
<?php next_posts_link('« Older Posts'); ?>
</div>
<div class="col-xs-6 text-right">
<?php previous_posts_link('Newer Posts »'); ?>
</div>
<?php endif;
wp_reset_query();
?>
</div>
</div>
<div class="col-xs-12 col-sm-4">
<?php get_sidebar(); ?>
</div>
</div>
<?php get_footer(); ?>
Maybe you were doing the Wordpress101 course in youtube. In the code you show there is not a search bar. The search bar is in the header that you called here using:
Maybe in the header was repeated the calling to the search form:
<div class="container">
<?php get_search_form(); ?>
</div>
Also, I had the problem that bootstrap wasn't rendering in a good way the menu, so I had to add also in the header.php (no matter if I also refer to the bootstrap in the functions.php file , as I assumed you did it in the tutorial) the lines on the Bootstrap CDN in this page:
http://blog.getbootstrap.com/2016/07/25/bootstrap-3-3-7-released/
Copy this CDN links:
Latest compiled and minified CSS
Optional theme
Latest compiled and minified JavaScript
I have an Easy Digital Downloads archive page the shows published downloads, but also pending downloads although its not suppose to.
for some reason, the wp_count_posts() doesn't affect on the loop, and I can see also pending posts in the archive page. I cant figure out why.
<?php
$count_posts = wp_count_posts('download');
$published_posts = $count_posts->publish;
$key = 0;
?>
<?php if (have_posts()) : ?>
<div class="all_product">
<div class="row">
<?php while (have_posts()) : the_post();
if ($key < 12) {
?>
<div class="col-lg-3 col-md-4 col-sm-12 single-download-list">
<?php get_template_part('content-grid', 'download'); ?>
</div>
<?php
}
$key++;
endwhile; ?>
</div>
</div>
<?php else : ?>
<?php
$args= array(
'post_type' => 'download',
'post_status' => 'publish'
)
$posts = get_posts($args);
$key = 0;
?>
<?php if ($posts) : ?>
<div class="all_product">
<div class="row">
<?php foreach($posts as $post) setup_postdata($post );
if ($key < 12) {
?>
<div class="col-lg-3 col-md-4 col-sm-12 single-download-list">
<?php get_template_part('content-grid', 'download'); ?>
</div>
<?php
}
$key++;
endforeach;
endif;
?>
</div>
</div>
<?php
endif;
wp_reset_postdata();?>
?>
<?php else : ?>
I need to have a different layout for the first post in every page, but don't know where to start. The code is the following:
<?php get_header(); ?>
<div class="row">
<section class="small-12 columns grid-style">
<?php $i = 0; $counter = range(0, 200, 3); ?>
<?php
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$args = array('offset'=> 0, 'paged'=>$paged);
$all_posts = new WP_Query($args);
if (have_posts()) : while($all_posts->have_posts()) : $all_posts->the_post();?>
<?php if ($i % 3 == 0) { echo '<div class="row journal" data-equal=".post">'; } ?
<!--Post -->
<article class="grid-style post" id="post-<?php the_ID(); ?>"
<div class="post-img">
<?php get_template_part( 'inc/postformats/grid-style' ); ?>
</div>
<div class="post-box">
<div class="post-title">
<h2><?php echo ShortenText(get_the_title(), 50); ?></h2>
</div>
<aside class="post_categories">
<?php the_category(', '); ?>
</aside>
<div class="post-content">
<?php echo ShortenText(get_the_excerpt(), 170); ?>
</div>
</div>
</article>
<!--/Post -->
<?php if (in_array($i + 1, $counter)){ echo '</div>'; } ?>
<?php $i++; endwhile; ?>
<div class="small-12 columns">
<?php theme_pagination($all_posts->max_num_pages, 1, true); ?>
</div>
<?php else : ?>
<p><?php _e( 'Please add posts from your WordPress admin page.', THB_THEME_NAME ); ?></p>
<?php endif; ?>
</section>
</div>
<?php get_footer(); ?>
I need to use a different image size, so I need to output everything inside < ! - - Post - - > again for the first post only.
Are you trying to include div.row.journal to the first post?
If it's the case try doing this:
Replace <?php if ($i % 3 == 0) { echo '<div class="row journal" data-equal=".post">'; } ? by the following: (It'll echo it only on the first page, for the first post)
<?php
if ($all_posts->current_post == 0 && !is_paged()) {
echo '<div class="row journal" data-equal=".post">';
}
?>
Doing the same for the closing div by replacing <?php if (in_array($i + 1, $counter)){ echo '</div>'; } ?> by :
<?php
if ($all_posts->current_post == 0 && !is_paged()) {
echo '</div>';
}
?>
You have to define a counter and ask with if...else... inside the loop
$post_counter = 1;
while (start_loop):
if ($post_counter == 1){
echo "<div id='1'></div>";
else:
echo "<div id='2'></div>";
$post_counter += 1;
//end loop
I think that should help you.
This is the code I have now, I was able to output the HTML for the first post, and a different one for ALL the posts, but I am getting 2 first posts. One using the first layout and the second using the second layout
<?php
/*
Template Name: Blog - Grid Style
*/
?>
<?php get_header(); ?>
<div class="row">
<section class="small-12 columns grid-style">
<?php $i = 0; $counter = range(0, 200, 3); ?>
<?php
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$args = array('offset'=> 0, 'paged'=>$paged);
$all_posts = new WP_Query($args);
$post_counter = 0;
if (have_posts()) : while($all_posts->have_posts()) : $all_posts->the_post(); $post_counter++;?>
<?php if ($i % 3 == 0) { echo '<div class="row journal" data-equal=".post">'; } ?>
<?php if ($post_counter == 1){ ?>
<!--Layout Post 1-->
<div class="row">
<article class="grid-style post small-9 small-centered column" id="post-<?php the_ID(); ?>">
<div class="post-img">
<?php get_template_part( 'inc/postformats/grid-style' ); ?>
</div>
<div class="post-box">
<div class="post-title">
<h2><?php echo ShortenText(get_the_title(), 50); ?>1</h2>
</div>
<aside class="post_categories">
<?php the_category(', '); ?>
</aside>
<div class="post-content">
<?php echo ShortenText(get_the_excerpt(), 170); ?>
</div>
</div>
</article>
</div>
<!--/Layout Post 1-->
<?php } ?>
<!--Other Posts -->
<div class="row">
<article class="grid-style post small-9 small-centered column" id="post-<?php the_ID(); ?>">
<div class="post-img">
<?php get_template_part( 'inc/postformats/grid-style' ); ?>
</div>
<div class="post-box">
<div class="post-title">
<h2><?php echo ShortenText(get_the_title(), 50); ?></h2>
</div>
<aside class="post_categories">
<?php the_category(', '); ?>
</aside>
<div class="post-content">
<?php echo ShortenText(get_the_excerpt(), 170); ?>
</div>
</div>
</article>
</div>
<!--/Other Posts -->
<?php if (in_array($i + 1, $counter)){ echo '</div>'; } ?>
<?php $i++; endwhile; ?>
<div class="small-12 columns">
<?php theme_pagination($all_posts->max_num_pages, 1, true); ?>
</div>
<?php else : ?>
<p><?php _e( 'Please add posts from your WordPress admin page.', THB_THEME_NAME ); ?></p>
<?php endif; ?>
</section>
</div>
<?php get_footer(); ?>
Thanks to some answers on here, I've managed to distinguish my posts into the latest post and all the rest. However, it needs to be the oldest post. Here is my current loop:
<?php if (have_posts()) : ?>
<?php $post = $posts[0]; $c=0;?>
<?php while (have_posts()) : the_post(); ?>
<!-- first post -->
<?php $c++;
if( $c == 1) :?>
<div class="container">
<div class="inner_box">
<ul>
<div class="title">
<a href="<?php the_permalink();?>">
<?php the_title(); ?>
</div>
<?php the_content(); ?>
</a>
</ul>
<div class="down">a</div>
</div>
</div>
<?php else :?>
<!-- second post -->
<div class="container">
<div class="inner_box">
<ul>
<div class="title">
<a href="<?php the_permalink();?>">
<?php the_title(); ?>
</div>
<?php the_content(); ?>
</a>
</ul>
<div class="up">b</div>
</div>
</div>
<?php endif; ?>`
I saw somewhere that you can use a while loop to target the last post from a post.length. However, I am unsure how to implement this.
Yes, you're right. Use count.
Suppose the total posts is 5 for $total_posts = count($posts);.
You'll have to check your $counter for total - 1 as the array is $posts[0], $posts[1], $posts[2], $posts[3], $posts[4].
<?php
if ( have_posts() ) :
$counter = 0;
$total_posts = count($posts) - 1;
while ( have_posts() ) :
the_post();
if( $counter == $total_posts ) {
?>
<div class="container"><?php // CUSTOM CODE FOR LAST ARTICLE ?></div>
<?php
} else {
?>
<div class="container"><?php // CUSTOM CODE FOR THE REST OF ARTICLES ?></div>
<?php
}
$counter++;
endwhile;
endif;
Note that you only need to open <?php and close ?> when changing from PHP to HTML, using them at every line is very confusing.