WordPress: Looping multiple custom fields from a post - php

I've recently come to a project where using custom fields would be pretty handy. It's for a restaurant and if I can get this right, I could use this bit of code for a few different sections of the site.
I'm using the Magic Fields 2 plugin and right now it's awesome, except for when it comes to displaying the fields I've created. Here's where I'm getting pretty lost.
For example, I have a post called "Specials" and that has a grouping called "Menu Item" and that group has two fields called "Name" and "Description". Basically name serves as the menu item name, and description will be a small blurb about the food item.
Here's the code in my theme for this section right now:
<div id="specials">
<?php
$query2 = get_post(28);
$title = $query2->post_title;
$itemname= get_post_meta($post->ID, 'menu_item_name', true);
$description = get_post_meta($post->ID, 'menu_item_description', true);
?>
<div id="specialstitle"><?php echo $title; ?></div>
<div class="stripebackbrown"> </div>
<div id="specialslist">
<?php while ( have_posts() ) : the_post();
echo '<span>'.$itemname.'</span>';
echo '<p>'.$description.'</p>';
endwhile;
wp_reset_query();
?>
</div>
</div><!-- end specials-->
Now there is a very good chance what I'm doing in the above code is completely wrong, if it is, please let me know.
What I'm experiencing with the above code however is it's pulling the very first group for that post.
So instead of something like:
Tomato Soup
description text here
Turkey Sandwich
description text here
Greek Salad
description text here
I'm getting:
Tomato Soup
description text here
Tomato Soup
description text here
Tomato Soup
description text here
So while the above code is technically working, it's not working properly at the same time.
Any help would be greatly appreciated!
EDIT:
I'm having some better success with this:
<div id="specials">
<?php
$query2 = get_post(28);
$title = $query2->post_title;
?>
<div id="specialstitle"><?php echo $title; ?></div>
<div class="stripebackbrown"> </div>
<div id="specialslist">
<?php $itemname = get_post_meta ($post->ID, 'menu_item_name', false); ?>
<?php $description = get_post_meta ($post->ID, 'menu_item_description', false); ?>
<?php foreach ($itemname as $itemname){
echo '<span>' .$itemname. '</span>';
echo '<p>' .$description. '</p>';
} ?>
</div>
</div><!-- end specials-->
However, I'm not sure how to add $description to that foreach loop. So right now it's listing out the menu names but adding "Array" where the description should be. Getting closer!

I think you want to do this like that:
<div id="specials">
<?php
$query2 = get_post(28);
$title = $query2->post_title;
?>
<div id="specialstitle"><?php echo $title; ?></div>
<div class="stripebackbrown"> </div>
<div id="specialslist">
<?php while ( have_posts() ) : the_post();
$itemname = get_post_meta(get_the_ID(), 'menu_item_name', true);
$description = get_post_meta(get_the_ID(), 'menu_item_description', true);
echo '<span>'.$itemname.'</span>';
echo '<p>'.$description.'</p>';
endwhile;
wp_reset_query();
?>
</div>

Found a solution:
<?php
$query2 = get_post(28);
$title = $query2->post_title;
?>
<div id="specialstitle"><?php echo $title; ?></div>
<div class="stripebackbrown"> </div>
<div id="specialslist">
<?php $itemname = get_post_meta ($post->ID, 'menu_item_name', false); ?>
<?php $description = get_post_meta ($post->ID, 'menu_item_description', false); ?>
<?php foreach (array_combine($itemname, $description) as $itemname => $description){
echo '<span>' .$itemname. '</span>';
echo '<p>' .$description. '</p>';
} ?>
</div>
</div><!-- end specials-->
This combines the two arrays created by $itemname and $description and loops them as many times as there are groups to loop.
#speccode, thanks so much for trying to help me, your reordering of my two lines got me heading in the right direction.

