PHP: Break loop and then continue? - php

I'm having a problem with the WordPress posts loop. I'd like to break down the post loop, to add some HTML div tags in the post. For example, I'm trying to add a div .wrap around the posts after first post. As it's to wrap the posts, so it should be only once.
The problem is that the .wrap div is being repeated because of the loop. How can I break the loop, and add the .wrap div only once and then continue the loop?
Here's my code:
while ($wp_query->have_posts()) :
$wp_query->the_post();
if($wp_query->current_post <= 1){ ?>
<div class="x">
.. post 1
</div>
<?php }
if($wp_query->current_post > 1){ ?>
<div class="wrap"> <!-- should be only once -->
<div class="y">
.. post 2
</div>
<div class="y">
.. post 3
</div>
</div><!-- should be only once -->
<?php } ?>
endwhile;

Try this
<?php
while ($wp_query->have_posts()) :
$wp_query->the_post();
if($wp_query->current_post <= 1){ ?>
<div class="x">
.. post 1
</div>
<div class="wrap"> <!-- should be only once -->
<?php
$is_wrapped = 1;
}
if($wp_query->current_post > 1){ ?>
<div class="y">
.. post 2, then post 3, ...
</div>
<?php }
endwhile;?>
<?php if (!empty($is_wrapped)){ ?>
</div><!-- should be only once -->
<?php } ?>

You can just use an iterator index, like this:
$i = 0;
while (...) {
if ($i == 1) {
// actions you need to do only once
}
...
$i++
}

<div class="x">
while ($wp_query->have_posts()) :
$wp_query->the_post();
<--print post-->
if($wp_query->current_post <= 1){
</div><div class="y">
}
endwhile;
</div>
You will get an empty <div class="x" /> if there's no post and an empty <div class="y" /> if there's only one post. But may be that's feasible in your case...
edit: example
<?php
$wp_query = new WPDummy;
echo '<div class="x">';
while ($wp_query->have_posts()) :
$wp_query->the_post();
$wp_query->the_content();
if($wp_query->current_post <= 1){
echo '</div>', "\n",'<div class="y">';
}
endwhile;
echo '</div>';
// boilerplate
class WPDummy {
public $current = null;
public $current_post = 0;
public function __construct() {
$this->posts = array( array('content'=>'A'),array('content'=>'B'),array('content'=>'C'),array('content'=>'D') );
}
public function have_posts() {
return false!=current($this->posts);
}
public function the_post() {
$this->current_post+=1;
$this->current = current($this->posts);
next($this->posts);
}
public function the_content() {
echo '<span class="content">', $this->current['content'], '</span>';
}
}
prints
<div class="x"><span class="content">A</span></div>
<div class="y"><span class="content">B</span><span class="content">C</span><span class="content">D</span></div>

Related

Adding div class based on PHP variable from ACF repeater field?

I am looping through a repeater field in Advanced Custom Fields and displaying divs for each item in the repeater. If the index is equal to 0, I want to add a special class to just that div. Is this possible? Here's what I've tried:
<?php if (have_rows('products')): $i = 0; ?>
<div class="product-container">
<?php while (have_rows('products')) : the_row(); ?>
<div class="product <?php if ($i == 0) { echo 'active-class'; } ?>"></div>
<?php $i++; endwhile; ?>
</div>
<?php endif; ?>
Unfortunately this is not working.
Instead of doing the conditional within the class, I just did it on the outside and defined two different class tags based on the condition:
<?php if (have_rows('products')): $i = 0; ?>
<div class="product-container">
<?php while (have_rows('products')) : the_row(); ?>
<div <?php if ($i == 0) { ?>class="product active"<?php } else { ?>class="product"<?php } ?> ></div>
<?php $i++; endwhile; ?>
</div>
<?php endif; ?>

Changing HTML structure according to counter

