I am using CMB2 file_list for uploading photos e.g. photo gallery. On the home page I need to get only the first photo and not the entire gallery. Below is the function to get all the photo. How can i retrieve only the first photo in the list?
function cmb2_output_file_list( $file_list_meta_key, $img_size = 'medium' ) {
$files = get_post_meta( get_the_ID(), $file_list_meta_key, 1 );
echo '<div class="file-list-wrap">';
foreach ( (array) $files as $attachment_id => $attachment_url ) {
echo '<div class="file-list-image">';
echo wp_get_attachment_image( $attachment_id, $img_size );
echo '</div>';
}
echo '</div>';
}
cmb2_output_file_list( 'wiki_test_file_list', 'small' );
You'd use something like this, make sure to change the meta key to the correct one, this will get the ID and URL of first file in the list:
$file_list_meta_key = 'wiki_test_file_list';
$files = get_post_meta( get_the_ID(), $file_list_meta_key, 1 );
$first_id = key($files);
$first_url = reset($files);
Related
I want to get the 'title' of each image to display underneath each image in the Woocommerce product gallery. Not the main image, but the smaller clickable thumbnails.
All of my images currently have titles set.
I have looked in product-thumbnails.php and have found this code:
if ( $attachment_ids && has_post_thumbnail() ) {
foreach ( $attachment_ids as $attachment_id ) {
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', wc_get_gallery_image_html( $attachment_id ), $attachment_id );
}
}
I believe this is what I need to edit but I am not sure what to add.
I also found this post where a similar thing has been asked but for captions Show caption under product gallery in WooCommerce, however it doesn't work when I add it
Any ideas?
EDIT
So I have copied the function from wc-template-functions.php into my child themes functions.php file:
function wc_get_gallery_image_html( $attachment_id, $main_image = false ) {
$flexslider = (bool) apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) );
$gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' );
$thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) );
$image_size = apply_filters( 'woocommerce_gallery_image_size', $flexslider || $main_image ? 'woocommerce_single' : $thumbnail_size );
$full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) );
$thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size );
$full_src = wp_get_attachment_image_src( $attachment_id, $full_size );
$image = wp_get_attachment_image( $attachment_id, $image_size, false, array(
'title' => get_post_field( 'post_title', $attachment_id ),
'data-caption' => get_post_field( 'post_excerpt', $attachment_id ),
'data-src' => $full_src[0],
'data-large_image' => $full_src[0],
'data-large_image_width' => $full_src[1],
'data-large_image_height' => $full_src[2],
'class' => $main_image ? 'wp-post-image' : '',
) );
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . '</div>';
}
I also renamed the function wc_get_gallery_image_with_title_html as well as changing the return line to this:
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
It doesn't seem to work. However, if i add in the word TEST in place of $imageTitle in the return line above to see if anything will appear, the word TEST does appear below every image.
The word test doesnt appear under each thumbnail though, it appears under the main gallery image.
What am I missing or doing wrong here?
EDIT
Now the title shows thanks to Zipkundan's help, but it shows under the main image and not under each thumbnail. How can I move it to show under each relevant thumbnail?
Here, "wc_get_gallery_image_html( $attachment_id )" (one of the argument in the filter) is what outputs the final html. This is a function defined in "wc-template-functions.php". Thus you can not alter this function. You can see the function code at following URL:
http://woocommerce.wp-a2z.org/oik_api/wc_get_gallery_image_html/
Well, here's some hint for you to workout your way.
Hope you are using child theme. Copy the function code (the function which is passed as argument in filter) in your child theme's "functions.php" file. Name the function something different, say "wc_get_gallery_image_with_title_html". Alter that code to append the image title in the 'return' statement. Something like:
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
Where, $imageTitle will be the title of the image wrapped into some html tag like 'span' or 'p'.
Then copy the file "product-thumbnails.php" into you child theme and replace the original function argument with the new function you have created. So the code becomes like this:
if ( $attachment_ids && has_post_thumbnail() ) {
foreach ( $attachment_ids as $attachment_id ) {
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', wc_get_gallery_image_with_title_html( $attachment_id ), $attachment_id );
}}
Hope this helps.
Update (after your Edit)
Hi Kiki,
You were missing output of the image title in the function. Following is the updated function.
function wc_get_gallery_image_with_title_html( $attachment_id, $main_image = false ) {
$flexslider = (bool) apply_filters( 'woocommerce_single_product_flexslider_enabled', get_theme_support( 'wc-product-gallery-slider' ) );
$gallery_thumbnail = wc_get_image_size( 'gallery_thumbnail' );
$thumbnail_size = apply_filters( 'woocommerce_gallery_thumbnail_size', array( $gallery_thumbnail['width'], $gallery_thumbnail['height'] ) );
$image_size = apply_filters( 'woocommerce_gallery_image_size', $flexslider || $main_image ? 'woocommerce_single' : $thumbnail_size );
$full_size = apply_filters( 'woocommerce_gallery_full_size', apply_filters( 'woocommerce_product_thumbnails_large_size', 'full' ) );
$thumbnail_src = wp_get_attachment_image_src( $attachment_id, $thumbnail_size );
$full_src = wp_get_attachment_image_src( $attachment_id, $full_size );
$image = wp_get_attachment_image( $attachment_id, $image_size, false, array(
'title' => get_post_field( 'post_title', $attachment_id ),
'data-caption' => get_post_field( 'post_excerpt', $attachment_id ),
'data-src' => $full_src[0],
'data-large_image' => $full_src[0],
'data-large_image_width' => $full_src[1],
'data-large_image_height' => $full_src[2],
'class' => $main_image ? 'wp-post-image' : '',
) );
$imageTitle = '<span>' . esc_html( get_the_title($attachment_id) ) . '</span>';
return '<div data-thumb="' . esc_url( $thumbnail_src[0] ) . '" class="woocommerce-product-gallery__image">' . $image . $imageTitle . '</div>';
}
Note the line before 'return' statement.
Try using the above function and don't forget to change the argument function in "product-thumbnails.php".
Also, once you get the image title text displayed, you might need to add some css rules for the text to display properly.
Hope this works.
Since the gallery thumbnail images are dynamically generated and appended via javascript, it can be customized only via javascript.
Following javascript custom function will append the title of product image in the gallery to its respective thumbnail in gallery navigation.
jQuery(window).load(function(){
if( jQuery('body').hasClass('single-product') ){
var imgtitles = [];
jQuery('.woocommerce-product-gallery__wrapper').children('div').each(function(){
var imgTitle = jQuery(this).find('a').find('img.wp-post-image').attr('title');
console.log(imgTitle);
imgtitles.push(imgTitle);
});
if( jQuery('ol.flex-control-nav').length && jQuery('ol.flex-control-nav').children().length>1 ){
for(i=0; i<imgtitles.length; ++i){
jQuery('ol.flex-control-nav li:nth-child('+(i+1)+')').append('<span class="flexthum-title">'+imgtitles[i]+'</span>');
}
}
}});
You can see a working example here.
http://woocom.stuprohosting.in/product/vneck-tee/
If this gives you desired result, then I would recommend to discard changes you have made in "functions.php" and "product-thumbnails.php" which I suggested in previous answer.
I have used plugin "Header and Footer Scripts" to add this custom function in website footer. https://wordpress.org/plugins/header-and-footer-scripts/
jQuery(window).load(function(){
if( jQuery('body').hasClass('single-product') ){
var imgtitles = [];
jQuery('.woocommerce-product-gallery__wrapper').children('div').each(function(){
var imgTitle = jQuery(this).find('a').find('img').attr('data-caption');
console.log(imgTitle);
imgtitles.push(imgTitle);
});
if( jQuery('ol.flex-control-nav').length && jQuery('ol.flex-control-nav').children().length>1 ){
for(i=0; i<imgtitles.length; ++i){
jQuery('ol.flex-control-nav li:nth-child('+(i+1)+')').append('<span class="flexthum-title">'+imgtitles[i]+'</span>');
}
}
}});
I have a problem to receive the first image of the woocommerce gallery, if the post thumbnail is missing. I want to show the post thumbnail, if this is missing, the first image of the WooCommerce gallery and at least the placeholder image, if all is missing.
I found this function in the WooCommerce Codex, but I donĀ“t come on an satisfying solution. Maybe someone can help me to receive an good solution
function woocommerce_get_product_thumbnail( $size = 'shop_catalog', $deprecated1 = 0, $deprecated2 = 0 ) {
global $post;
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size );
if ( has_post_thumbnail() ) {
$props = wc_get_product_attachment_props( get_post_thumbnail_id(), $post );
return get_the_post_thumbnail( $post->ID, $image_size, array(
'title' => $props['title'],
'alt' => $props['alt'],
) );
} elseif ( wc_placeholder_img_src() ) {
return wc_placeholder_img( $image_size );
}
}
}
So, I found myself an soultion. Is not as perfect as I wished, but it works. I post this this answer, if someone is searching for an similar solution. So, this could be an way:
/* GET PRODUCT IMAGE WITH GALLERY FALLBACK
================================================== */
if ( ! function_exists( 'zet_get_prod_image_fallback_gallery' ) ) {
function zet_get_prod_image_fallback_gallery() {
global $post, $woocommerce, $product;
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size );
$thumb_gallery_ids = $product->get_gallery_attachment_ids();
if ( has_post_thumbnail() || $thumb_gallery_ids ) {
if ( has_post_thumbnail() ) {
$image_id = get_post_thumbnail_id();
} else {
$image_id = $thumb_gallery_ids[0];
}
$thumb_image = wp_get_attachment_url( $image_id, apply_filters( 'single_product_small_thumbnail_size', 'shop_thumbnail' ) );
$image_html = '<img src="'.$thumb_image.'" />';
echo $image_html;
// Get the Placeholder image
} elseif ( wc_placeholder_img_src() ) {
echo wc_placeholder_img( $image_size );
}
}
}
For users who are not so familiar with wordpress: add this snippet to your functions.php
If you want to use this fallback for your whole shop -> change the function woocommerce_template_loop_product_thumbnail() in woocommerce/content-product.php to zet_get_prod_image_fallback_gallery(). Hope it helps!
Here's my situation:
I'm redesigning an existing Wordpress site.
The new design separates all images from the actual post content and puts it in a Featured Gallery.
Currently, each post has your typical inline images in the post content.
Is this even remotely possible to extract all inline images from the post content, and create Featured Galleries with those images for each post?
In the past I've done something like the below to grab the first image in the post content, and set it as the standard featured image, but nothing like what I have to do with this dilemma.
function wpforce_featured() {
global $post;
$already_has_thumb = has_post_thumbnail($post->ID);
if (!$already_has_thumb) {
$attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
if ($attached_image) {
foreach ($attached_image as $attachment_id => $attachment) {
set_post_thumbnail($post->ID, $attachment_id);
}
}
}
} //end function
add_action('the_post', 'wpforce_featured');
add_action('save_post', 'wpforce_featured');
add_action('draft_to_publish', 'wpforce_featured');
add_action('new_to_publish', 'wpforce_featured');
add_action('pending_to_publish', 'wpforce_featured');
add_action('future_to_publish', 'wpforce_featured');
Basically the method I used was to create a one time script that I ran to move all inline images from the post to the Featured Gallery, like this:
// Loop over every post
while ( have_posts() ) : the_post();
// Get the images attached to the post.
$imageids = array();
$images = get_attached_media( 'image', $post->ID );
foreach ($images as $image) {
$imageids[] = $image->ID;
}
$comma_separated = implode(",", $imageids);
// Save them to the Featured Gallery (Got this info by digging into the Featured Gallery plugin's source code)
if ( $post->post_type == 'revision' ) {return;}
if ( get_post_meta( $post->ID, 'fg_perm_metadata', FALSE ) ) {
update_post_meta( $post->ID, 'fg_perm_metadata', $comma_separated );
} else {
add_post_meta( $post->ID, 'fg_perm_metadata', $comma_separated );
}
if ( !$comma_separated ) delete_post_meta( $post->ID, 'fg_perm_metadata' );
endwhile;
// Reset Query
wp_reset_query();
Then, I created a function that removes all images in the post content, which I placed in functions.php:
function remove_images( $content )
{
$content =
preg_replace(
array('{<a(.*?)(wp-att|wp-content\/uploads)[^>]*><img}',
'{ wp-image-[0-9]*" /></a>}'),
array('<img','" />'),
$content
);
$content = preg_replace('/<img(.*)>/i','', $content, 1);
return $content;
}
add_filter( 'the_content', 'remove_images' );
First preg_replace removes the link around the images. Second removes the image.
the problem is if i read you correctly is that all the images are located as urls in the post content?
You can parse them:
$content = get_the_content();
$html = new DOMDocument;
$html->loadHTML($content);
//get the images
$images = $html->getElementsByTagName('img');
foreach($images as $image=>$key {
$imageurls[]=$key->attributes->getNamedItem("src")->value;//play with this cant remember how it returns object.
}
$content= preg_replace('/<img(.*)>/i','',$content,1);
echo $content;
// you also have a array of images to use.
I am trying to get all the gallery images from a single post. Here in get_post_gallery() the variable $image returns the thumbnail URL. Can any one help me with retrieving full size image URL from the post.
$gallery = get_post_gallery(get_the_ID(), false )
foreach( $gallery['src'] as $image ) {
$image_list . = '<li>' . $image . '</li>';
}
This work for me:
$gallery = get_post_gallery( $post, false );
$ids = explode( ",", $gallery['ids'] );
foreach( $ids as $id ) {
$link = wp_get_attachment_url( $id );
$image_list . = '<li>' . $link . '</li>';
}
Thanks to Matt for this code, see the original post
You can try this
<?php wp_get_attachment_image( $attachment_id, $size, $icon, $attr ); ?>
where you give the attachment id of the gallery image in $attachment_id and
$size = (thumbnail, medium, large or full)
here basically you choose full as you want to display the full size image.
Let me know if this helped you . :)
I am using a foreach loop to generate a set of thumbnail links. I am using Wordpress and for one reason or another the place my PHP is executing is not the place I would like to render the list. So my question is: can I replace the echo statement with something that will store all of the generated html (for each image, not just the last one) and allow me to generate it further down the same page?
Thanks for any help. Here's my php so far:
foreach ($gallery_images as $galleryID) {
$attachment = get_post( $galleryID );
$thumb_img = wp_get_attachment_image_src( $galleryID, 'thumbnail' ); //thumbnail src
$full_img = wp_get_attachment_image_src( $galleryID, 'full' ); //full img src
echo '<img src="' . $thumb_img[0] .'">';
$gallery_images_count++;
}//end forEach
You can store the results to an array so that you can "echo" the results later:
$links = array();
foreach ($gallery_images as $galleryID) {
$attachment = get_post( $galleryID );
$thumb_img = wp_get_attachment_image_src( $galleryID, 'thumbnail' ); //thumbnail src
$full_img = wp_get_attachment_image_src( $galleryID, 'full' ); //full img src
$links[] = '<img src="' . $thumb_img[0] .'">';
$gallery_images_count++;
}
And then later in your code, you can print it out:
echo implode("\n", $links);
$arr = array();
foreach(...) {
$arr[] = '<a href=........';
}