PHP loop to echo certain div class on first round only - php

I'm trying to create an accordion where the first one is open (with this CSS that means that the panel has 'in' added to the panel-collapse div).
So, I'm setting the variable $i to 1 and just echoing 'in' when it does equal 1, incrementing after the first. When this is executed, however, all looped posts have 'in' and so are open. Can anyone see what I'm doing wrong?
<?php
$i=1;
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<!-- individual panel -->
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#faqs" href="#<?php the_ID(); ?>">
<?php the_title(); ?>
</a>
</h4>
</div>
<div id="<?php the_ID(); ?>" class="panel-collapse collapse <?php if ($i=1) { echo 'in'; } ?>">
<div class="panel-body">
<?php the_field('answer'); ?>
</div>
</div>
</div>
<!-- /individual panel -->
<?php $i++; endwhile;
?>

<?php
$i=1;
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<!-- individual panel -->
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#faqs" href="#<?php the_ID(); ?>">
<?php the_title(); ?>
</a>
</h4>
</div>
<div id="<?php the_ID(); ?>" class="panel-collapse collapse <?php if ($i==1) { echo 'in'; } ?>">
<div class="panel-body">
<?php the_field('answer'); ?>
</div>
</div>
</div>
<!-- /individual panel -->
<?php $i++; endwhile;
?>
It should be $i==1 not $i=1 in your if condition
When you do $i=1 it means you are assigning value 1 to $i , so every time it is successfully satisfying condition.
Here is Comparison Operators :D

Related

ACF flexible content layout group for table of contents