I have an HTML structure that I need to dynamically output.
I am using a counter within my loop to check for the first post, and applying the class headline-big and m-grid-item for the first post. Then I'm applying the second class headline-scroll for the subsequent posts.
The problem is, the 2nd, 3rd and 4th posts are not being nested inside headline-scroll they are each getting their own div.headline-scroll which is messing up site.
I need the 2nd, 3rd and 4th posts to be nested inside a single div.headline-scroll instead of each one of them being nested under a separate one.
This is the HTML for structure
<!-- / 1ST POST -->
<div class="headline-big">
<div class="m-grid-item">
...
</div>
</div>
<!-- / END OF FIRST POST -->
<!-- / 2ND, 3RD AND 4TH POST - ALL NESTED INSIDE div.headline-scroll -->
<div class="headline-scroll">
<!-- / 2ND POST -->
<div class="m-grid-item -medium">
...
</div>
<!-- / END OF 2ND POST -->
<!-- / 3RD POST -->
<div class="m-grid-item -small">
...
</div>
<!-- / END OF 3RD POST -->
<!-- / 4TH POST -->
<div class="m-grid-item -small">
...
</div>
<!-- / END OF 4TH POST -->
</div>
And this is the PHP
if ( $featured->have_posts() ) {
$i = 0;
while ( $featured->have_posts() ) {
$featured->the_post();
if ( $i == 0 ) :
?>
<div class="headline-big">
<div class="m-grid-item">
<?php endif; ?>
<?php if ( $i != 0 ) : ?>
<div class="headline-scroll">
<div class="m-grid-item -medium">
<?php endif; ?>
<?php the_title(); ?>
</div>
</div>
<?php $i++;
}
} else {
echo 'Add some posts';
}
I'm not sure if I could be able to answer your question well. But this is how I understand. If there is a question, please let me know and I will modify.
if ( $featured->have_posts() ) {
$i = 1;
while ( $featured->have_posts() )
{
$featured->the_post();
if( $i == 1)
{
?>
<div class="headline-big">
<div class="m-grid-item">
<?php the_title(); ?>
</div>
</div>
<div class="headline-scroll">
<?php
}
else
{
$small = array(3,4); //list of small classes
$class = ( in_array($i, $small)) ? '-small' : '-medium';
<div class="m-grid-item <?php echo $class; ?>">
<?php the_title(); ?>
</div>
<?php
}
$i++;
}
echo '</div><!-- end of headline-scroll -->';
} else {
echo 'Add some posts';
}
I've simplified it here with if conditions.
If it's the first post, create the headline-big div.
If it's the second post, create the headline-scroll div and the medium class div.
For all subsequent posts, just use the small div. Finally, outside the while loop, if we had more than 1 post, we need to add a closing div to close off the headline scroll.
if ( $featured->have_posts() ) {
$i = 0;
while ( $featured->have_posts() )
{
$featured->the_post();
if( $i == 0)
{
?>
<div class="headline-big">
<div class="m-grid-item">
<?php the_title(); ?>
</div>
</div>
<?php
}
else if($i == 1)
{
?>
<div class="headline-scroll">
<div class="m-grid-item -medium">
<?php the_title(); ?>
</div>
<?php
}
else
{
<div class="m-grid-item -small">
<?php the_title(); ?>
</div>
}
$i++;
}
if($i > 1){
?>
</div><!-- end of headline-scroll -->
<?php
}
} else {
echo 'Add some posts';
}
You never closed many of your DIV tags, and you were opening your div.headline-scroll inside a loop, so you were bound to get more than one. Try this instead maybe? Consistent indent and minimal PHP in your HTML will make things easier to debug, though you're hamstrung by Wordpress' awful functions.
<?php if (!$featured->have_posts()):?>
<p>Add some posts!</p>
<?php else: $i = 0; while ($featured->have_posts()): $featured->the_post();?>
<?php if (!$i):?>
<div class="headline-big">
<div class="m-grid-item">
<?php the_title(); ?>
</div>
</div>
<div class="headline-scroll">
<?php else:?>
<div class="m-grid-item -medium">
<?php endif; ?>
<?php the_title(); ?>
</div>
<?php $i++; endwhile;?>
</div>
<?php endif?>

ACF / PHP Repeater count

