Wrapping WordPress Posts After X Amount of Times, Without Modifying Loop? - php

I have a WordPress starter theme and one of the features is the ability to chose different archive formats by selecting different template parts. My index.php essentially looks like this:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<!-- To see additional archive styles, visit the /parts directory -->
<?php get_template_part( 'parts/loop', 'archive' ); ?>
<?php endwhile; ?>
<?php joints_page_navi(); ?>
<?php else : ?>
<?php get_template_part( 'parts/content', 'missing' ); ?>
<?php endif; ?>
One of the archive formats is a grid format, which essentially needs to output like so:
Start Row
Post 1
Post 2
Post 3
End Row
Start Row
Post 4
Post 5
Post 6
End Row
.....
Normally, I use this method:
<?php foreach (array_chunk($posts, 2, true) as $posts) : ?>
<div class="row">
<?php foreach( $posts as $post ) : setup_postdata($post); ?>
<div class="six columns">
<?php the_content(); ?>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
However, that piece of code requires a different type of loop than the standard WP loop, which makes it hard to integrate into the theme without the user having to also make adjustments to the loop.
So my question is, is it possible to wrap X amount of posts with a div without modifying the standard WordPress loop?

You can start iterating (counting) over posts by using the iterator $i;
In your archive.php or index.php (the file which has the main query):
<?php if (have_posts()) :
$i = 1; //Start counting
while (have_posts()) : the_post(); ?>
<!-- To see additional archive styles, visit the /parts directory -->
<?php get_template_part( 'parts/loop', 'archive' ); ?>
<?php $i++; //Increase $i ?>
<?php endwhile; ?>
<?php joints_page_navi(); ?>
<?php else : ?>
<?php get_template_part( 'parts/content', 'missing' ); ?>
<?php endif; ?>
And in your parts/loop file (which has the loop "<article></article>"), make calculations to check the current post index and decide whether to skip, start or close the wrapper tag:
<?php
//Doing some math
$x = 4 //Change this to any number you want
if ( $i == 1 || $i == $x || $i % $x == 1 ) {
$before_article = '<div class="wrapper">'; //The wrapper start tag
}
if ( $i % $x == 0 || $wp_query->current_post + 1 == $wp_query->post_count ) {
$after_article = '</div>'; //The wrapper end tag
}
<?php echo $before_article; ?>
<article>
<!-- post content here -->
</article>
<?php echo $after_article; ?>
<?php $before_article = ''; $after_article = ''; ?>

Related

I want to have 3 boxes across page with one specific post in each