I have an ACF flexible content field with a layout name of 'post_section' which has a group field called 'paragraph' with fields for 'id', 'title' and 'text'. In my component-post_section.php file i have the following php:
<?php if( have_rows('paragraph') ): ?>
<?php while( have_rows('paragraph' ) ): the_row(); ?>
<div class="container">
<div class="row" id="<?php the_sub_field('id'); ?>">
<h2><?php the_sub_field('title'); ?></h2>
<?php the_sub_field('text'); ?>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
This produces the following which is fine:
But im trying to produce the following - a bootstrap accordion table of contents above with the titles of the two post_section titles:
This is my php:
<?php if( have_rows('paragraph') ): ?>
<?php while( have_rows('paragraph' ) ): the_row(); ?>
<div id="accordion">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Table of Contents
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
<p><?php the_sub_field('title'); ?></p>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row" id="<?php the_sub_field('id'); ?>">
<h2><?php the_sub_field('title'); ?></h2>
<?php the_sub_field('text'); ?>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
However, this is what i get:
Any ideas on how i can achieve what i want i.e an output of my title and text field fields for each paragraph BUT only a single output of the titles in the table of contents div like this?
Maybe i need to create a separate component php file for the accordion?
Thanks for any help.
If I am understanding your question right, you simply want a single accordion dropdown to reveal a list of your flexible content paragraph sections?
The single accordion dropdown content is essentially a list of anchor links to navigate directly directly to your flexible content paragraph sections.
If this is the case, then see working example below of how to achieve this.
All of this code below must be run inside your post loop.
<div class="container">
<?php if(have_rows('paragraph')): ?>
<div class="accordion" id="tableContentsAccordion">
<div class="card">
<div class="card-header" id="tableContents">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#tableContentsList" aria-expanded="true" aria-controls="tableContentsList">
Table of Contents
</button>
</h2>
</div>
<div id="tableContentsList" class="collapse show" aria-labelledby="tableContents" data-parent="#tableContentsAccordion">
<div class="card-body">
<?php while(have_rows('paragraph')): the_row();
$title = get_sub_field('title');
?>
<?php echo $title; ?><br/>
<?php endwhile; ?>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if(have_rows('paragraph')): ?>
<div class="row">
<?php while(have_rows('paragraph')): the_row();
$title = get_sub_field('title');
?>
<div class="col-12" <?php echo $title ? 'id="' . sanitize_title($title) . '"' : ''; ?>>
<?php echo $title ? '<h2>' . $title . '</h2>' : ''; ?>
<?php the_sub_field('text'); ?>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</div>
As mentioned in previous comments on your question, you need to run the have_rows('paragraph') statement twice in order to output flexible content paragraph sections content in two separate html locations.
You can actually combine all my code into a single have_rows('paragraph') statement, but only if your section content immediately follows your table of contents html.
If you want to put your table of contents in the sidebar or anywhere separate from your paragraph section output, then you will need to use have_rows('paragraph') twice.
Update 1
So in response to your first comment, I created this example ACF flexible content field on a test environment.
Flexible content field named paragraphs and field location set to Post post type.
With a single block layout named paragraph with two sub fields title and name...
I then created a new post with this flexible content data...
I then ran this php code in my single.php...
<?php
// get our header
get_header();
?>
<main>
<div class="container">
<?php if(have_posts()): ?>
<?php while(have_posts()) : the_post(); ?>
<h1 class="pb-2 my-4 border-bottom"><?php the_title(); ?></h1>
<?php if(have_rows('paragraphs')): ?>
<div class="accordion" id="tableContentsAccordion">
<div class="card">
<div class="card-header" id="tableContents">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#tableContentsList" aria-expanded="true" aria-controls="tableContentsList">
Table of Contents
</button>
</h2>
</div>
<div id="tableContentsList" class="collapse show" aria-labelledby="tableContents" data-parent="#tableContentsAccordion">
<div class="card-body">
<?php while(have_rows('paragraphs')): the_row(); ?>
<?php $title = get_sub_field('title'); ?>
<?php echo $title; ?><br/>
<?php endwhile; ?>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if(have_rows('paragraphs')): ?>
<div class="row my-4">
<?php while(have_rows('paragraphs')): the_row(); ?>
<?php $title = get_sub_field('title'); ?>
<div class="col-12" <?php echo $title ? 'id="' . sanitize_title($title) . '"' : ''; ?>>
<?php echo $title ? '<h2>' . $title . '</h2>' : ''; ?>
<?php the_sub_field('text'); ?>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
</div>
</main>
<?php
// get our footer
get_footer();
And this is the tested output within the <main> html element...
This update code is the same as my first code example, but I've changed the flexible content field name from paragraph to paragraphs in this second update example, and I've also included the full singe.php post loop.
Not sure how my code outputted your However screenshot?
Let me know if you need more help.

How to add posts in the home page same as blog page with me selecting static page for each?