I have a repeater using Advanced Custom fields, which when a count reaches a total (of 3) based on an iterative count, I would like to output a div, then reset the counter.
Here's the code, at the moment it's not outputting as it should and I don't know enough about math to get it to work.
Appreciate your assistance :-)
<?php if(have_rows('flexible_row')) : ?>
<div class="row">
<?php if(empty($count)){ $count=1;} while(have_rows('flexible_row')) : the_row(); ?>
<?php if(get_sub_field('column_width') == "One column") { $count = $count+1; ?>
<div class="col-sm-4">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
Count is <?php echo $count; ?>
<hr/>
</div>
<?php } if(get_sub_field('column_width') == "Two columns") { $count = $count+2; ?>
<div class="col-sm-8">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
Count is <?php echo $counter; ?>
<hr/>
</div>
<?php } else { $count = $count+3; ?>
<div class="col-sm-12">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
Count is <?php echo $counter; ?>
<hr/>
</div>
<?php } if ($count == 3) { ?></div><div class="row"><?php $count = 0; } ?>
<?php endwhile; ?>
</div>
<?php endif; ?>
Think I'd got my logic mixed up a bit — I wasn't using the else clauses correctly. Here's the final working code in case anyone stumbles across this in the future:
<?php if(have_rows('flexible_row')) : ?>
<div class="row">
<?php if(empty($count)){ $count=0;} while(have_rows('flexible_row')) : the_row(); ?>
<?php if(get_sub_field('column_width') == "One Column") { $count = $count+1; ?>
<div class="col-sm-4">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
</div>
<?php } elseif(get_sub_field('column_width') == "Two Columns") { $count = $count+2; ?>
<div class="col-sm-8">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
</div>
<?php } else { $count = $count+3; ?>
<div class="col-sm-12">
<?php the_sub_field('title');?>
<?php the_sub_field('content');?>
</div>
<?php } if ($count == 3) { ?></div><div class="row"><?php $count = 0; } ?>
<?php endwhile; ?>
</div>
You could of course use switch statements too..

PHP Product Listing - End of Loop Close Row

