Get image caption in Wordpress - php

I have this code to retrieve the image url for the images in a gallery and it works ok but i cannot figure out how i could get the caption for each image.
I tried searching all over but i cannot seem to put all the information out there together! Any suggestions on how i could retrieve the captions?
function show_related_gallery_image_urls( $content ) {
global $post;
// Only do this on singular items
if( ! is_singular() )
return $content;
// Make sure the post has a gallery in it
if( ! has_shortcode( $post->post_content, 'gallery' ) )
return $content;
// Retrieve all galleries of this post
$galleries = get_post_galleries_images( $post );
$image_list = <<<END
<div class="side_bar">
<div class="related">
<h3>Related Images</h3>
END;
// Loop through all galleries found
foreach( $galleries as $gallery ) {
// Loop through each image in each gallery
foreach( $gallery as $image ) {
$src = $image;
$image_list .= '<a href="' . $src . '" rel="' . get_the_title() . '">'
. '<img src="' . $src .'" />'
. '</a>';
}
}
$image_list .= '</div></div>';
// Append our image list to the content of our post
$content .= $image_list;
return $content;
}
add_filter( 'the_content', 'show_related_gallery_image_urls' );
I hope i explained myself well! Thanks!

This hasn't been tested by try it, I cleaned up some of your code a bit:
1) Combined the first 2 IF statements into 1
2) Used get_post_gallery() (Codex) which returns the src and the image ID. We use the image ID to return the caption, we can also get the description and more if we needed to.
3) Removed the containing Foreach Statement since both my method only returns 1 gallery, not multiple so no need to loop through.
function show_related_gallery_image_urls( $content ) {
global $post;
// Only do this on singular items
if( ! is_singular() || !has_shortcode( $post->post_content, 'gallery' ) )
return $content;
// Retrieve all galleries of this post
$galleries = get_post_gallery( $post, false );
$image_list = <<<END
<div class="side_bar">
<div class="related">
<h3>Related Images</h3>
END;
// Loop through each image in each gallery
$i = 0; // Iterator
foreach( $gallery['src'] as $src ) {
$caption = wp_get_attachment($gallery['id'][$i])['caption'];
$image_list .= '<a href="' . $src . '" rel="' . get_the_title() . '">'
. '<img src="' . $src .'" />'
. '<div class="caption">'
. $caption
. '</div>'
. '</a>';
$i++; // Incremenet Interator
}
$image_list .= '</div></div>';
// Append our image list to the content of our post
$content .= $image_list;
return $content;
}
add_filter( 'the_content', 'show_related_gallery_image_urls' );
function wp_get_attachment( $attachment_id ) {
$attachment = get_post( $attachment_id );
return array(
'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
'caption' => $attachment->post_excerpt,
'description' => $attachment->post_content,
'href' => get_permalink( $attachment->ID ),
'src' => $attachment->guid,
'title' => $attachment->post_title
);
}
On a sidenote, there is a gallery filter function where you can change how the gallery is displayed post_gallery Filter, here's a question that kind of shows how to edit it. There's also a great WordPress Stack Exchange where that may be helpful in the future!

Related

Add title underneath WooCommerce product gallery images

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>');
}
}
}});

Get image inside a post using wp_get_recent_posts

I am trying to create a a page in wordpress where I show 5 recent posts.
I was able to successfully do that.
However, I am not able to retrieve images that are present inside that post.
I am using this code to retrieve post url and post image. (Post URL works fine!)
$args = array('numberposts'=>'5');
$recentposts = wp_get_recent_posts($args);
foreach($recentposts as $post){
$v = $post['ID'];
$postlink = get_permalink($v);
$postimg = get_the_post_thumbnail($v);
}
try below code
$posts = get_posts( array( 'posts_per_page' => 5 ) );
foreach ( $posts as $_post ) {
if ( has_post_thumbnail( $_post->ID ) ) {
echo '<a href="' . get_permalink( $_post->ID ) . '" title="' . esc_attr( $_post->post_title ) . '">';
echo get_the_post_thumbnail( $_post->ID, 'thumbnail' );
echo '</a>';
}
}

Add WP permalink to PHP function

