Hello I would like to create two functions with different parameter but with a same common function. Here's my example...
The common function :
function my_responsive_pictures($post_id){
// Get alt text or set the $alt_text variable to the post title if no alt text exists
$alt_text = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
if ( !$alt_text ) { $alt_text = esc_html( get_the_title($post_id) ); }
// Get the info for each image size including the original (full)
$thumb_original = wp_get_attachment_image_src($attachment_id, 'slideshow');
$thumb_large = wp_get_attachment_image_src($attachment_id, 'slideshow-lg');
$thumb_medium = wp_get_attachment_image_src($attachment_id, 'slideshow-md');
$thumb_small = wp_get_attachment_image_src($attachment_id, 'slideshow-xs');
// Create array containing each image size + the alt tag
$thumb_data = array(
'thumb_original' => $thumb_original[0],
'thumb_large' => $thumb_large[0],
'thumb_medium' => $thumb_medium[0],
'thumb_small' => $thumb_small[0],
'thumb_alt' => $alt_text
);
// Echo out <picture> element based on code from above
echo '<picture>';
echo '<!--[if IE 9]><video style="display: none;"><![endif]-->'; // Fallback to <video> element for IE9
echo '<source srcset="' . $thumb_data['thumb_large'] . ', ' . $thumb_data['thumb_original'] . ' x2" media="(min-width: 800px)">';
echo '<source srcset="' . $thumb_data['thumb_medium'] . ', ' . $thumb_data['thumb_large'] . ' x2" media="(min-width: 400px)">';
echo '<source srcset="' . $thumb_data['thumb_small'] . ', ' . $thumb_data['thumb_medium'] . ' x2">';
echo '<!--[if IE 9]></video><![endif]-->'; // Fallback to <video> element for IE9
echo '<img srcset="' . $thumb_data['thumb_small'] . ', ' . $thumb_data['thumb_medium'] . ' x2" alt="' . $thumb_data['thumb_alt'] . '">';
echo '</picture>';
}
Another one which calls the common function :
function my_responsive_thumbnail($post_id){
// Get the featured image ID
$attachment_id = get_post_thumbnail_id($post_id);
my_responsive_pictures();
}
And a second one with other parameters $attachment_ID :
function my_responsive_acfthumbnail($post_id){
// Get the featured image ID
$attachment_id = get_field('image_bandeau');
my_responsive_pictures();
}
Nothing happens :(. What do I do wrong ? Thanx for your help...
Your function is expecting a parameter, and when you're calling it here
my_responsive_pictures();
you aren't passing anything.
You also have to call the my_responsive_thumbnail() function before it's going to make the subsequent calls to your "common" function.
There are a few issues with this code. The first thing we need to look at is the main function.
function my_responsive_pictures($post_id){
Your function definition doesn't give $post_id a default value therefore it's required any time you call the function. By attempting to call the function without passing an the argument you'll trigger an error.
$alt_text = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
if ( !$alt_text ) { $alt_text = esc_html( get_the_title($post_id) ); }
Here you're referring to $attachment_id which hasn't been set. When it's not found you're then getting the title of the post.
For this to work you'll need to set two parameters for the function.
function my_responsive_pictures( $attachment_id, $post_id ) {
Any time we call this function we need to pass in the $attachment_id (ID of the image) and $post_id (ID of the post).
Next up we need to modify the functions that ultimately call the main function.
function my_responsive_thumbnail( $post_id ) {
// Get the featured image ID
$attachment_id = get_post_thumbnail_id( $post_id );
// Now that we have the featured image ID, we really ought
// to do some error checking. Let's assume that all went well.
my_responsive_pictures( $attachment_id, $post_id );
}
This next function requires more attention. Remember that you're calling these functions with the post ID. You need to let get_field() know the ID of the post it should retrieve the image for.
function my_responsive_acfthumbnail( $post_id ) {
// Get the featured image ID
$attachment_id = get_field( 'image_bandeau', $post_id );
my_responsive_pictures( $attachment_id, $post_id );
}
Example usage:
my_responsive_acfthumbnail( get_the_ID() );
You may also want to consider setting a default for the post ID so you don't need to pass it in when retrieving an image for the current post you're viewing.
Finally, consider the level of duplication between the functions which call my_responsive_pictures. You'll want to check the attachment ID is valid so the functions are likely to become larger with only 1 line that's different.
Further information on get_field(): https://www.advancedcustomfields.com/resources/get_field/
Related
I'm trying to write my own code for populating JSON-LD Schema code (I'd rather not rely on plugins for this).
For Wordpress posts, one of the key schema elements is author data. So I use get_the_author_meta() function to access it.
This works perfectly fine when it fires in the wp_footer action, but comes up empty when firing in wp_head.
I've checked this in the astra theme as well as twentytwentyone theme.
I stole this code just for demonstration purposes, it's twitter OG card and not Schema but its effectively the same. Forgive me but I can't remember what stackoverlow post I found it in.
In functions.php:
function my_twitter_cards() {
if (is_singular()) {
global $post;
$twitter_user = get_the_author_meta('nickname'); #This is the element that works in wp_footer but not in wp_head, all the other fields seem to work.
$twitter_url = get_permalink();
$twitter_title = get_the_title();
$twitter_excerpt = get_the_excerpt();
$twittercard_image = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
$twittercard_thumb = $twittercard_image[0];
if (!$twittercard_thumb) {
$twittercard_thumb = 'https://www.example.com/default-image.png';
}
if ($twitter_user) {
echo '<meta name="twitter:creator" value="#' . esc_attr($twitter_user) . '" />' . "\n";
}
echo '<meta name="twitter:card" value="summary" />' . "\n";
echo '<meta name="twitter:url" value="' . esc_url($twitter_url) . '" />' . "\n";
echo '<meta name="twitter:title" value="' . esc_attr($twitter_title) . '" />' . "\n";
echo '<meta name="twitter:description" value="' . esc_attr($twitter_excerpt) . '" />' . "\n";
echo '<meta name="twitter:image" value="' . esc_url($twittercard_thumb) . '" />' . "\n";
echo '<meta name="twitter:site" value="#mhthemes" />' . "\n";
}
}
add_action('wp_head', 'my_twitter_cards'); #swap this out for wp_footer to see the difference.
My theory was that it couldn't access the loop when called in the header, but that doesn't explain why post-specific data is populating (i.e permalink, title, etc), and not the get_the_author_meta data.
Now I can go with it if I just populate the footer, in this application it would be OK, but some things need to be in the header, so I want to figure out why its not working as expected.
Thank you in advance!
get_the_author_meta() accepts two optional parameters:
get_the_author_meta(string $field = '', int|false $user_id = false)
Where $field is the user field to retrieve (Default value is '')
and $user_id is the user ID (Default value is false)
When used within The Loop, the user ID need not be specified, it defaults to the current post author. A user ID must be specified if used outside The Loop.
You can get the current post author ID outside The Loop, and then use it to fetch the desired author field like this:
global $post;
$post_id = $post->ID;
$post_author_id = get_post_field('post_author', $post_id);
$twitter_user = get_the_author_meta('nickname', $post_author_id);
On a side note, the above example uses global $post because you are already using it in your code, otherwise I would use get_queried_object_id() to get the post ID outside of The Loop:
$post_id = get_queried_object_id();
Wordpress automatically adds srcset and sizes attributes to all images coming from posts. That’s very neat.
But how to I get WordPress to add those attributes to images that come from a customizer input?
In my case: a default image for posts. That default image is displayed when no image was uploaded in a post. It’s uploaded by the user through the customizer and called using get_theme_mod.
image from post (works fine, all attributes are added):
get_the_post_thumbnail($post->ID, 'news', array('class' => 'img-responsive'));
if no image is provided: the default image is loaded (no ’scrset’ and ’sizes’)
'<img src="' . esc_url( get_theme_mod( 'default_image' ) ) . '" alt="default image" class="img-responsive" />'
wp_image_add_srcset_and_sizes() seems to be the way to go but it requires attributes I don’t know where to get.
Thank you for your help!
this function does the trick:
function create_responsive_image( $img ) {
$img_id = attachment_url_to_postid( $img );
$img_srcset = wp_get_attachment_image_srcset( $img_id );
$img_sizes = wp_get_attachment_image_sizes( $img_id );
return '<img src="' . $img . '" srcset="' . esc_attr( $img_srcset ) . '" sizes="' . esc_attr( $img_sizes ) . '">';
}
I'm trying to create a PHP while loop for WordPress that populates content to some Gravity Forms fields. I'm using Advanced Custom Fields with a repeater field to get the content and then trying to use eval() to create functions inside the while loop, like this:
if( have_rows( 'tickets', 'option' ) ) :
while( have_rows( 'tickets', 'option' ) ) : the_row();
$shortname = get_sub_field('short_name');
$image = get_sub_field('image');
add_filter( 'gform_field_value_' . $shortname . '_img', 'populate_' . $shortname . '_img' );
eval("
function populate_{$shortname}_img( $value ) {
return $image;
}
");
endwhile;
endif;
The problem is that I'm getting this error:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'populate_test_img' not found or invalid function name in /srv/www/nordstan/htdocs/wp-includes/plugin.php on line 235
(I'm getting multiples of these, of course, and one of the $shortname variables are "test".)
However, if I'm changing "return $image" to "return 'test'", no error message is printed and the whole thing is executed correctly, so the functions are created.
What am I doing wrong?
Thanks in advance!
Change the order...because your eval doesn't run until after the add_filter, add_filter is failing to find the function (that doesn't exist until run time).
$shortname = get_sub_field('short_name');
$image = get_sub_field('image');
eval("
function populate_{$shortname}_img( $value ) {
return '$image';
}
");
add_filter( 'gform_field_value_' . $shortname . '_img', 'populate_' . $shortname . '_img' );
also note that $image is a string and needs to be treated as such in the context of that eval'd code.
I'm working on a gallery for the homepage of this site: Warm Glow Photo
I have called the featured image at a specific size (800x600) that I have defined in functions.php. This seems to be calling
...IMAGE.jpg?resize=800%2C600
instead of the version of the featured image called
...IMAGE-800x600.jpg
I am using a plug-in for cropping thumbnails which means I need to call this image rather than cropping with ?resize.
I've found lots of info about how to call different size thumbnails but nothing that explains why it crops with ?resize instead of calling the different thumbnail itself. Any ideas on how to do this would be much appreciated.
The relevant code is:
<?php
if ( has_post_thumbnail() ) {
$large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
echo '<li><a href="' . $large_image_url[0] . '" title="' . the_title_attribute( 'echo=0' ) . '">';
the_post_thumbnail( 'bones-thumb-800' );
echo '</a></li>';
}
?>
and defining bones-thumb-800 in functions.php
add_image_size( 'bones-thumb-800', 800, 600, true );
To get the plain URL of a post use this function :
function um_get_post_featured_image_src($post_id = null,$size = "full"){
if(!$post_id){
global $post;
$post_id = $post->ID;
}
if(has_post_thumbnail($post_id)){
$image = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), $size );
return $image[0];
}else{
return "";
}
}
If you have a $post globally than you don't need to pass post ID.
I'm using a wordpress plugin called Types.
I'm using their custom field capabilities to upload images into my gallery in my custom sidebar. I'm also using a lightbox to display these images.
So I'm trying get the title of each image to appear
<?php $resortimages = get_post_meta(get_the_ID(), 'wpcf-r-images');
foreach ($resortimages as $resortimage) {
echo '<li><a href="'. $resortimage. '" rel="lightbox" title="" ><img src="'. $resortimage. '"/></a></li>';
}
I've tried getting post title but it just gets the title of the post itself.
Jesper, it looks like Types image field only stores image URL, not its contents. If you want to retrieve some other info (title, caption and description, for example), probably you'll have to try to get image ID by its URL. In your functions.php:
/**
* Retrieve the attachment ID from its URL
*
* #param string $image_url
* #return int $attachment[0] The attachment ID
*
* #link http://pippinsplugins.com/retrieve-attachment-id-from-image-url/
*/
function mytheme_get_attachment_id( $image_url ) {
global $wpdb;
$prefix = $wpdb->prefix;
$attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $image_url ) );
return $attachment[0];
}
After that, you can use you foreach and check for your IDs:
<?php
$resortimages = get_post_meta(get_the_ID(), 'wpcf-r-images');
foreach ($resortimages as $resortimage) {
// Get attachment ID by its URL
if ( $resortid = mytheme_get_attachment_id( $resortimage ) )
$resortname = get_the_title($resortid);
echo '<li><a href="'. $resortimage. '" rel="lightbox" title="' . $resorttitle . ' ><img src="'. $resortimage. '"/></a></li>';
}
?>
But beware of the number of queries that you'll do. Hope it helps!