I am trying to have 3 boxes across my WP page.
<div class="row text-center">
<div class="col-md-4">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php static $count = 0;
if ($count == "1") { break; }
else { ?>
<div class="post">
<?php the_title(); ?>
<?php the_content(); ?>
</div>
<?php $count++; } ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
<div class="col-md-4">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php static $count = 0;
if ($count == "1") { break; }
else { ?>
<div class="post">
<?php the_title(); ?>
<?php the_content(); ?>
</div>
<?php $count++; } ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
<div class="col-md-4">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php static $count = 0;
if ($count == "1") { break; }
else { ?>
<div class="post">
<?php the_title(); ?>
<?php the_content(); ?>
</div>
<?php $count++; } ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
</div>
The object is to have one different specific post in each of the three boxes.
I am trying to make a page that has every block of text easily editable from the admin rather than the code. I am using a plugin that allows me to add a shortcode to a post where I want my specific post to show.
I have the boxes in place and have everything correct.
The first box populates with the correct post as it should but the other two won't display their posts.
It seems that maybe I can only use the loop once on the page, if so how can I achieve my aims?
Thanks for reading, any understandable advice will be very welcome, I have only recently started custom themes and PhP is a bit of a struggle too so I would be grateful if the help could be dumbed down a bit.
NB: I have tried replacing break with continue as suggested but the second and third post still don't show. Is it possible that there is more than just replacing the word break with continue?
Your loop breaks out of the foreach loop on the second iteration since $count = 1. You might have wanted to do continue to skip the 2nd post?
(Don't be tempted to think that break just breaks out of the conditional block. The conditional logic simply chooses which path or block of code to execute.)
EDIT
First of all, you are doing a loop for each box...The purpose of the loop is so that you don't need to repeat your code.
Second, you are restarting the loop each time..
Use the loop like this:
$query = new WP_Query( array( 'post_type' => 'post' ) );
<?php if ( $query->have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="post">
<?php the_title();
the_content();
?>
</div>
<?php endwhile;
wp_reset_postdata();
endif;
?>
There a couple ways to do the query. I do like the get_posts better for simple queries because you don't need to reset the postdata using that way. You'd pass in the same arguments to the WP_Query.
Also I recommend you create a page template for this and assign it to a page. This way if you want to change your template you can just assign the page a different one instead of modifying your index.php code.

How to separate WordPress posts loop in to two columns?

I need to separate WordPress posts loop in to 2 columns , left and right.
Currently I am doing this with 2 separate loops but would like to make it with one if possible.
<div class="left-side">
<?php
$row_start = 1;
while ( have_posts() ) : the_post();
if( $row_start % 2 != 0) {// odd
get_template_part( 'blog','item');
}
++$row_start;
endwhile;
?>
</div>
<div class="right-side">
<?php
$row_start = 1;
while ( have_posts() ) : the_post();
if( $row_start % 2 == 0) {// even
get_template_part( 'blog','item');
}
++$row_start;
endwhile;
?>
</div>
Any help is appreciated!
Move the loops into a separate template files.
Create two files in your themes directory, one named posts-odd.php and the other named posts-even.php and add the post loops respectively, i.e:
posts-odd.php:
<?php
$row_start = 1;
while ( have_posts() ) : the_post();
if( $row_start % 2 != 0) {// odd
get_template_part( 'blog','item');
}
++$row_start;
endwhile;
?>
posts-even.php:
<?php
$row_start = 1;
while ( have_posts() ) : the_post();
if( $row_start % 2 == 0) {// even
get_template_part( 'blog','item');
}
++$row_start;
endwhile;
?>
In your main template you can now use get_template_part function to include the partial template into your main template:
<div class="left-side">
<?php get_template_part('posts', 'odd') ?>
</div>
<div class="right-side">
<?php get_template_part('posts', 'even') ?>
</div>
If you're displaying the odd and even posts in various places this will give you the benefit of only having to define the loop templates once.
https://developer.wordpress.org/reference/functions/get_template_part/
Not easy but possible.
<?php
$i = 0;
$column = array();
$column[1] = $column[2] = '';
if (have_posts()) :
while (have_posts()) :
the_post();
$i++;
$column[$i] .= '<div class="'.esc_attr(implode(' ', get_post_class())) .'">';
$column[$i] .= '<div class="post_inner">
'.get_the_content().'
</div>
</div>';
$i = ($i==2) ? 0 : $i;
endwhile; ?>
<div id="grid_posts">
<div class="span6"><?php echo $column[1]?></div>
<div class="span6"><?php echo $column[2]?></div>
</div>
<?php else: ?>
<p><?php esc_html_e('No posts were found. Sorry!', 'mytheme'); ?></p>
<?php endif; ?>
Basically you create columns array and put your contents in there in two keys (1 and 2), and every 2 posts you put in one column, and keep increasing the counter to 2 and resetting it once it gets to 2. So you keep filling the array with posts - first to key 1 and then to key 2 and so on.
Then you just output those two into 2 columns (span6 in my case).
Hope this helps.

Wordpress add separate section in between of posts without disturbing the posts continuity

I am building a basic Wordpress blog which is build on Duplex theme.
I Would like to do some minor customization to the site where in the site has an Instagram widget after two posts and then continue the posts.
Just to simplify the order of the page would be :
2 posts.
Instagram widget
Continue from 3rd post.
The Front page displays set to posts like the way I want.
How can I achieve getting the Instagram widget in between of the posts without disturbing the flow?
What you do is run the loop two times to display the first posts, reset it and then start it again after your widget - skipping the two first posts.
You may achieve this like so:
First run the loop, displaying the two first posts.
// The Query
$the_query = new WP_Query( array( 'posts_per_page' => 2 ) );
// The Loop
if ( $the_query->have_posts() ) {
//Display post
}
Reset the query, and display your widget
/* Restore original Post Data */
wp_reset_postdata();
//Your widget here.
Display the next posts, skipping the first two.
// The Second Query
$the_query = new WP_Query( array( 'posts_per_page' => 10, 'offset' => 2 ) );
// The Loop
if ( $the_query->have_posts() ) {
//Display post
}
Thanks a ton #danjah! Below is my code
<?php get_header(); ?>
<div id="content">
<div class="posts clearfix">
<?php if ( is_search() ) { ?>
<h2 class="archive-title"><i class="icon-search"></i> <?php echo $wp_query->found_posts; ?> <?php _e('Results for','hyphatheme'); ?> "<?php the_search_query() ?>" </h2>
<?php } else if ( is_tag() ) { ?>
<h2 class="archive-title"><i class="icon-tag"></i> <?php single_tag_title(); ?></h2>
<?php } else if ( is_day() ) { ?>
<h2 class="archive-title"><i class="icon-time"></i> <?php echo get_the_date(); ?></h2>
<?php } else if ( is_month() ) { ?>
<h2 class="archive-title"><i class="icon-time"></i> <?php echo get_the_date('F Y'); ?></h2>
<?php } else if ( is_year() ) { ?>
<h2 class="archive-title"><i class="icon-time"></i> <?php echo get_the_date('Y'); ?></h2>
<?php } else if ( is_category() ) { ?>
<h2 class="archive-title"><i class="icon-list-ul"></i> <?php single_cat_title(); ?></h2>
<?php } else if ( is_author() ) { ?>
<h2 class="archive-title"><i class="icon-pencil"></i> <?php echo get_userdata($author)->display_name; ?></h2>
<?php } ?>
<?php
if ( have_posts()) :
while ( have_posts() ) : the_post();
/*
* Include the post format-specific template for the content. If you want to
* use this in a child theme, then include a file called called content-___.php
* (where ___ is the post format) and that will be used instead.
*/
get_template_part( 'content', get_post_format() );
endwhile;
else:
/*
* If no posts are found in the loop, include the "No Posts Found" template.
*/
get_template_part( 'content', 'none' );
endif;
?>
</div><!--END .posts-->
<?php if ( hypha_page_has_nav() ) : ?>
<!-- post navigation -->
<?php $post_nav_class = ( get_option( 'hypha_customizer_infinite_scroll' ) == 'enable' ) ? ' infinite' : '' ; ?>
<div class="post-nav<?php echo $post_nav_class; ?>">
<div class="post-nav-inside clearfix">
<div class="post-nav-previous">
<?php previous_posts_link(__('<i class="icon-arrow-left"></i> Newer Posts', 'hyphatheme')) ?>
</div>
<div class="post-nav-next">
<?php next_posts_link(__('Older Posts <i class="icon-arrow-right"></i>', 'hyphatheme')) ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( is_single() ) { ?>
<!-- comments template -->
<?php if ( 'open' == $post->comment_status ) : ?>
<?php comments_template(); ?>
<?php endif; ?>
<?php } ?>
</div><!--END #content-->
One approach would be the one mentioned would be the one by #danjah wehre you're creating a secondary loop on the page to get the first two posts. Since you're new to wordPress, lets start at the beginning.
All of your templating revolves around the loop. The loop works with the query already defined on the page. wordPress has various default queries depending on which template its loading (a post, an archive, a single post, a page, the index)
The Loop
The Tempalte Heirarchy
So a) wordpress defines the query based on the route you're on, and b) you use the loop to get at it. BUT. You can alater the query, override it, or run additional queries.
Have a loop at WP_Query
Lets loop at the standard loop. In your index.php you probably have something like :
<!-- Start the Loop. -->
<?php if ( have_posts() ) :
while ( have_posts() ) :
the_post(); ?>
<!-- use markup or template helpers in here -->
<?php endwhile;
endif; ?>
While you could run a secondary query before the main loop, insert the thing you want, and then alter the main loop to skip those first two, the second way would be to, rather than creating another loop and altering the main one, why not rather keep a count. You could do this with a variable that you increment (its just a standard php while loop after all), But I believe that you can also get the current post index from the global $wp_query object.
$index = 1;
<!-- Start the Loop. -->
<?php if ( have_posts() ) :
while ( have_posts() ) :
the_post(); ?>
<!-- use markup or template helpers in here -->
<?php if ($index == 2) : ?>
<!-- do something after the second post -->
<?php endif; ?>
<!-- increment the index -->
$index++;
<?php endwhile;
endif; ?>
I believe you can get the index as well with $wp_query->current_post, but I haven't done this for a while, and haven't tested this.
Hope it helps!

Wordpress: div enclosing each group of three posts

In Wordpress, I want to have a div wrapping around every three posts (because the posts are in a grid, three per line, and I want each line to have a uniform height so the "read more" buttons line up at the bottom - http://restartcomputer.com/category/products/mac-products/). I figured out (logically) how to do this - it is basically outlined in the accepted answer of this question: PHP loop: Add a div around every three items syntax
However, I've tried everything and cannot get the code to work. The divs do not get added, at all. Here is the code:
if (have_posts()) :
$counter = 1; ?>
<div class="entries-wrapper">
<?php while (have_posts()) : the_post(); ?>
//post stuff
<?php if ($counter % 3 == 0) { ?>
</div><div class="entries-wrapper">
<?php }
$counter += 1; ?>
<?php endwhile; ?>
</div>
//some more code
<?php endif; wp_reset_query(); ?>
Any idea why?
You have not entered back into Script (Line 4):
if (have_posts()) :
$counter = 1; ?>
<div class="entries-wrapper">
<?php while (have_posts()) : the_post(); ?>
//post stuff
<?php if ($counter % 3 == 0) { ?>
</div><div class="entries-wrapper">
<?php }
$counter += 1; ?>
<?php endwhile; ?>
</div>
//some more code
<?php endif; wp_reset_query(); ?>
I did something similar in my theme to align posts side by side:
<?php if ( have_posts() ) : ?>
<?php $col = 1; ?>
<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php if($col == 1) echo "<div class='row'>"; ?>
<div class="post col<?php echo $col; ?>" id="post-<?php echo the_ID(); ?>">
<?php
/* Include the Post-Format-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Format name) and that will be used instead.
*/
get_template_part( 'content', get_post_format() );
?>
<?php (($col==1)?$col=2:$col=1); ?>
</div>
<?php if($col == 1) echo "</div>"; ?>
<?php endwhile; ?>
<?php kubrick_paging_nav(); ?>
<?php else : ?>
Can also try moving the DIV within the WHILE statement.

PHP counter increment for every 1st and 4th div

I am running a wordpress if while statement and would like my items to display in a column format.
I am currently using 960.gs which is your standard 960 grid system, and by default adds 10px padding to left and right, by simply passing a class of alpha or omega you can get rid of these.
How do I get php to execute a statment for every 1st one to add alpha and 4th one omega?
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="grid_4">
<?php $wp_query->is_home = false; ?>
<div class="entry">
<h3 style="margin-bottom:10px;"><?php the_title(); ?></h3>
<?php //the_excerpt() ?>
</div>
</div>
<?php endwhile; endif; ?>
Try maybe something like this. I wasn't sure what you meant by every 1st and 4th so I made it the way you can see. You should be able to customize it yourself.
<?php $counter = 0; ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$div = '<div class="entry';
if ($counter % 4 == 0)
$div .= " alpha";
else if($counter % 4 == 3)
$div .= " omega";
echo $div . '">';
?>
<div class="grid_4">
<?php $wp_query->is_home = false; ?>
<div class="entry">
<h3 style="margin-bottom:10px;"><?php the_title(); ?></h3>
<?php //the_excerpt() ?>
</div>
</div>
<?php $counter++; ?>
<?php endwhile; endif; ?>
Try this:
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div class="grid_4">
<?php $wp_query->is_home = false; ?>
<div class="entry <?php if (!($i++ % 4)) { ?>alpha<?php } ?> <?php if (!(($j++)+1 % 4)) { ?>omega<?php } ?>">
<h3 style="margin-bottom:10px;"><?php the_title(); ?></h3>
<?php //the_excerpt() ?>
</div>
</div>
<?php endwhile; endif; ?>
Looks kind of like a repeat of something I've seen recently. (Not your fault, it was poorly named and you wouldn't have been able to search on it). Help needed improving a foreach loop
I think what you're looking for would be more precisely described as class=alpha on row 4k+1, class=omega on row=4k
I'm not familiar with your if/while syntax, and the embedded PHP throws me off a little. But I think what you want to do:
is initialize a counter to 0 before the while loop ($i = 0). Increment it at the end of the loop ($i++)
I'm not sure where you want to put these classes, but put if ($i%4==1) class="alpha" and if(i%4==0) class="omega" (add php tags as appropriate, for some reason they werent showing up right for me).

Categories