I know this is old but I had the same problem so I attempted to improved #speccode answers' a tiny bit and it seems to work:
<?php $itemnames = get_post_meta($post->ID, 'itemnames', false); ?>
<?php $descriptions = get_post_meta($post->ID, 'descriptions', false); ?>
<?php foreach (array_combine($itemnames, $descriptions) as $itemname => $description)
{
echo '<img src="'.$itemname.'"/>';
echo '<p>' .$description. '</p>';
}
?>
I also attempted abit of structuring in there (see below) but I can't guarantee the validity of the markup... anyone?
<?php $itemnames = get_post_meta($post->ID, 'itemnames', false); ?>
<?php $descriptions = get_post_meta($post->ID, 'descriptions', false); ?>
<?php foreach (array_combine($itemnames, $descriptions) as $itemname => $description)
{
echo '<div class="nameAndDescription"><img src="'.$itemname.'"/>';
echo '<p>' .$description. '</p></div>';
}
?>

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

Foreach loop works on font-page.php but not page.php?

I made a simple custom meta box plugin to display testimonials. I used a foreach loop to retrieve and display the data on my front-page.php page. However, using the exact same code on my page.php page returns
Warning: Invalid argument supplied for foreach().
What is the reason for this error and how can I fix it?
Here is the code used on both front-page.php and page.php:
<div id="testimonials">
<?php
$testimonials = get_post_meta($post->ID, "testimonials_data", true);
$counter = 0;
foreach($testimonials as $testimonial){
$counter++;
?>
<div class="testimonial <?php if($counter == 1){echo 'active-testimonial';}; ?>">
<p><?php echo $testimonial['field1']; ?></p>
<span><?php if(!empty($testimonial['field2'])){echo $testimonial['field2'];}; if(!empty($testimonial['field3'])){echo ' - ' . $testimonial['field3'];}; ?></span>
</div>
<?php }; ?>
</div>
EDIT:
To be more clear. My problem isn't that the foreach loop doesn't work at all. It works on the front-page.php but not page.php using the same code. How do I get it to work on both pages?
Your get_post_meta() $single attribute is set to true. Try setting it to false so that it always returns an array.
$testimonials = get_post_meta($post->ID, "testimonials_data", false);
get_post_meta( int $post_id, string $key = '', bool $single = false )
This function return (mixed) values
- It Will be an array if $single is false.
- It Will be value of meta data field if $single is true.
so if you have stored value in string testimonials_data except json_encoded.
then it will show you value in array only.
and apply some !empty check
<div id="testimonials">
<?php
$testimonials = get_post_meta($post->ID, "testimonials_data", true);
$counter = 0;
if(!empty($testimonials)){
foreach($testimonials as $testimonial){
$counter++;
?>
<div class="testimonial <?php if($counter == 1){echo 'active-testimonial';}; ?>">
<p><?php echo $testimonial['field1']; ?></p>
<span><?php if(!empty($testimonial['field2'])){echo $testimonial['field2'];}; if(!empty($testimonial['field3'])){echo ' - ' . $testimonial['field3'];}; ?></span>
</div>
<?php };
}?>
</div>

How to Get Post ID of Parent Loop in Nested Loop