The code below adds an image into my wordpress RSS feed. I am wanting to make it so that the image is automatically hyperlinked back to the corresponding post. The code is in my theme's functions.php
function wcs_post_thumbnails_in_feeds( $content ) {
global $post;
if( has_post_thumbnail( $post->ID ) ) {
$content = get_the_post_thumbnail( $post->ID ) . '<span class="text">' . $content . '</span>';
}
return $content;
}
add_filter( 'the_excerpt_rss', 'wcs_post_thumbnails_in_feeds' );
add_filter( 'the_content_feed', 'wcs_post_thumbnails_in_feeds' );
Can I change this so that the post_thumbnail is automatically wrapped with a link to the post?
How can I wrap the get_the_post_thumbnail( $post->ID ) part of the code with a link? Thanks
You can use the get_permalink function and pass it the post ID.
function wcs_post_thumbnails_in_feeds( $content ) {
global $post;
if( has_post_thumbnail( $post->ID ) ) {
$content = '' . get_the_post_thumbnail( $post->ID ) . '<span class="text">' . $content . '</span>';
}
return $content;
}

Direct a portfolio item to the single project and disable the ajax script wordpress theme

At the moment on my portfolio page you can click on a portfolio item and a ajax container pops up. And in this container you can click on a button to go to the project and read more details.
BUT
I want to disable this ajax container and when you click on a single portfolio item it needs to go straight to the project item page with all the details on it etc.
Now have I been searching in all of the .php files and in the scripts but I just can't find the action when you click on a portfolio item and I'm not really sure with what I need to replace it when found. I hope someone could help me with this one.
Here is the code of the portfolio page:
<div id="portfolio-grid" class="clearfix">
<?php
while ( $portfolio_query->have_posts() ) : $portfolio_query->the_post();
get_template_part( 'includes/entry', 'portfolio' );
endwhile;
wp_reset_postdata();
?>
</div> <!-- end #portfolio-grid -->
And here is the code of the Ajax container -I think-
function et_show_ajax_project(){
global $wp_embed;
$project_id = (int) $_POST['et_project_id'];
$portfolio_args = array(
'post_type' => 'project',
'p' => $project_id
);
$portfolio_query = new WP_Query( apply_filters( 'et_ajax_portfolio_args', $portfolio_args ) );
while ( $portfolio_query->have_posts() ) : $portfolio_query->the_post();
global $post;
$width = apply_filters( 'et_ajax_media_width', 600 );
$height = apply_filters( 'et_ajax_media_height', 480 );
$media = get_post_meta( $post->ID, '_et_used_images', true );
echo '<div class="et_media">';
if ( $media ){
echo '<div class="flexslider"><ul class="slides">';
foreach( (array) $media as $et_media ){
echo '<li class="slide">';
if ( is_numeric( $et_media ) ) {
$et_fullimage_array = wp_get_attachment_image_src( $et_media, 'full' );
if ( $et_fullimage_array ){
$et_fullimage = $et_fullimage_array[0];
echo '<img src="' . esc_url( et_new_thumb_resize( et_multisite_thumbnail($et_fullimage ), $width, $height, '', true ) ) . '" width="' . esc_attr( $width ) . '" height="' . esc_attr( $height ) . '" />';
}
} else {
$video_embed = $wp_embed->shortcode( '', $et_media );
$video_embed = preg_replace('/<embed /','<embed wmode="transparent" ',$video_embed);
$video_embed = preg_replace('/<\/object>/','<param name="wmode" value="transparent" /></object>',$video_embed);
$video_embed = preg_replace("/height=\"[0-9]*\"/", "height={$height}", $video_embed);
$video_embed = preg_replace("/width=\"[0-9]*\"/", "width={$width}", $video_embed);
echo $video_embed;
}
echo '</li>';
}
echo '</ul></div>';
} else {
$thumb = '';
$classtext = '';
$titletext = get_the_title();
$thumbnail = get_thumbnail($width,$height,$classtext,$titletext,$titletext,false,'Ajaximage');
$thumb = $thumbnail["thumb"];
echo '<a href="'. esc_url( get_permalink() ) . '">';
print_thumbnail($thumb, $thumbnail["use_timthumb"], $titletext, $width, $height, $classtext);
echo '</a>';
}
echo '</div> <!-- end .et_media -->';
echo '<div class="et_media_description">' .
'<h2 class="title">' . '' . get_the_title() . '' . '</h2>' .
truncate_post( 560, false );
echo '</div> <!-- end .et_media_description -->';
echo '<a class="more" href="' . get_permalink() . '">' . __( 'Meer info »', 'Flexible' ) . '</a>';
endwhile;
wp_reset_postdata();
die();
}
You can see the page here: http://bit.ly/10BDVVf
Again thank you!
This is being controlled via javascript in /wp-content/themes/Flexible/js/custom.js. Comment out lines 29-77 and it will link as expected (the return false at the end cancels that standard navigation), but keep in mind that if you edit the theme directly and upgrade it, your changes will be overwritten.