I'm new to WordPress, and I've created a custom template, I'm facing a problem when I try to fetch the posts to the front page (homepage).
In (dashboard->Reading) I set my homepage displays as a Static page and selected Home page as (home) and Post page as (posts).
In the index.php the code that's showing the posts in Posts page is :
<section class="recent-posts" id="recent-posts">
<div class="container">
<div class="title text-center">
<h1 class="title-blue">posts</h1>
</div>
<div class="row">
<?php
while(have_posts()) {
the_post();
?>
<div class="col-lg-6">
<div class="single-rpost d-sm-flex align-items-center" data-aos="fade-right"
data-aos-duration="800">
<div class="post-thumb">
<img class="img-fluid" src="<?php echo get_the_post_thumbnail_url(get_the_ID()); ?>" alt="post-1">
</div>
<div class="post-content text-sm-right">
<time datetime="<?php the_time('l, jS/n/Y'); ?>">
<?php the_time('l, jS/n/Y'); ?>
</time>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h3>
<p class="post-excerpt">
<?php echo wp_trim_words(get_the_excerpt(), 10); ?>
</p>
<p>
<!-- <a href="#"> -->
<?php echo get_the_category_list(' ') ?>
<!-- </a> -->
</p>
<a class="post-btn" href="<?php the_permalink(); ?>">
<i class="fa fa-arrow-left"></i>
</a>
</div>
</div>
</div>
<?php
}
wp_reset_query();
?>
</div>
<!-- Posts Navigation -->
</div>
</section>
<!-- Paginate through pages -->
<div class="pagination">
<?php echo paginate_links(); ?>
</div>
It works fine in posts page but when I copy the same code in page-home.php file it doesn't work and fetches no posts at all.
Sorry I'm a beginner, but I need help.
Thanks.
Try this
<?php
global $paged, $wp_query, $wp;
$args = wp_parse_args($wp->matched_query);
if ( !empty ( $args['paged'] ) && 0 == $paged ) {
$wp_query->set('paged', $args['paged']);
$paged = $args['paged'];
}
$temp = $wp_query;
$wp_query= null;
$wp_query = new WP_Query();
$wp_query->query('paged='.$paged.'&showposts=10&cat='.get_option('prototype_blog_cat'));
?>
<?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
<div class="col-lg-6">
<div class="single-rpost d-sm-flex align-items-center" data-aos="fade-right"
data-aos-duration="800">
<div class="post-thumb">
<img class="img-fluid" src="<?php echo get_the_post_thumbnail_url(get_the_ID()); ?>" alt="post-1">
</div>
<div class="post-content text-sm-right">
<time datetime="<?php the_time('l, jS/n/Y'); ?>">
<?php the_time('l, jS/n/Y'); ?>
</time>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h3>
<p class="post-excerpt">
<?php echo wp_trim_words(get_the_excerpt(), 10); ?>
</p>
<p>
<!-- <a href="#"> -->
<?php echo get_the_category_list(' ') ?>
<!-- </a> -->
</p>
<a class="post-btn" href="<?php the_permalink(); ?>">
<i class="fa fa-arrow-left"></i>
</a>
</div>
</div>
</div>
<?php endwhile; ?>
<span >
<?php echo paginate_links( array(
'prev_text' => '<span>Previous</span>',
'next_text' => '<span>Next</span>'
)); ?>
It should solve the problem.

Bootstrap accordion in WP ACF loop only opening/closing first panel

As title implies this code shows all the questions that i add to the loop/accordion but no matter which one i click on it only opens and closes the first and i cant tell why.
<div class="container">
<div class="row">
<div id="accordion" role="tablist" aria-multiselectable="false" class="py-4">
<?php
$counter = 0;
$loop = get_field('questions');
foreach($loop as $row) : ?>
<div class="card card-no-border card-no-shadow">
<div class="card-header" role="tab" id="heading<?php echo $counter++ ?>">
<h5 class="mb-0">
<a class="body2 uppercase bold" data-toggle="collapse" data-parent="#accordion"
href="#collapse<?php the_ID(); ?>"
aria-expanded="<?php echo $first; ?>" aria-controls="collapse<?php the_ID(); ?>">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
<span style='padding-right: 20px;'></span>
<?php echo $row['question_title']?>
</a>
</h5>
</div>
<div id="collapse<?php the_ID(); ?>" class="collapse<?php if ($first) {
echo "show";
} ?>" role="tabpanel"
aria-labelledby="heading<?php the_ID(); ?>">
<div class="card-block body2">
<?php echo $row['answer'] ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
I would say you need to look at your id's
href="#collapse<?php the_ID(); ?>"
id="collapse<?php the_ID(); ?>"
the_id function is outputting the current page id not the id of each loop/question
You could use your counter instead
id="collapse<?php echo $counter; ?>"

Bootstrap accordion in Wordpress