I'm trying to figure out how to get the current post ID from my main wp_query loop to work in the nested loop..
I've added my loops below with most HTML removed to make it cleaner to see.
I need to replace the "16" where it says "$currentID = 16;" in the nested loop with the actual current post ID from the main loop.
<?php $related_query = new WP_Query( 'post_type=post&posts_per_page=-1' ); ?>
<?php if( $related_query->have_posts() ): ?>
<?php while ( $related_query->have_posts() ) : $related_query->the_post(); ?>
<?php the_ID(); ?>
<?php the_time('F j, Y'); ?>
<?php the_category(); ?>
<?php echo get_edit_post_link(); ?>
<?php echo get_post_meta(get_the_ID(), 'cf_meta-desc', true); ?>
<?php echo get_post_meta(get_the_ID(), 'cf_xray', true); ?>
<?php the_tags(); ?>
<ul>
<h4>Recommended Articles</h4>
<?php
$related_cfs = get_post_meta( get_the_ID(), 'cf_related' );
foreach($related_cfs as $related_cf) {
echo '<li>';
echo '<span class="related-links__id">' .$related_cf. '</span>';
echo '<span class="related-links__title"><a target="_blank" href="' .get_permalink($related_cf). '">' .get_the_title($related_cf). '</a></span>';
echo '<span class="related-links__edit"><a target="_blank" href="' .get_edit_post_link($related_cf). '">edit</a></span>';
echo '</li>';
} ?>
</ul>
<?php global $post;$backup=$post; //saves main query data before calling nested query ?>
<!-- BEGIN NESTED LOOP -->
<?php $referral_query = new WP_Query( 'meta_key=cf_related&posts_per_page=-1' ); ?>
<ol>
<h4 class="referring-links__header">Linkbacks (<?php
$meta_key = 'cf_related';
$currentID = 16;
$sql = "SELECT count(DISTINCT pm.post_id)
FROM $wpdb->postmeta pm
JOIN $wpdb->posts p ON (p.ID = pm.post_id)
WHERE pm.meta_key = '$meta_key'
AND pm.meta_value = '$currentID'
";
$count = $wpdb->get_var($sql);
echo "$count";
?>)
</h4>
<?php while ( $referral_query->have_posts() ) : $referral_query->the_post(); ?>
<?php
$currentID = 16;
$arrayCFrelated = get_post_custom_values('cf_related');
if (in_array($currentID, $arrayCFrelated))
{ ?>
<li>
<?php the_ID(); ?>
<?php the_title(); ?>
<?php echo get_edit_post_link(); ?>
</li>
<?php } ?>
<?php endwhile; ?>
</ol>
<!-- END NESTED LOOP -->
<?php $post=$backup; //brings back main query data before called nested query ?>
<?php echo get_post_meta(get_the_ID(), 'cf_img-feature', true); ?>
<?php endwhile; ?>
<?php else: ?>
<p class="center">Nothing found.</p>
<?php endif; ?>
<?php wp_reset_query(); ?>
The code you posted is very hard to read because it is all nested and distributed between opening and closing php tags.
First of all - You should consider to get familiar with functions and objects as an alternative to nest everything within the same loop. This will also help other developers who work with you to understand your code.
As for your problem. Try using other types of loops to get indices within the loop. For example:
for ($i1=0; $i1 < count($yourarray); $i1++) {
// ...
echo "index: $i1 <br />";
echo "value: {$yourarray[$i1]}";
}
or
foreach ($array AS $idx => $value) {
// ...
echo "index: $idx <br />";
echo "value: $value";
}
I know this question is old but I run into the same issue recently.
If you have a main loop and want to get the ID (or any other data) of the current post to be used inside of a nested wp_query then use the global $post object.
Using 'get_the_id()' inside of the nested wp_query will return the id of the current post in the nested wp_query and not the main query
Example:
$post_id = $post->ID;

Hover image description on image