Adding caption area to 'Flexslider Plug-in'

I have this question on the Wordpress stack exchange as well, but not having any luck there. So, as my solution probably involves me hard-coding php and css, It may be better to have it here.
I'm using 'Flex Slider' plugin - that works on top of 'WP rotator' plug-in on my Wordpress 3.2 website. I have it implemented fine, and beginning to look at inserting my content - but I need to add a caption to be on top of the slider. As are present on most sliders on the web, within the documentation of the non-Wordpress plugin of the tool it suggests I can do something like;
<div class="flex-container">
<div class="flexslider">
<ul class="slides">
<li>
<img src="slide1.jpg" />
<p class="flex-caption">Captions and cupcakes. Winning combination.</p>
</li>
<li>
<img src="slide2.jpg" />
<p class="flex-caption">This image is wrapped in a link!</p>
</li>
<li>
<img src="slide3.jpg" />
</li>
</ul>
</div>
</div>
Problem is; with the Wordpress plug-in version, I can't find that markup to work inside.
Here's the only non-css non-js file in the plug-ins directory, so I assume I have to work in there.
I've tried inserting the mark-up that was suggested non-Wordpress above, but not sure where to insert it as it's broke it with my attempts thus far.
<?php
/*
Plugin Name: Flex Slider for WP Rotator
Plugin URI: http://wordpress.org/extend/plugins/flex-slider-for-wp-rotator/
Description: Turns WP Rotator into FlexSlider, a fully responsive jQuery slider.
Version: 1.1
Author: Bill Erickson
Author URI: http://www.billerickson.net/blog/wordpress-guide
*/
class BE_Flex_Slider {
var $instance;
function __construct() {
$this->instance =& $this;
register_activation_hook( __FILE__, array( $this, 'activation_hook' ) );
add_action( 'plugins_loaded', array( $this, 'init' ) );
}
/**
* Activation Hook
* Confirm WP Rotator is currently active
*/
function activation_hook() {
if( !function_exists( 'wp_rotator_option' ) ) {
deactivate_plugins( plugin_basename( __FILE__ ) );
wp_die( sprintf( __( 'Sorry, you can’t activate unless you have installed WP Rotator', 'flex-slider-for-wp-rotator'), 'http://wordpress.org/extend/plugins/wp-rotator/' ) );
}
}
function init() {
// Remove original scripts and styles
remove_action('wp_head','wp_rotator_css');
remove_action('admin_head','wp_rotator_css');
remove_action('wp_head','wp_rotator_javascript');
remove_action('admin_head','wp_rotator_javascript');
remove_action('init','wp_rotator_add_jquery');
remove_action('admin_init','wp_rotator_add_jquery');
// Enqueue Scripts and Styles
add_action( 'init', array( $this, 'enqueue_scripts_and_styles' ) );
// Remove original outer markup
remove_action( 'wp_rotator', 'wp_rotator' );
// Add new markup
add_action( 'wp_rotator', array( $this, 'flex_slider' ) );
remove_shortcode( 'wp_rotator' );
add_shortcode( 'wp_rotator', array( $this, 'flex_slider_markup' ) );
}
function enqueue_scripts_and_styles() {
// Use this filter to limit where the scripts are enqueued.
$show = apply_filters( 'be_flex_slider_show_scripts', true );
if ( true === $show ) {
wp_enqueue_style( 'flex-slider', plugins_url( 'flexslider.css', __FILE__ ) );
wp_enqueue_script( 'jquery ');
wp_enqueue_script( 'flex-slider', plugins_url( 'jquery.flexslider-min.js', __FILE__ ), array( 'jquery' ) );
add_action( 'wp_head', array( $this, 'flex_slider_settings' ) );
}
}
function flex_slider_settings() {
?>
<script type="text/javascript" charset="utf-8">
jQuery(window).load(function() {
jQuery('.flexslider').flexslider({
<?php
$flex_settings = array(
'animation' => '"' . wp_rotator_option( 'animate_style' ) . '"',
'slideshowSpeed' => wp_rotator_option( 'rest_ms' ),
'animationDuration' => wp_rotator_option( 'animate_ms' ),
);
$flex_slide_settings = array(
'controlsContainer' => '".flex-container"'
);
if( 'slide' == wp_rotator_option( 'animate_style' ) )
$flex_settings = array_merge( $flex_settings, $flex_slide_settings );
$flex_settings = apply_filters( 'be_flex_slider_settings', $flex_settings );
foreach ( $flex_settings as $field => $value ) {
echo $field . ': ' . $value . ', ';
}
?>
});
});
</script>
<?php
}
function flex_slider_markup() {
$output = '';
if( 'slide' == wp_rotator_option( 'animate_style' ) )
$output .= '<div class="flex-container">';
$output .= '<div class="flexslider"><ul class="slides">';
$loop = new WP_Query( esc_attr( wp_rotator_option('query_vars') ) );
while ( $loop->have_posts() ): $loop->the_post(); global $post;
$url = esc_url ( get_post_meta( $post->ID, 'wp_rotator_url', true ) );
if ( empty( $url ) ) $url = get_permalink($post->ID);
$show_info = esc_attr( get_post_meta( $post->ID, 'wp_rotator_show_info', true ) );
if ( true == $show_info ) {
$title = get_the_title();
if ( get_the_excerpt() ) $excerpt = get_the_excerpt();
else $excerpt = '';
$caption = $title . ' <span class="excerpt">' . $excerpt . '</span>';
$info = '<p class="flex-caption">' . apply_filters( 'be_flex_slider_caption', $caption, $title, $excerpt ) . '</p>';
} else {
$info = '';
}
$image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'wp_rotator' );
$slide = '<li><img src="' . $image[0] . '" />' . $info . '</li>';
$output .= apply_filters( 'be_flex_slider_slide', $slide );
endwhile; wp_reset_query();
$output .= '</ul></div>';
if( 'slide' == wp_rotator_option( 'animate_style' ) )
$output .= '</div>';
return $output;
}
function flex_slider() {
echo $this->flex_slider_markup();
}
}
new BE_Flex_Slider;
?>
I have contacted the plug-in developer, he's not responding so I assume hes not going to support my question - so I'm left to handcode.
http://wordpress.org/extend/plugins/wp-rotator/
http://flex.madebymufffin.com/
http://wordpress.org/extend/plugins/flex-slider-for-wp-rotator/
Thanks for any pointers!
It looks like captions are automatically added to the slider as long as you set the post to show rotator info (wp_rotator_show_info... probably on the plugin settings page or on your individual post page). The automatic caption is made up of the title of the post plus the excerpt. Here's the key part in the plugin above:
$show_info = esc_attr( get_post_meta( $post->ID, 'wp_rotator_show_info', true ) );
if ( true == $show_info ) {
$title = get_the_title();
if ( get_the_excerpt() ) $excerpt = get_the_excerpt();
else $excerpt = '';
$caption = $title . ' <span class="excerpt">' . $excerpt . '</span>';
$info = '<p class="flex-caption">' . apply_filters( 'be_flex_slider_caption', $caption, $title, $excerpt ) . '</p>';
} else {
$info = '';
}
UPDATE: If you want the caption to show no matter what, replace the above portion with this:
$title = get_the_title();
if ( get_the_excerpt() ) $excerpt = get_the_excerpt();
else $excerpt = '';
$caption = $title . ' <span class="excerpt">' . $excerpt . '</span>';
$info = '<p class="flex-caption">' . apply_filters( 'be_flex_slider_caption', $caption, $title, $excerpt ) . '</p>';
Note that I merely deleted the part that checks for wp_rotator_show_info.

Categories