Sorry for the title, I wasn't sure how to word it.
Basically, I have a webpage that uses Advanced Custom Fields to populate products, it loops through the products and displays them in groups of three, per row; each row alternates color - light grey to dark grey.
My issue is, the code I wrote is checking if each row has 3 items, so if the product listing row ends on 1 or 2, the row containing div is not closed off, thus wrapping my footer and messing up the for the rest of the page. The following is my code, it should be pretty easy to follow - you can also see I am using LazyLoadAny - Basically, I count the items, if there are more than 6 I lazyload the rest. On the first item I open the row container and when there are three I close it. So again, I need to figure out how to close the container if the row ends on 1 or 2 items not just 3.
Short Version: How do I close the "internal-product-light" or "internal-product-dark" rows if they end with 1 or 2 products instead of 3?
<?php
$count = 0;
$rowCount = 0;
$rowClass = "internal-product-light";
// check if the repeater field has rows of data
if( have_rows('product_listing_repeater') ): ?>
<div class="internal-container">
<div class="full-product-line-contain">
<?php // loop through the rows of data
while ( have_rows('product_listing_repeater') ) : the_row(); $count++; $rowCount++; ?>
<?php if($rowCount == 1) { ?>
<div class="<?php echo $rowClass; ?>">
<div class="product-centering">
<?php if($count > 6) { ?>
<div class="js-lazyload">
<?php echo "<!--"; }
} ?>
<div class="internal-section product-line-item product-alignment clearfix">
<div class="product-contain">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link">
<?php
if(get_sub_field('has_image')):
$singleImage = get_sub_field('block_image');
?>
<img class="product-line-image" src="<?php echo $singleImage ?>" />
<?php endif; ?>
</a>
<?php endif; ?>
<div class="internal-content-contain-right no-float">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link-title">
<h2><?php the_sub_field('block_headline'); ?></h2>
</a>
<?php endif; ?>
<?php if(get_sub_field('has_link')): ?>
<?php the_sub_field('link_text')?>
<?php endif; ?>
</div>
</div>
</div>
<?php if($rowCount == 3) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php $rowCount = 0;
if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
<?php endwhile; ?>
</div>
</div>
Your last if-statment could be:
<?php if(($rowCount % 3) == 0) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
And then, after the while-block:
<?php if(($rowCount % 3) <> 0) { ?>
<?php if($count > 6) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
The x % y returns the remainder of x/y.
So the following code is actually a much simpler solution than I thought it would be - I will post the code then break it down.
<?php
$count = 0;
$rowCount = 0;
$rowClass = "internal-product-light";
$rowInfo = get_sub_field('product_listing_repeater');
$fieldCount = count($rowInfo);
// check if the repeater field has rows of data
if( have_rows('product_listing_repeater') ): ?>
<div class="internal-container">
<div class="full-product-line-contain">
<?php // loop through the rows of data
while ( have_rows('product_listing_repeater') ) : the_row(); $count++; $rowCount++; ?>
<?php
if($rowCount == 1) { ?>
<div class="<?php echo $rowClass; ?>">
<div class="product-centering">
<?php if($count > 6) { ?>
<div class="js-lazyload">
<?php echo "<!--"; }
} ?>
<div class="internal-section product-line-item product-alignment clearfix">
<div class="product-contain">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link">
<?php
if(get_sub_field('has_image')):
$singleImage = get_sub_field('block_image');
?>
<img class="product-line-image" src="<?php echo $singleImage ?>" />
<?php endif; ?>
</a>
<?php endif; ?>
<div class="internal-content-contain-right no-float">
<?php if(get_sub_field('has_link')): ?>
<a href="<?php the_sub_field('link_url')?>" class="product-link-title">
<h2><?php the_sub_field('block_headline'); ?></h2>
</a>
<?php endif; ?>
<?php if(get_sub_field('has_link')): ?>
<?php the_sub_field('link_text')?>
<?php endif; ?>
</div>
</div>
</div>
<?php if($rowCount == 3 || $count == $fieldCount) { ?>
<?php if($count > 6 || $count == $fieldCount) { echo "-->"; ?>
</div><!-- End lazy load div -->
<?php } ?>
</div><!-- End product centering -->
</div><!-- End row -->
<?php $rowCount = 0;
if($rowClass == "internal-product-light"){ $rowClass = "internal-product-dark";}else{$rowClass = "internal-product-light";}
} ?>
<?php endwhile; ?>
</div>
</div>
As you can see, I added the variable $fieldCount = count($rowInfo) which counts the ACF repeater field. Then when I was originally checking for 3 products, I added an OR statement - <?php if($rowCount == 3 || $count == $fieldCount) { ?> and to the lazyload check - <?php if($count > 6 || $count == $fieldCount) { echo "-->"; ?>
This makes sure that if it is 3, it closes the div and if it is the end of the array (figured out through count), it closes the div.
Please post any questions for clarification.

ajax breaking wordpress theme with php javascript

I am attempting to utilize a plugin that uses ajax to help "ajaxify" a wordpress theme. The plugin works great on almost all the pages.
The way it works is that it replaces the content from within a container div that you specify. In my instance it was "#newwrap". That does it's job, the only issue is that on reload the javascript/jquery functions from within the content has to be called again.
Within the plugin there is a place where you can indicate what to reload. I have gotten most of the other parts to work correctly, this one is the one that is stumping me though.
I have a page in the theme that utilizes filters with php. When I click on that specific page the page looks like it renders in css etc except nothing shows and the filters do not work. I look at the html behind it with firebug and the content is there just not being displayed.
Here is the link to the site: http://nex.vyralmedia.com
Once there please click on portfolio > image portfolios
If you click on that page it will load and just show the filters, but they wont work and the content will not display. If you refresh that page you will see what it is supposed to look like without using ajax.
Here is the link to the wordpress plugin: http://wordpress.org/extend/plugins/advanced-ajax-page-loader/
So in this case I am looking for the reload code I should use, or just some way to get that portion working properly.
Any Help would be greatly appreciated.
Here is the template page code for it:
<?php
/*
The template that is used to render pages that are targeted by the multiple portfolio behavior of Prime.
*/
get_header(); ?>
<div id="newwrap">
<?php roots_content_before(); ?>
<?php roots_main_before(); ?>
<?php
global $prime_portfolio;
$portfolio_instance = get_option(PRIME_OPTIONS_KEY);
$show_filter = false;
$page = get_queried_object();
foreach ($portfolio_instance['portfolio_instance_slider'] as $p) {
if(key_exists('portfolio_show_filters', $p) && $p['portfolio_show_filters'][0] == 'Yes' && $p['portfolio_page'] == $page->ID) {
$show_filter = true;
}
}
?>
<div class="main portfolio-main <?php if($show_filter) { echo 'show-filter'; } else { echo 'no-filter'; }?>" role="main">
<div class="subheader-wrapper">
<div class="container_12">
<div class="grid_12">
<div id="subheader">
<?php
global $post;
global $prime_frontend;
$prime_frontend->prime_title_and_subtitle();
?>
<?php if($show_filter) { ?>
<div class="table select-table">
<select class="filter">
<option data-filter="*"><?php echo get_portfolio_all_filter_text(); ?></option>
<?php
global $prime_portfolio;
$prime_portfolio->render_all_filter_list_item();
$page = get_queried_object();
$portfolio_instance = get_option(PRIME_OPTIONS_KEY);
$filters = NULL;
foreach ($portfolio_instance['portfolio_instance_slider'] as $p) {
if ($p['portfolio_page'] == $page->ID) {
$filters = isset($p['portfolio_filters']) ? $p['portfolio_filters'] : NULL;
break;
}
}
if (!empty($filters)) {
foreach ($filters as $fil) {
$f = get_term($fil, 'portfolio_filter');
?>
<option data-filter='article[data-filters*="<?php echo $f->slug; ?>"]'>
<?php echo $f->name; ?>
</option>
<?php
}
}
?>
</select>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
<div class="content-wrapper">
<div class="overlay-divider"></div>
<?php if($show_filter) { ?>
<div class="filter-wrapper">
<div class="table">
<ul id="filters">
<?php
$prime_portfolio->render_all_filter_list_item();
$page = get_queried_object();
$portfolio_instance = get_option(PRIME_OPTIONS_KEY);
$filters = NULL;
foreach ($portfolio_instance['portfolio_instance_slider'] as $p) {
if ($p['portfolio_page'] == $page->ID) {
$filters = isset($p['portfolio_filters']) ? $p['portfolio_filters'] : NULL;
break;
}
}
if (!empty($filters)) {
foreach ($filters as $fil) {
$f = get_term($fil, 'portfolio_filter');
$prime_portfolio->render_filter_list_item($f);
}
}
?>
</ul>
</div>
<div class="overlay-divider bottom"></div>
<div class="clear"></div>
</div>
<?php } ?>
<?php
$page = get_queried_object();
$page_portfolio_properties = $prime_portfolio->get_portfolio_options($page->ID);
global $wp_query;
$temp_query = $wp_query;
$orig_query_vars = $temp_query->query_vars;
$args = $prime_portfolio->get_portfolio_item_args_for($page->ID);
$posts_per_page = -1;
if (isset($page_portfolio_properties['portfolio_posts_per_page'])) {
$posts_per_page = $page_portfolio_properties['portfolio_posts_per_page'];
$posts_per_page = empty($posts_per_page) ? -1 : intval($posts_per_page);
}
$args['posts_per_page'] = $posts_per_page;
if (!empty($orig_query_vars['paged'])) {
$args['paged'] = intval($orig_query_vars['paged']);
}
else if (!empty($orig_query_vars['page'])) {
$args['paged'] = intval($orig_query_vars['page']);
}
$wp_query = new WP_Query($args);
$paginated = $wp_query->max_num_pages > 1 ? 'paginated' : '';
?>
<div class="portfolio-wrapper">
<div class="row-fluid clearfix page-container">
<div class="span12">
<!--PAGE CONTENT-->
<div class="prime-page prime-full-width prime-portfolio <?php echo $paginated; ?>">
<div id="masonry-container">
<?php get_template_part('loop', 'portfolio'); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php get_footer(); ?>
</div>
<?php roots_main_after(); ?>
<?php roots_content_after(); ?>
</div>
opacity for your article items is set to 0 in style.css line 4293 :
article.item {
opacity: 0;
}
You should remove that rule, or modify your js code to correctly set opacity after ajax loading.

Categories