I am no expert in PHP, javascript and js; so I am hoping someone can help me in easy language terms. I have just developed my first wordpress site and changed the code immensely, using this forum - thanks heaps so far!
The site: http://www.heritageglass.com.au
My request: text (description of image in media library) hovering over image.
Just like this website or this plugin, I have found several questions on this site that refer to my issue but they haven't seemed to help or I don't exactly know where to place this as it's grabbing the_title and I want the_description. Is there such a term?
PHP code in portfolio.php template:
<div data-id="post-<?php the_ID(); ?>" data-type="<?php
$categories = get_the_category();
$count = count($categories);
$i=1;
foreach($categories as $category) {
echo str_replace('-', '', $category->slug);
if ($i<$count) echo ' '; $i++;} ?>" class="post-<?php the_ID(); ?>
<?php
$categories = get_the_category();
foreach($categories as $category) {
echo str_replace('-', '', $category->slug).' '; } ?> project portfolio-item-wrap">
<div class="portfolio-item">
<?php if ( has_post_thumbnail() ) { ?>
<a class="portfolio-item-img" href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail( 'portfolio-image' ); ?></a>
<?php } ?>
<h4><?php the_title(); ?></h4>
<p>
<?php
$categories = get_the_category();
$temp = array();
foreach($categories as $category) {
if ($category->category_parent == 0) continue;
$temp[] = str_replace('-', '', $category->name);
}
echo implode(", ", $temp);
?>
</p>
</div>
</div>
I found this: Text over image using jquery and css
and added the script in the header.php. And used my .portfolio-item and .portfolio-item-img instead of .wrapper and .description - but that didn't do anything.
Hoping someone can lead me in the right direction?
Thanks!
Doing a search on the WordPress forums I found this from four years ago, not sure if it's what you need, but it might point you in the right direction.
$img_desc = $image->post_excerpt;
I think it will help you....
http://www.net-kit.com/10-jquery-caption-plugins/#
http://www.inwebson.com/jquery/jquery-image-hover-effects/
When editing a post, add two custome field, one for title, one for descritption.
Our code goes like this:
$dataType = '';
$divClass = '';
$categories = get_the_category();
$count = count($categories);
$i=1;
foreach($categories as $category) {
$dataType .= str_replace('-', '', $category->slug);
$divClass .= str_replace('-', '', $category->slug).' ';
if ($i<$count) $dataType.= ' ';
$i++;
}
$metaList = get_post_meta(get_the_ID());
$title = isset($metaList['title']) ? $metaList['title'] : '';
$description = isset($metaList['description']) ? $metaList['description'] : '';
// now we have title and description for the thumb!
?>
<div data-id="post-<?php the_ID(); ?>" data-type="<?php echo $dataType;?>"
class="post-<?php the_ID(); echo $divClass;?> project portfolio-item-wrap">
<div class="portfolio-item">
<?php if ( has_post_thumbnail() ) { ?>
<a class="portfolio-item-img" href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
<?php the_post_thumbnail( 'portfolio-image' ); ?>
</a>
<?php } ?>
<h4><?php the_title(); ?></h4>
<p>
<?php
$temp = array();
foreach($categories as $category) {
if ($category->category_parent == 0) continue;
$temp[] = str_replace('-', '', $category->name);
}
echo implode(", ", $temp);
?>
</p>
</div>
</div>
I have found the answer after sooooo much research.
This is the answer: How do I get the featured image description from my wordpress page?
enter the the_post_thumbnail_caption(); within the span tags and set your span tags class in css.
done.
Thanks to all of you for your help!

Echoing post meta in divs

Argh, this code is not pulling through my custom meta.
<?php
$my_meta = get_post_meta($post->ID,'_my_meta', true);
if (!empty($post_meta)) {
?>
<div class='client-testimonial'><?php echo $my_meta['testimonial']; ?></div>
<div class='client-name'><?php echo $my_meta['name']; ?></div>
<?php
}
?>
But the one below works, the only reason I am not using it is because it still shows the speach marks and dash when the fields are left empty in the admin panel
<?php
$my_meta = get_post_meta($post->ID,'_my_meta', true);
echo "<div class='client-testimonial'>". "'".$my_meta['testimonial']."'". "</div>";
echo "<div class='client-name'>". "-" .$my_meta['name']."</div>";
?>
Please help me on why the first code is not echoing the info. I am at the end of my tether!
You're checking if $post_meta is not empty, you don't have a variable named $post_meta
Change:
if (!empty($post_meta))
to
if (!empty($my_meta))
i think u have checked wrong variable.
<?php
$my_meta = get_post_meta($post->ID,'_my_meta', true);
if (isset($my_meta) && !empty($my_meta)) {
?>
<div class='client-testimonial'><?php echo $my_meta['testimonial']; ?></div>
<div class='client-name'><?php echo $my_meta['name']; ?></div>
<?php
}
?>

Categories