WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] How to output comma-separated array? (14 posts)

  1. daledude
    Member
    Posted 1 year ago #

    I've got this code, and I've almost got it working, but I can't a) get the code to output in the right place, and b) get it to output separately in each list item properly.

    I have a meta field with comma-separated data in it, and I want to explode the comma-separated data into individual list items.

    Here is the code I have so far:

    <div class="thumbnails"><h2>Additional Colors</h2><ul class="additional_colors"><?php
    	$attachments = get_posts( array(
    		'post_type' 	=> 'attachment',
    		'numberposts' 	=> -1,
    		'post_status' 	=> null,
    		'post_parent' 	=> $post->ID,
    		'post__not_in'	=> array( get_post_thumbnail_id() ),
    		'post_mime_type'=> 'image',
    		'orderby'		=> 'menu_order',
    		'order'		=> 'ASC'
    	) );
    	if ($attachments) {
    		$loop = 0;
    		$columns = apply_filters( 'product_thumbnails_columns', 3 );
    		$additional_colors = array(get_post_meta($post->ID, 'additional_colors', true));
    
    		foreach ( $attachments as $key => $attachment ) {
    
    			if ( get_post_meta( $attachment->ID, '_exclude_image', true ) == 1 )
    				continue;
    
    			$classes = array( 'zoom' );
    
    			if ( $loop == 0 || $loop % $columns == 0 )
    				$classes[] = 'first';
    
    			if ( ( $loop + 1 ) % $columns == 0 )
    				$classes[] = 'last';
    
    			if($additional_colors) {
             foreach ( $additional_colors as $additional_color ) {
    	         echo $additional_color;  }
    	         }
    			printf( '<li><a href="%s" title="%s" rel="thumbnails" class="%s">%s</a> %s</li>', wp_get_attachment_url( $attachment->ID ), esc_attr( $attachment->post_title ), implode(' ', $classes), wp_get_attachment_image( $attachment->ID, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) ), explode(',', $additional_color ) );
    
    			$loop++;
    		}
    	}
    ?>
    </ul>
    </div>

    It's the additional colors that I'm trying to get to work right. It outputs the code like this (summarized):

    <div class="thumbnails"><h2>Additional Colors</h2>
    <ul class="additional_colors">
    data,data,data,data
    <li><a><img></a> <a>Array</a></li>
    data1,data2,data3,data4
    <li><a><img></a> <a>Array</a></li>
    data1,data2,data3,data4
    <li><a><img></a> <a>Array</a></li>
    data1,data2,data3,data4
    <li><a><img></a> <a>Array</a></li>
    </ul>
    </div>

    When I want it to be (summarized):

    <div class="thumbnails"><h2>Additional Colors</h2>
    <ul class="additional_colors">
    <li><a><img></a> <a>data1</a></li>
    <li><a><img></a> <a>data2</a></li>
    <li><a><img></a> <a>data3</a></li>
    <li><a><img></a> <a>data4</a></li>
    </ul>
    </div>

    Basically it outputs all of the comma-separated stuff as one line, outside of the list item, and in the place of the list item, it just outputs "Array". I'm novice at PHP, just hacking away other code trying to learn. Any help?

  2. bcworkz
    Member
    Posted 1 year ago #

    I didn't really look at your code too closely, my comment is based on the appearance of "Array" in your output.

    Are you trying to output the result of explode()? It returns an array. You still need to separate out the array elements using a foreach construct.

  3. daledude
    Member
    Posted 1 year ago #

    Hi bcworkz,

    Thanks for the reply.

    I am attempting to do that, but I'm not quite sure how to do it yet.

    The $additional_colors = array(get_post_meta($post->ID, 'additional_colors', true)); seems to pull the data in properly from the database, which is a comma-separated line of text, such as "Pattern 01, Pattern 02, Pattern 03", etc.

    So below that, I have writen `if($additional_colors) {
    foreach ( $additional_colors as $additional_color ) {
    echo $additional_color; }
    }`

    And placed the additional_color part at the end in printf( '<li><a href="%s" title="%s" rel="thumbnails" class="%s">%s</a> %s</li>', wp_get_attachment_url( $attachment->ID ), esc_attr( $attachment->post_title ), implode(' ', $classes), wp_get_attachment_image( $attachment->ID, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) ), explode(',', $additional_color ) );

    I feel like the foreach is supposed to be wrapped around the printf but I do not think so... Looking at the code that was already there, the implode was done within the printf for the classes, so I assumed the explode must be done there also. But I am not sure. I can't figure out how to get it within the printf part.

  4. bcworkz
    Member
    Posted 1 year ago #

    implode() returns a string, so not a problem, unrelated to the explode(). I'm unsure of the data structure stored in the postmeta table, it looks to be a main array of sub-arrays. There's already a foreach construct for $additional_colors, assigning each element to $additional_color, but then there is the improper attempt to explode $additional_color.

    And if your output summary is correct, the postmeta value main array contains a single sub-array as it's only element, because the foreach $additional_colors seems to only loop once. If so, could have just done $additional_colors[0] instead of assigning $additional_color.

    This example will not show all data if there are more than one sub array in the main array. It will also fail if I misinterpreted the data structure that is stored. This should get you closer to what you're looking for, but may need more tweaking:

    if($additional_colors[0]) {
    	foreach ( $additional_colors[0] as $additional_color ) {
    	printf( '<li><a href="%s" title="%s" rel="thumbnails" class="%s">%s %s</a></li>', wp_get_attachment_url( $attachment->ID ), esc_attr( $attachment->post_title ), implode(' ', $classes), wp_get_attachment_image( $attachment->ID, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) ), $additional_color );
    }

    Replace this with everything between, but not including $classes[] = 'last'; and $loop++;
    I also moved the </a> tag to include the $additional_color text as part of the image link, guessing at your intention.

  5. daledude
    Member
    Posted 1 year ago #

    Hi bcworkz!

    Thanks for your assistance with this. I tried the steps you suggested, but the output remains the same as before your suggestions.

    To my knowledge it should loop through for each individual item. Each page will have a different amount of additional names.

    I've captured some screenshots to attempt to convey what is happening atm.

    Here is a screenshot of the entered in Custom Fields in WordPress:

    http://dalemoore.net/junk/custom-fields.png

    You can see it's just a comma-separated list here for the additional colors. I would like each of those to be spit out into individual list items, which I was trying to do with explode.

    Here is the current result:

    http://dalemoore.net/junk/current-result.png

    Where it currently says "Array", it should instead say one of the individual names from the comma-separated list. There are 3 names in the list, 3 thumbnails, so one name should go to each list item, rather than the current listing of all three names in each list item.

    I get this same result with my original and your modifications.

  6. keesiemeijer
    moderator
    Posted 1 year ago #

    Explode returns an array. You need to loop through it
    Example to give you an idea:

    $additional_colors = get_post_meta($post->ID, 'additional_colors', true);
    	if($additional_colors != '') {
    		$additional_colors = explode(',', $additional_colors);
    		if(is_array($additional_colors)){
    			foreach ($additional_colors as $additional_color) {
    				echo $additional_color;
    			}
    		}
    	}

    http://php.net/manual/en/function.explode.php

  7. daledude
    Member
    Posted 1 year ago #

    Hi keesiemeijer,

    I took a look at that link a day or two before posting here, and thought that I was understanding correctly. Explode takes the comma-separated string that it is pulling from my Custom Field additional_colors, and then separates them on the delimiter comma into individual values. Is this not correct?

    So my issue is that I am not looping through the array afterward? Or am I not to use explode at all? bcworkz does not include the explode in their example, so I am not seeing how the string becomes divided. Sorry for my confusion... I keep thinking I am close to my "AHA" moment where it all clicks, but it still eludes me...

  8. daledude
    Member
    Posted 1 year ago #

    OK, I have updated my code based on both of your help... and am one step closer I do believe!

    <div class="thumbnails"><h2>Additional Colors</h2><ul class="additional_colors"><?php
    
    	$attachments = get_posts( array(
    		'post_type' 	=> 'attachment',
    		'numberposts' 	=> -1,
    		'post_status' 	=> null,
    		'post_parent' 	=> $post->ID,
    		'post__not_in'	=> array( get_post_thumbnail_id() ),
    		'post_mime_type'=> 'image',
    		'orderby'		=> 'menu_order',
    		'order'			=> 'ASC'
    	) );
    	if ($attachments) {
    
    		$loop = 0;
    		$columns = apply_filters( 'product_thumbnails_columns', 3 );
    
    		foreach ( $attachments as $key => $attachment ) {
    
    			if ( get_post_meta( $attachment->ID, '_exclude_image', true ) == 1 )
    				continue;
    
    			$classes = array( 'zoom' );
    
    			if ( $loop == 0 || $loop % $columns == 0 )
    				$classes[] = 'first';
    
    			if ( ( $loop + 1 ) % $columns == 0 )
    				$classes[] = 'last';
    
    		    $additional_colors = get_post_meta($post->ID, 'additional_colors', true);
    	if($additional_colors != '') {
    		$additional_colors = explode(',', $additional_colors);
    		if(is_array($additional_colors)){
    			foreach ($additional_colors as $additional_color) {
    				printf( '<li><a href="%s" title="%s" rel="thumbnails" class="%s">%s</a> %s</li>', wp_get_attachment_url( $attachment->ID ), $additional_color, implode(' ', $classes), wp_get_attachment_image( $attachment->ID, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) ), $additional_color );
    			}
    		}
    	}		
    
    			$loop++;
    
    		}
    
    	}
    ?>
    </ul>
    </div>

    Below is a link to the current output!

    http://dalemoore.net/junk/progress-heckyea.png

    It is outputting the text where I want, FINALLY!, but it is outputting the thumbnails and the text three times... hmmm...

  9. keesiemeijer
    moderator
    Posted 1 year ago #

    You are looping through the attachments and then looping again through all the $additional_colors array.

    How did you attach a (custom field) metadata to the attachment? get_post_meta( $attachment->ID, '_exclude_image', true )

    Maybe add a "color name" custom field to the attachment also.

  10. daledude
    Member
    Posted 1 year ago #

    Hi keesiemeijer,

    The custom field is attached to the page, not to the attachments. I wasn't aware you could use custom fields with attachments.

  11. keesiemeijer
    moderator
    Posted 1 year ago #

    Because you use the attachent ID ($attachment->ID) I thought you had used some functions to have post meta on image attachments. This can be done:
    http://wordpress.stackexchange.com/questions/14500/custom-fields-for-attachments
    http://www.wpbeginner.com/wp-tutorials/how-to-add-additional-fields-to-the-wordpress-media-uploader/

    The problem I think is that there is no relation to the attachment images and your "additional_colors" custom field.

  12. daledude
    Member
    Posted 1 year ago #

    Ah... I think I see what you mean.

    I followed the steps in the WP Beginner tutorial, and changed the first field to my Additional Colors and left the photographer url one alone for now, and set it up as a plugin as they recommended and activated it. It does create a new custom field in the Media, but I'm now thinking this isn't how I need it to work...

    Is there not a way to do it attached to the page instead of the attachment, but still inject it into that attachment code? The code I have now seems to do it, it just does it x times, depending on the number of attachments/additional colors. Attaching it to the postmeta of the attachment isn't going to work. I'm needing the two to "technically" be separate, but output on the frontend together. The reasoning is that I'm uploading a CSV using a plugin to handle this, and there's an additional_colors column in it. The plugin requires all meta fields to be attached to the page.

  13. bcworkz
    Member
    Posted 1 year ago #

    You can get the output you want, keeping the attachments separate from color meta, but it's rather inelegant and a bit dangerous, as you have to manually assure the images and colors are in synch, whereas if the meta was associated with the attachements, you are assured the descriptions will always be in synch.

    As things stand, you need to get rid of the nested loops, instead step through the color names array as each image is output. Here is a generic example to illustrate the logic, you'll need to fill in all the error trapping and other niggly details:

    $loop = 0;
    $additional_colors = get_post_meta($post->ID, 'additional_colors', true);
    //insert any error trapping needed here
    $additional_colors = explode(',', $additional_colors);
    foreach ( $attachments as $key => $attachment ) {
      //insert code to deal with no image and classes here
      printf( '<li><a href="%s" title="%s" rel="thumbnails" class="%s">%s</a> %s</li>', wp_get_attachment_url( $attachment->ID ), $additional_colors[$loop], implode(' ', $classes), wp_get_attachment_image( $attachment->ID, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) ), $additional_colors[$loop] );
      $loop++;
    }
  14. daledude
    Member
    Posted 1 year ago #

    bcworkz -

    You are the (wo)man! That totally worked. Thanks to you and keesiemeijer for your assistance with this.

    I understand what you mean about how they can get out of sync. I will work on improving it as time allows, but since it will be handled through the spreadsheet it shouldn't be too difficult to keep in order.

    I'm comparing what I had with what you just said now to try to decipher the differences/what is happening/what went wrong.

    I just started a basic intro PHP book last night, http://www.sitepoint.com/books/phpmysql5/. It seems like a good introduction. If you have other recommendations, for more design-inclined people, I'd love to know about them. :) I've gotten by for a while just trial and error and Google, but ready to buckle down and learn proper. Thanks again!

Topic Closed

This topic has been closed to new replies.

About this Topic

Tags

No tags yet.