I'm trying to get Bootstrap's accordion to work in Wordpress, but I'm not sure what else I have to add in the loop. At the moment, its expanding the first panel only no matter which one I click, and not displaying any content.
<div class="panel-group" id="accordian" role="tablist" aria-multiselectable="true">
<?php
$args = array(
'post_type' => 'faq_question',
'category_name' => 'order',
'posts_per_page' => -1
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="<?php the_ID(); ?>">
<h4 class="panel-title">
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordian" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"><?php the_title();?></a>
</h4>
</div><!-- end panel heading -->
<div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="<?php the_ID(); ?>">
<div class="panel-body">
<p><?php the_content(); ?></p>
</div><!-- end panel body -->
</div><!-- end panel collapse -->
</div><!-- end panel default -->
<?php endwhile; wp_reset_query(); ?>
</div><!-- end panel group -->
Appreciate any help, thanks.
Code for Bootstrap 4 with area Closed
<!-- Accordion Collapse Bootstrap 4 -->
<div id="accordion" role="tablist" aria-multiselectable="true">
<?php
$args = array(
'post_type' => 'question',
'posts_per_page' => -1
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<div class="card">
<div class="card-header" role="tab" id="<?php the_ID(); ?>">
<h5 class="mb-0">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<?php the_ID(); ?>" aria-expanded="false" aria-controls="collapseOne">
<?php the_Title(); ?>
</a>
</h5>
</div>
<div id="collapse<?php the_ID(); ?>" class="collapse" role="tabpanel" aria-labelledby="heading<?php the_ID(); ?>">
<div class="card-block">
<?php the_Content(); ?>
</div>
</div>
<?php endwhile; wp_reset_query(); ?>
</div>
</div>
<!-- Accordion Collapse Bootstrap 4 -->
I suspect it's because you are ending up with multiple divs with the same id, #collapse1, so Bootstrap doesn't know which one you want to collapse. Try altering your code so that each collapsible panel has a unique id, like this;
(I've stripped out some of the extra attributes so I could more easily see what's going on)
<div class="panel-group" id="accordian">
<?php
$args = array(
'post_type' => 'faq_question',
'category_name' => 'order',
'posts_per_page' => -1
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordian" href="#collapse<?php the_ID(); ?>" ><?php the_Title(); ?></a>
</h4>
</div><!-- end panel heading -->
<div id="collapse<?php the_ID ?>" class="panel-collapse collapse">
<div class="panel-body">
<p><?php the_Content(); ?></p>
</div><!-- end panel body -->
</div><!-- end panel collapse -->
</div><!-- end panel default -->
<?php endwhile; wp_reset_query(); ?>
</div><!-- end panel group -->
<?php
$args = array(
'post_type' => 'Help',
'posts_per_page' => -1
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="<?php the_ID(); ?>">
<h4 class="panel-title">
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordian" href="#collapse<?php the_ID(); ?>" aria-expanded="false" aria-controls="collapseOne"><?php the_title();?></a>
</h4>
</div><!-- end panel heading -->
<div id="collapse<?php the_ID(); ?>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="<?php the_ID(); ?>">
<div class="panel-body">
<p><?php the_content(); ?></p>
</div><!-- end panel body -->
</div><!-- end panel collapse -->
</div><!-- end panel default -->
<?php endwhile; wp_reset_query(); ?>
</div><!-- end panel group -->

How do I create such a dynamic structure?HTML + PHP [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have the following PHP code, which dynamically generates content:
<div id="carousel-example" class="carousel slide hidden-xs" data-ride="carousel">
<div class="carousel-inner">
<div class="item active">
<div class="row">
<?php foreach ($this->getItems() as $_item): ?>
<div class="col-sm-3">
<a class="product-image" href="<?php echo $_item->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(75); ?>" width="75" height="75" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>
<div class="product-details">
<h3 class="product-name"><?php echo $this->escapeHtml($_item->getName()) ?></h3>
<?php echo $this->getPriceHtml($_item, true) ?>
<button type="button" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Add to Cart')) ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_item) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
<ul class="add-to-links">
<?php if ($this->helper('wishlist')->isAllow()) : ?>
<li><?php echo $this->__('Add to Wishlist') ?></li>
<?php endif; ?>
<?php if($_compareUrl=$this->getAddToCompareUrl($_item)): ?>
<li><span class="separator">|</span> <?php echo $this->__('Add to Compare') ?></li>
<?php endif; ?>
</ul>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
The above code outputs the following structure:
<div class="carousel-inner">
<div class="item active">
<div class="row">
<div class="col-sm-3">product1</div>
<div class="col-sm-3">product2</div>
<div class="col-sm-3">product3</div>
<div class="col-sm-3">product4</div>
<div class="col-sm-3">product5</div>
<div class="col-sm-3">product6</div>
.
.
.
etc..
</div>
</div>
</div>
I want to create this structure:
<div class="carousel-inner">
<div class="item active">
<div class="row">
<div class="col-sm-3">product1</div>
<div class="col-sm-3">product2</div>
<div class="col-sm-3">product3</div>
<div class="col-sm-3">product4</div>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-sm-3">product1</div>
<div class="col-sm-3">product2</div>
<div class="col-sm-3">product3</div>
<div class="col-sm-3">product4</div>
</div>
</div>
<div class="item">
<div class="row">
<div class="col-sm-3">product1</div>
<div class="col-sm-3">product2</div>
<div class="col-sm-3">product3</div>
<div class="col-sm-3">product4</div>
</div>
</div>
.
.
.
etc...
</div>
How do I change the dynamic structure so they get what they want?
Thanks in advance!
In order to create the structure you want:
You need to put <div class="item active"> in the foreach loop as well, because in order to have many items, you want that to be repeated many times too.
You have to remove active from <div class="item active"> as it will be added to every item, while we only want it to be in the first one.
You have to create a checking variable, so that the class active is added to the first item only.
Your final code should look like:
<div id="carousel-example" class="carousel slide hidden-xs" data-ride="carousel">
<div class="carousel-inner">
<?php
$i = 0; /* This is the checking variable */
$active; /* This is the variable containing the class 'active' */
foreach ($this->getItems() as $_item):
$i++; /* We increment the checking variable in each loop */
$active = ($i === 1) ? "active" : ""; /* We make the check */
?>
<div class="item <?php echo $active;?>">
<!-- The rest of your code as it is -->
</div>
<?php
endforeach;
?>
</div>
</div>
[EDIT]:
Considering your comment, in the case of wanting four products in each item, you would need to use another loop inside <div class = "row">.
The key part you are doing wrong in your code, however, that doesn't change, is that you don't loop the <div class = "item"> and that's way you have only one.
A preview of how your code inside <div class="item"> should be:
<div class="item <?php echo $active;?>">
<div class="row">
<?php
for ($i = 0; $i <= 4; ++$i):
?>
<div class="col-sm-3"><!-- The rest of the code --></div>
<?php
endfor;
?>
</div>
</div>
Try this:
<div id="carousel-example" class="carousel slide hidden-xs" data-ride="carousel">
<div class="carousel-inner">
<div class="item active">
<div class="row">
<?php foreach ($this->getItems() as $key=>$_item): // add $key in for loop
if($key != 0 && $key % 4 == 0) { // just add this code - it will check if 4 records has been displayed re create row div...
echo '</div><div class="row">';
}
?>
<div class="col-sm-3">
<a class="product-image" href="<?php echo $_item->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(75); ?>" width="75" height="75" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>
<div class="product-details">
<h3 class="product-name"><?php echo $this->escapeHtml($_item->getName()) ?></h3>
<?php echo $this->getPriceHtml($_item, true) ?>
<button type="button" title="<?php echo Mage::helper('core')->quoteEscape($this->__('Add to Cart')) ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_item) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
<ul class="add-to-links">
<?php if ($this->helper('wishlist')->isAllow()) : ?>
<li><?php echo $this->__('Add to Wishlist') ?></li>
<?php endif; ?>
<?php if($_compareUrl=$this->getAddToCompareUrl($_item)): ?>
<li><span class="separator">|</span> <?php echo $this->__('Add to Compare') ?></li>
<?php endif; ?>
</ul>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>

Categories