Out putting an ACF nested repeater within a foreach loop - php

I have a Food/Drinks menu on a website which the owner can fill-in the backend using an ACF nested repeater:
Level 1. section_container (parent repeater)
Level 2. section_heading (text field) sub_section_container (sub repeater)
Level 3. sub_section_heading (text field) food_item (sub sub repeater)
Level 4. item_name (text) item_description (text) price (text)
Each time a new parent repeater is created this contents should be placed within a sequential div called "section_0x" (the 'x' increases 1 with each addition). The content of this div will be visible in the tab content area with the calls 'tabcontent'.
In other words, the entire content of section_container (parent repeater) and it's sub fields should be wrapped in div called 'section_01' then and subsequent parent repeaters with be placed in sequential divs 'section_02' , 'section_03' etc., etc.
The Tab heading is also added automatically using the sub_field "section_heading". This is working correctly - so each time a parent repeater is created a new tabbed section is created on the front end and the heading is outputted.
However I'm having trouble outputting the entire contents of the nested repeater within the tabbed content area.
<?php
/**
* Template part for displaying the food menu
*
* #package GL_Apollo
*/
?>
<script>
function openSection(evt, sectionName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(sectionName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
<div class="food-menu-container">
<div class="menu-title"><?php the_field('menu_title'); ?> </div>
<!-- Tab links -->
<div class="food-menu-tab-container">
<div class="tab">
<?php
$counter_tab = 1;
if( have_rows('section_container') ) :
while( have_rows('section_container') ): the_row();
$section_name = array( get_sub_field('section_heading') );
foreach ($section_name as $section_names) {?>
<button class="tablinks" onclick="openSection(event, 'section_0<?php echo $counter_tab; ?>')">
<?php echo $section_names; ?>
</button>
<?php $counter_tab++; // increment before foreach ends
}
endwhile;
endif;
wp_reset_postdata();
?>
</div>
</div>
<!-- Food content -->
<div class="menu-section-container">
<?php
$counter = 1;
// check if the repeater field has rows of data
if( have_rows('section_container') ):
// loop through the rows of data
while ( have_rows('section_container') ) : the_row();
$section_container = get_field('section_container');
if( have_rows('sub_section_container') ):
// loop through the rows of data
while ( have_rows('sub_section_container') ) : the_row();
$sub_section_container = get_field('sub_section_container');
$sub_head = get_sub_field('sub_section_heading');
if( have_rows('food_item') ):
// loop through the rows of data
while ( have_rows('food_item') ) : the_row();
$item = get_sub_field('item_name');
$price = get_sub_field('price');
$description = get_sub_field('item_description');
$menu_content = array (
"<div>$section_container</div>" . "<div>$sub_section_container</div>" . "<div class='sub_head'>$sub_head</div>" . "<div class='item'>$item</div>" . "<div class='price'>$price</div>" . "<div class='description'>$description</div>"
);
foreach ($menu_content as $menu_contents); { ?>
<div id="section_0<?php echo $counter; ?>" class="tabcontent">
<?php echo($menu_contents) ?>
</div>
<?php $counter++; // increment before foreach ends
}
endwhile;
endif;
endwhile;
endif;
endwhile;
endif;
echo '<pre>';
var_dump( $menu_contents );
echo '</pre>';?>
</div> <!-- section -->
</div> <!-- menu-section-container -->
<span class="btn" data-glf-cuid="0c1de6b2-1ca9-4202-b790-3cd5a62af2b3" data-glf-ruid="9e6118c3-d144-4511-973e-d7d7f7418e1a" ><?php the_field('order_button'); ?></span>
<script src="https://www.fbgcdn.com/widget/js/ewm2.js" deferasync ></script>
</div> <!-- food-menu-container -->

Related

While Loop displays arguments inside the first argument

I have a while loop created to display all my wordpress posts. The issue is that all the posts (except the first) appear inside the first post.
I've check my div structures and I couldn't find any issues.
The loop is working, but the div isn't showing in the right place.
<div class="slider-vertical">
<!-- This is the main loop for the posts -->
<?php
$count = 0;
while ( $all_posts->have_posts() ) : $all_posts->the_post();
$count++;
// Variabled for the specific fields (color, 3D objects and so on...)
$fond_couleur = get_field('fond_de_couleur_hex');
$visuel_3D = get_field('source_iframe_3d');
$visuel_3D_2 = get_field('source_iframe_3d_2');
// get_template_part( 'template-parts/content', 'portfolio' );
$content = get_the_content();
$content = apply_filters( 'the_content', $content );
$content = str_replace( ']]>', ']]>', $content );
$gallerieArray = get_field('image_galerie');
$title = get_the_title($post);
?>
<!-- HTML structure for the posts - this is displayed, but only the first one is at the right place -->
<?php
echo '<div class="post-numero';
if($count == 1){
echo ' actif';
}
echo '">';
?>
<!-- DIV that contains the 3D object -->
<div class="visuel-3d" style="background:<?php echo $fond_couleur;?>;">
<!-- Injecting the 3D Object via an iframe -->
<div class="slider-horizontal">
<?php echo '<span class="post-horizontal actif">'. $visuel_3D .'</span>';?>
<?php if($visuel_3D_2){
echo '<span class="post-horizontal">'. $visuel_3D_2 .'</span>';
} ?>
</div>
<h2 class="titrePost"><?php echo $title; ?></h2>
</div>
<!-- Cross used to close the rightside menu -->
<span class="arrow-right-sidebar">x</span>
<!-- HTML structure for the rightside menu -->
<div class="right-sidebar-content foo">
<div class="right-top">
<h2 style="text-align: center;"><?php echo $title; ?></h2>
</div>
<div class="right-bottom">
<div><?php echo $content ?></div><!-- That is where the next posts of the while loop get printed -->
<div class="gallerie-sidebar-full">
<?php // loop for the image gallery at the bottom of the rightside menu
if ($gallerieArray == true){
foreach($gallerieArray as $key => $val){
$gallerieImages[] = $val["url"];
}
$idg = 0;
foreach ($gallerieImages as $val){
echo '<img id="id-'. $title .'-'. $idg .'" class="gallerie-sidebar" src="'. $val .'">';
$idg += 1;
}
}
?>
</div>
</div>
</div>
</div>
<?php
endwhile;
?>
</div>
What is expected is 4 different posts inside the "slider-vertical" div displayed at the same level in the HTML structure.
The actual result is the first post at the correct level and then the next posts 2 levels deeper inside the first post.
this kind of problem occurs when there is a not properly closed HTML tag on the first execution of the loop, try to use a short statement syntax
echo '<div class="post-numero'. (($count == 1)? ' actif' : '').'">;
check also the content printed by <?php echo $content ?> of the first post, may contains an open HTML tag.
You can easily check the generated code using the souce view (CTRL+U) in Firefox that highlights in red the wrong HTML closing tags

Different layout for nth rows ACF REPEATER

I am using ACF repeater to display images, I want to achieve layout so that 1 - 2 - 3 elements go with col-lg-4 grid and 4-5-6-7 go with col-lg-3 grid and so on, repeating that layout for all items
I've tried using but it's to get 3 elements into 1 div
mostly my layout will be
first row 3x col-lg-4
second row 4x col-lg-3
third row 3x col-lg-4
fourth row 4x col-lg-3
<?php
// check if the repeater field has rows of data
if( have_rows('gallery_repeater') ):
// loop through the rows of data
// add a counter
$count = 0;
$group = 0;
while ( have_rows('gallery_repeater') ) : the_row();
// vars
$teacher_bio = get_sub_field('image');
if ($count % 3 == 0) {
$group++;
?>
<div id="teachers-<?php echo $group; ?>" class="cf group-<?php echo $group; ?>">
<?php
}
?>
<div class="teacher">
<img src="<?php the_sub_field('image'); ?>" />
<?php echo $teacher_bio; ?>
</div><!-- .teacher -->
<?php
if ($count % 3 == 2) {
?>
</div><!-- #teachers -->
<?php
}
$count++;
endwhile;
else :
// no rows found
endif;
?>
Hi Please check below code for reference :
$gallery_repeater = get_field('gallery_repeater');
foreach (array_chunk($gallery_repeater, 7) as $key => $value) {
foreach ($value as $k => $val) {
$class = $k < 3 ? 'col-lg-3' : 'col-lg-4';
echo '<div class="'.$class.'"> <img src="'.$val['image'].'" />'.$val['teacher_bio'].'</div>';
}
}

Tab contents with ACF Nested Repeater

I have a nested ACF repeater:
section_container (parent repeater)
section_heading (text field) sub_section_container (sub repeater)
sub_section_heading (text field) food_item (sub sub repeater)
item_name (text) item_description (text) price (text)
All of which needs to be wrapped in div Section_01 this will then appear in the first "tab" section contents, with the tab heading taken from the text field "section_heading". Section headings will be things like, Starters / Mains / Sweets / Drinks
If the user adds a row in the back end "section_container" this repeats all of the above, but this needs to be wrapped in a div called Section_02 in order for it to be displayed in the next tab. This is achieved via a counter - as I don't want a pre determined number of sections / rows.
At the moment rather than ALL of the content from parent repeater "section_container" being displayed within a single div, it's taking each single array output and then wrapping that content in a div.
What I get is:
<div class="section_01">
Starter item 1 Start Price 1 Starter Description 1
</div>
<div class="section_02">
Starter item 2 Start Price 2 Starter Description 2
</div>
What I want is:
<div class="section_01">
Starter item 1 Start Price 1 Starter Description 1
Starter item 2 Start Price 2 Starter Description 2
</div>
<div class="section_02">
Mains item 1 Mains Price 1 Mains Description 1
Mains item 2 Mains Price 2 Mains Description 2
</div>
<?php
/**
* Template part for displaying the food menu
*
* #package GL_Apollo
*/
?>
<script>
function openSection(evt, sectionName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(sectionName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
<div class="food-menu-container">
<div class="menu-title"><?php the_field('menu_title'); ?> </div>
<!-- Tab links -->
<div class="food-menu-tab-container">
<div class="tab">
<?php
$counter_tab = 1;
if( have_rows('section_container') ) :
while( have_rows('section_container') ): the_row();
$section_name = array( get_sub_field('section_heading') );
foreach ($section_name as $section_names) {?>
<button class="tablinks" onclick="openSection(event, 'section_0<?php echo $counter_tab; ?>')">
<?php echo $section_names; ?>
</button>
<?php $counter_tab++; // increment before foreach ends
}
endwhile;
endif;
wp_reset_postdata();
?>
</div>
</div>
<!-- Food content -->
<div class="menu-section-container">
<?php
$counter = 1;
// check if the repeater field has rows of data
if( have_rows('section_container') ):
// loop through the rows of data
while ( have_rows('section_container') ) : the_row();
if( have_rows('sub_section_container') ):
// loop through the rows of data
while ( have_rows('sub_section_container') ) : the_row();
$sub_head = get_sub_field('sub_section_heading');
if( have_rows('food_item') ):
// loop through the rows of data
while ( have_rows('food_item') ) : the_row();
$item = get_sub_field('item_name');
$price = get_sub_field('price');
$description = get_sub_field('item_description');
$menu_content = array (
"<div class='sub_head'>$sub_head</div>" . "<div class='item'>$item</div>" . "<div class='price'>$price</div>" . "<div class='description'>$description</div>"
);
foreach ($menu_content as $menu_contents); { ?>
<div id="section_0<?php echo $counter; ?>" class="tabcontent">
<?php echo $menu_contents ; ?>
</div>
<?php $counter++; // increment before foreach ends
}
endwhile;
endif;
endwhile;
endif;
endwhile;
endif;
echo '<pre>';
var_dump( $menu_contents );
echo '</pre>';
?>
</div> <!-- section -->
</div> <!-- menu-section-container -->
<span class="btn" data-glf-cuid="0c1de6b2-1ca9-4202-b790-3cd5a62af2b3" data-glf-ruid="9e6118c3-d144-4511-973e-d7d7f7418e1a" ><?php the_field('order_button'); ?></span>
<script src="https://www.fbgcdn.com/widget/js/ewm2.js" deferasync ></script>
</div> <!-- food-menu-container -->
Forgive me for trying to understand the question however, is it simply the case you're wanting to wrap a div around each food item section rather than each food item?
If this is the case, you can add a div between the if and while statements for the food_item.
<?php $foodItem == 1; ?>
<?php if( have_rows('food_item') ): ?>
<div class="section_<?php echo $foodItem; ?>">
<?php while( have_rows('food_item') ): the_row(); ?>
<?php the_field('item_name'); ?>
<?php the_field('item_description'); ?>
<?php the_field('price'); ?>
<?php $foodItem++; ?>
<?php endwhile; ?>
</div>
<?php endif; ?>
This should give you the outcome of:
<div class="section_1">
Starter item 1 Start Price 1 Starter Description 1
Starter item 2 Start Price 2 Starter Description 2
</div>
<div class="section_2">
Starter item 1 Start Price 1 Starter Description 1
Starter item 2 Start Price 2 Starter Description 2
</div>
If I have missed something, let me know.
M. Ferguson is correct in what he says, however the tabs section could also do with some cleaning up. Here is the complete cleaned up code. This should work if it does not let me know.
<script>
function openSection(evt, sectionName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(sectionName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
<div class="food-menu-container">
<div class="menu-title"><?php the_field('menu_title'); ?> </div>
<!--Menu Tabs-->
<div class="food-menu-tab-container">
<?php $tabNumber = 1;
if( have_rows('section_container') ) :
<div class="tab">
while( have_rows('section_container') ): the_row();
$section_name = get_sub_field('section_heading');?>
<button class="tablinks" onclick="openSection(event, 'section_0<?php echo $tabNumber; ?>')">
<?php echo $section_name; ?>
</button>
<?php $counter_tab++;
endwhile;?>
</div>
<?php endif;?>
</div>
</div>
<div class="menu-section-container">
<!--Food Menu-->
<?php $foodItem = 1; ?>
<?php if( have_rows('food_item') ): ?>
<div class="section_0<?php echo $foodItem; ?> section">
<?php while( have_rows('food_item') ): the_row(); ?>
<!--Add styling: .section .section_inner > div {display:inline-block;}-->
<div class="section_inner_0<?php echo $foodItem; ?> section_inner">
<div class="sub_head"><?php get_sub_field('sub_section_heading');?> </div>
<div class="item"><?php the_field('item_name'); ?> </div>
<div class="price"><?php the_field('item_description'); ?> </div>
<div class="description"><?php the_field('price'); ?></div>
<?php $foodItem++; ?>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</div>
</div>
<span class="btn" data-glf-cuid="0c1de6b2-1ca9-4202-b790-3cd5a62af2b3" data-glf-ruid="9e6118c3-d144-4511-973e-d7d7f7418e1a" ><?php the_field('order_button'); ?></span>
<script src="https://www.fbgcdn.com/widget/js/ewm2.js" deferasync ></script>
Outcome HTML:
<div class="section_01">
<div class="section_inner_01 section_inner">
<div class="sub_head">Starter </div><div class="item">item 1 </div><div class="item_price">Start Price 1 </div><div class="description">Starter Description 1</div>
</div>
<div class="section_inner_01 section_inner">
<div class="sub_head">Starter </div><div class="item">item 2 </div><div class="item_price">Start Price 2 </div><div class="description">Starter Description 2</div>
</div>
</div>
<div class="section_02">
<div class="section_inner_02 section_inner">
<div class="sub_head">Starter </div><div class="item">item 1 </div><div class="item_price">Start Price 1 </div><div class="description">Starter Description 1</div>
</div>
<div class="section_inner_02 section_inner">
<div class="sub_head">Starter </div><div class="item">item 2 </div><div class="item_price">Start Price 2 </div><div class="description">Starter Description 2</div>
</div>
</div>
Outcome Front End:
Starter item 1 Start Price 1 Starter Description 1
Starter item 2 Start Price 2 Starter Description 2

Change Post Title Color dynamically in wordpress

i want to change post title color dynamically like this
<h3 class="green">Post title 1</h3>
<p>post Text</p>
<h3 class="blue">Post title 1</h3>
<p>post Text</p>
<h3 class="orange">Post title 1</h3>
<p>post Text</p>
<h3 class="red">Post title 1</h3>
<p>post Text</p>
<h3 class="yello">Post title 1</h3>
<p>post Text</p>
I limit posts_per_pge = 5, so when a new post ad its title color change in GREEN
Any idea how can i do this any........idea
You can do it by simply as:
first add a custom field with each post and decide which color for that post title
now just get this meta field in your query and change title style
<h2 style="color:<?php echo $meta_color; ?>"> <?php the_title(); ?> </h2>
may this help you...
Count post with a variable and when its 5 return to zero. Then use that to echo diffetent classes. For example something like:
$post_count=0;
$class = "";
if (have_posts() ){....
$post_count .= 1;
if($post_count == 1) $class = "green";
// same with 2, 3, 4 and so on
<h3 class="<? echo $class; ?>">title</h3>
<p>post Text</p>
if($post_count == 4) $post_count = 0;
}// end loop
While Dk-Macadamias solution is a bit more flexible (allowing you to change color on a per-post basis) a more automatic alternative would be to let the post order decide and output the color from a predetermined array.
In your template file:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h3 class="<?php echo get_post_color_class(); ?>"><?php the_title(); ?></h3>
<?php endwhile; endif; ?>
In your functions.php
function get_post_color_class() { //Declare our custom function
global $wp_query; //Import the global $wp_query object
$colors = array('green','blue','orange','red','yellow'); //Declare our array of colors
return $colors[$wp_query->current_post]; //Return the item in our array with the same index as the current post in the loop
}
If you want to alter between two colors you can do it like this. This function will actually count at all posts on a page and not look at the global post ID
function get_post_color_class() { //Declare our custom function
global $wp_query; //Import the global $wp_query object
$colors = array('#D8D32B','#D12F4E'); //Declare our array of colors
return $colors[($wp_query->current_post % 2 != 0) ? 0 : 1];
//Return the item in our array with the same index as the current post in the loop
}
In my case I wanted to alter and change the border-color of a post in wordpess. I did it like this in the content.php:
<article id="post-<?php the_ID(); ?>" <?php post_class( ); ?>
style="border-left-color:<?php echo get_post_color_class(); ?>" >
More than two colors goes like this:
function get_post_color_class() { //Declare our custom function
global $wp_query; //Import the global $wp_query object
$colors = array('#D8D32B','#D12F4E', '#009562'); //Declare our array of colors
if($wp_query->current_post % 3 == 0){
return $colors[2];
}
if($wp_query->current_post % 2 == 0){
return $colors[1];
}
return $colors[0];
}
Alternativly you could resolve it with CSS:
http://www.w3schools.com/cssref/sel_nth-of-type.asp
This should be more elegant and faster.

How to edit php file and return wordpress blog entries in multiple columns?

I am using the same theme as this site http://foreignpolicydesign.com/v3/. However, my test site does not distribute the blog entries in columns
What might be causing this problem? I am suspecting it is whatever sets the $col_class to set the x1 ~ xN, but I cannot find the source of this variable.
Here is the code:
<?php include (TEMPLATEPATH . '/tanzaheader.php');
// [grid column setting]
$col_w = 200; // width of grid column
$gap_w = 35; // padding + margin-right (15+15+5)
$max_col = 5; // max column size (style div.x1 ~ xN)
// * additional info *
// check also "style.css" and "header.php" if you change $col_w and $gap_w.
// - style.css:
// div.x1 ~ xN
// div.grid-item
// div.single-item
// ... and maybe #sidebar2 li.widget.
// - header.php:
// gridDefWidth in javascript code.
//
// if you want to show small images in main page always, set $max_col = 1.
// [grid image link setting]
$flg_img_forcelink = true; // add/overwrite a link which links to a single post (permalink).
$flg_img_extract = false; // in single post page, extract thumbnail link to an original image.
$flg_obj_fit = 'large-fit'; // none | small-fit | large-fit ... how to fit size of object tag.
// * additional info *
// if you use image popup utility (like Lightbox) on main index, set $flg_img_forcelink = false;
?>
<!-- <?php if (is_singular()) : $is_top_single = true; /* wide column for single post */ ?> -->
<?php /* make a new query for grid items (in single page) */
$new_query_arg = 'paged='.$paged;
// use this code if you want filter items by category.
$arr_catID = array(20);
foreach( get_the_category() as $cat) $arr_catID[] = $cat->cat_ID;
if ( count($arr_catID) ) $new_query_arg .= '&cat=' . join(',', $arr_catID);
query_posts($new_query_arg);
?>
<!-- <?php endif; /* end of if is_singular() */ ?> -->
<div id="grid-wrapper">
<?php if (have_posts()) :
if ( $is_top_single ) $GLOBALS['more'] = false; //important
while (have_posts()) : the_post(); ?>
<?php
$content = get_the_content('Details ยป');
$content = apply_filters('the_content', $content);
list($col_class, $grid_img) = adjust_grid_image(
$content,
$col_w,
$gap_w,
$max_col,
$flg_img_forcelink,
$flg_obj_fit
);
?>
<div <?php post_class('grid-item ' . $col_class); ?> id="post-<?php the_ID(); ?>">
<h2 class="post-title"><?php the_title(); ?></h2>
<?php if ($grid_img) echo '<div class="grid-image">' . $grid_img . '</div>'; ?>
<div class="post-body">
<?php
$content = preg_replace('/<img(?:[^>]+?)>/', '', $content); // remove img tags
$content = preg_replace('/<a([^>]+?)><\/a>/', '', $content); // remove empty a tags
$content = preg_replace('/<p([^>]*?)><\/p>/', '', $content); // remove empty p tags
$content = preg_replace('/<object(.+?)<\/object>/', '', $content); // remove object tags
echo $content;
?>
</div>
<p class="post-meta">
Published on <?php the_time( get_option('date_format') ); ?> <?php the_time(); ?>.<br />
Filed under: <?php the_category(', ') ?> <?php the_tags('Tags: ', ', '); ?>
<?php edit_post_link(__("Edit This"), '(', ')'); ?><br />
<?php /*comments_popup_link();*/ ?>
</p>
</div>
<?php endwhile; else : ?>
<div class="grid-item x1">
<h2>Not Found</h2>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
</div>
<?php endif; ?>
</div><!-- /grid-wrapper -->
<div class="pagination" id="grid-pagination">
<?php paginate_links2($is_top_single); ?>
</div>
<?php /* reset the query */
wp_reset_query();
?>
</div><!-- /container -->
<?php include (TEMPLATEPATH . '/tanzafooter.php'); ?>
The columns are not created by PHP code, they are created dynamically by a jQuery plugin.
Your theme is referencing it here:
http://wpbeta.nfshost.com/wp-content/themes/js/jquery.vgrid.0.1.4-mod.js
But that returns a 404 file not found error.

Categories