2

Problem

I want the height and width properties in the img element of the Featured Image for a post, page, or custom post type.

Environment

  1. I have a custom theme based on the BlankSlate theme.
  2. The new twentyfifteen theme also does not display the properties.
  3. In Settings/Media, I have not changed the default image sizes.
  4. functions.php contains add_theme_support( 'post-thumbnails' );.
  5. I do not have custom image sizes.
  6. In Settings/Media, the box "Crop thumbnail to exact dimensions" is not checked. Therefore, I have some thumbnails that are not exactly 150 px x 150 px.
  7. Edit: I still want the other automatic properties from the Featured Image functions, such as alt and class.

Current output

From this example page on my website, the full HTML for the Featured Image is currently

<img src="http://i2.wp.com/www.hunterthinks.com/wp-content/uploads/2014/11/favicon-160x160.png?fit=150%2C150" class="attachment-thumbnail wp-post-image" alt="HunterThinks.com">

As an idealist, I would want the height and width normally, but the lack of height produces a layout problem with my current theme. As you can see, the last Featured Image overruns the end of the <section> element, and it looks terrible.

Current code

The header.php is large, so I will skip it unless someone thinks my problem is in there.

category.php

<?php get_header(); ?>
<section>
  <header><h1><?php _e( 'Main page: ', 'goldenratio' ); ?><?php single_cat_title(); ?></h1></header>
  <?php if ( '' != category_description() ) echo apply_filters( 'archive_meta', category_description() ); ?>
  <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  <?php get_template_part( 'entry', 'summary' ); ?> # FEATURED IMAGE COMES FROM HERE
  <?php endwhile; endif; ?>
  <?php get_template_part( 'nav', 'below' ); ?>
</section>
<?php get_footer(); ?>

entry-summary.php

<?php the_title( '<h1 class="clear">', '</h1>' ); ?>
<?php if ( has_post_thumbnail() ) { 
    echo '<figure class="clear-right"><a href="';
    the_permalink();
    echo '">';
    the_post_thumbnail( 'thumbnail' );
    echo '</a></figure>';
    } ?>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>" title="Go to the page">&rArr;&nbsp;Read&nbsp;&rArr;</a>

class="clear-right"

I cannot image why this class would affect things, but just in case I am wrong, I am including it here.

.clear-right{
 clear:right;
 float:right;
 margin-bottom:1em;
 margin-left:1.827%;}

Failed attempts

  1. I tried to use wp_get_attachment_image_src() but I guess I did not code it correctly because I couldn't even get the image to display. I don't have a sample of the code I tried.
  2. I tried using the_post_thumbnail( $size, $attr ) and adjusting the $attr array based on the documentation in wp_get_attachment_image() but I am pretty sure that will never work.

Code, concepts, and references?

Can someone please help me with the code, concepts, and reference materials that I am missing. I have a feeling that when I learn the answer I will feel a little silly, but I do want to fix this issue.

Thanks in advance.

  • What you want is custom code for your theme right? – Brad Dalton Jan 20 '15 at 8:20
  • If custom code is necessary, then yes. I am still surprised that WP generally does a good job with element attributes but does not include height and width by default, so I half-expect that there is a function for this. But the many excellent answers so far suggest that it is necessary to build a function or use some sleight of hand in The Loop to get these simple elements for the Feature Image. But I want to learn how to solve this type of problem much more than I want someone to write the code for me. "Teach a man to fish and you feed him for a lifetime." – hunterhogan Jan 20 '15 at 10:13
1

You can collect image attributes using "wp_get_attachment_metadata", see below example as starting point

function mytheme_post_thumbnail( $size = 'post-thumbnail', $attr = '', $post_id = null ) {
    if ( has_post_thumbnail( $post_id ) ) {
        $meta      = wp_get_attachment_metadata( get_post_thumbnail_id( $post_id ) );

        $args['width']  = $meta['sizes'][$size]['width'];
        $args['height'] = $meta['sizes'][$size]['height'];

        $args['alt']   = isset( $attr['alt'] ) ? $attr['alt'] : apply_filters( 'post_title', get_post( $post_id )->post_title );
        $args['title'] = isset( $attr['title'] ) ? $attr['title'] : apply_filters( 'post_title', get_post( $post_id )->post_title );
        $args['class'] = isset( $attr['class'] ) ? $attr['class'] : '';

        $thumbnail = wp_get_attachment_image( get_post_thumbnail_id( $post_id ), $size, false, $args);

        echo $thumbnail;
    } else {
        printf( '<img src="%1$s/images/default-thumb.png" alt="%2$s" />', get_template_directory_uri(), the_title_attribute( [  'echo' => false ] ) );
    }
}
  • My intuition is that this will work. I also like the idea of a function because then I can simply use the function on various pages instead of writing the full code. – hunterhogan Jan 19 '15 at 20:04
  • You taught me something new: how to access nested arrays. $meta['sizes'][$size]['width']; codex.wordpress.org/Function_Reference/… I am going to try this without the else because I have a default image plugin – hunterhogan Jan 24 '15 at 2:56
  • This is the closest to working. I like that it is a function. I modified the default size to thumbnail from post-thumbnail. I call it using mytheme_post_thumbnail(). I see that the img alt is set to the post title and I will want to change that to the img alt. The img class is empty and if I understand the code that is because I am not passing arguments to the function. It seems like there is a simple way to get the classes from the_post_thumbnail() or something like that. – hunterhogan Jan 24 '15 at 3:08
  • I used some code from @ShyamMakwana.me and changed the following $thumbnail_id = get_post_thumbnail_id( $post_id ); $meta = wp_get_attachment_metadata( $thumbnail_id ); and $args['alt'] = isset( $attr['alt'] ) ? $attr['alt'] : trim(strip_tags( get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true) )); Alt is displaying. Now I will look at class. – hunterhogan Jan 24 '15 at 3:24
  • I don't know why, but if I use the_post_thumbnail ( 'thumbnail' ) it now displays height and width. It includes the classes, but not the title from the mytheme_post_thumbnail(). I'm going to leave everything like it is. The sad part is that adding the height did not fix my "overflow" problem. And I will soon be without internet for an extended period, so this will have to be good enough. hunterthinks.com/my-life/bought-tent-guess-real – hunterhogan Jan 24 '15 at 3:42
2

If you only want the size ( the width and the height ) of the image in the img tag like so

<img src="source_of_your_image" width="500" height="250"/>

Then use the following php code:

$MySrc = "source_of_your_image";
$Myimg = "<img src='$MySrc' ";
$TheImg = (array)getimagesize($MySrc);
$Myimg .= $TheImg[3]."/>";

For more info on using getimagesize() go to http://php.net/manual/en/function.getimagesize.php

  • I want the alt and class, too. Thank you, though. – hunterhogan Jan 5 '15 at 23:21
1

I normally use something like:

if ( current_theme_supports('post-thumbnails') && has_post_thumbnail() ) {
    $post_thumb_id = get_post_thumbnail_id($id);
    $image_data = wp_get_attachment_image_src($post_thumb_id, 'thumbnail');
    $attr_title = esc_attr($title);
    $image = <<<HTML
<div class="thumbnail"><img id="attachment_{$post_thumb_id}" src="{$image_data[0]}" width="{$image_data[1]}" height="{$image_data[2]}" alt="{$attr_title}" /></div>
HTML;

} else {
    $image = '';
}

With your code, try:

<?php the_title( '<h1 class="clear">', '</h1>' ); ?>
<?php 
if ( has_post_thumbnail() ) { 
    echo '<figure class="clear-right"><a href="';
    the_permalink();
    echo '">';
    # The next line grabs the image source meta using the post thumbnail id
    $image_data = wp_get_attachment_image_src(get_post_thumbnail_id(), 'thumbnail');
    $attr_title = esc_attr( get_the_title() );
    # image_data is an array ( src => '...', 'width' => int, 'height' => 'int', ...)
    # so you can grab $image_data[0] as the source, $image_data[1] as the width, and $image_data[2] as the height
    $image_tag = <<<HTML
<img src="{$image_data[0]}" width="{$image_data[1]}" height="{$image_data[2]}" alt="{$attr_title}" />
HTML;

    #now that tag is built, just draw it out.
    echo $image_tag;
    echo '</a></figure>';
} ?>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>" title="Go to the page">&rArr;&nbsp;Read&nbsp;&rArr;</a>

That should get you what you are looking for.

  • I like this, and thank you for the explicit example using my markup! I especially like the conditional check for current_theme_supports as an error prevention: quite forward looking. I also noticed, you passed an additional argument, 'thumbnail' in wp_get_attachment_metadata( get_post_thumbnail_id( $post_id ) ); (As compared to Alex Sancho's answer). I am in a rush right now, but my intuition is that the additional argument is necessary to make sure it returns the values for the thumbnail size image and not some other size. – hunterhogan Jan 19 '15 at 20:15
  • 1
    Right. You can use thumbnail, medium, and large by default. You can also add your own image sizes in if needed using the add_image_size function in wordpress. Very welcome. – Privateer Jan 20 '15 at 12:15
1
+50

wp_get_attachment_image this function can help you.

Using this function, your file should like below...

entry-summary.php

<?php the_title( '<h1 class="clear">', '</h1>' ); ?>
<?php if ( has_post_thumbnail() ) { 
    $attachment_id = get_post_thumbnail_id( get_the_ID() );
    $default_attr = array(
        'src'   => $src,
        'class' => "attachment-$size",
        'alt'   => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )),
    );

    echo '<figure class="clear-right"><a href="';
    the_permalink();
    echo '">';
    //the_post_thumbnail( 'thumbnail' );
    wp_get_attachment_image( $attachment_id, 'thumbnail',1 , $default_attr );
    echo '</a></figure>';
    } ?>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>" title="Go to the page">&rArr;&nbsp;Read&nbsp;&rArr;</a>

To get height and width use wp_get_attachment_metadata function along width above code.

I haven't tested the code from my side, just got an example from codex. Hope this will work.

UPDATE 2 :

$attachment_id = get_post_thumbnail_id(get_the_ID()); 
$metadata = wp_get_attachment_metadata($attachment_id);
$height =  $metadata['height'];
$width =  $metadata['width'];
$alt = trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )) ; 
$src =  wp_get_attachment_url( $attachment_id );
$class = 'attachment-'.$attachment_id;

echo '<img src="'.$src.'" height="'.$height.'" width="'.$width.'" alt="'.$alt.'" class="'.$class.'" />';

UPDATE 3 :

to get height and width of thumbnail change your code lines as below.

$height =  $metadata['sizes']['thumbnail']['height'];
$width  =  $metadata['sizes']['thumbnail']['width'];
  • Thank you for showing how the code would integrate with my code--that is helpful. I will need to test this, but I am unclear where the height and width properties will be output as HTML. I had trouble deciphering the Codex for $default_attr, but (from memory) I don't think the array includes height and width property. If I remember correctly, I tried to add them to the array or something silly. But, I might have done it incorrectly, and your above code may work. I will try it. – hunterhogan Jan 19 '15 at 20:21
  • 1
    I have checked code and it's printing height width default. here is output <img height="412" width="668" alt="Alt text" class="attachment-full" src=".../map-img-017.jpg">' – shyammakwana.me Jan 20 '15 at 7:08
  • check update in my answer. I have updated code and checked as your requirement. – shyammakwana.me Jan 20 '15 at 7:57
  • Fascinating, so it seems that if I point wp_get_attachment_metadata($attachment_id); at the thumbnail size, then it should return the correct size. Thanks! – hunterhogan Jan 20 '15 at 10:06
  • 1
    check updated code – shyammakwana.me Jan 24 '15 at 4:53
0

EDIT: By default WordPress will crop thumbs to 150x150px when they are uploaded. When you uncheck the box in Settings>Media WordPress will not regenerate existing thumbnails, it will only generate proportional images when you upload new images. In short I believe your issue is not with the code you are using to display the thumbnail but the image itself.

However to get a thumbnail image output in html with the width, height, alt and classes the following code will produce the results you want:

$post_id = $post->ID; // current post id
$thumb_id = get_post_thumbnail_id($post_id);
$size = 'thumbnail';
if ( '' != get_the_post_thumbnail($post_id) ) { // checks we have a thumbnail
    echo wp_get_attachment_image($thumb_id, $size);
}

If the output result using my code is still 150px by 150px please try re-uploading the image.

  • I'm sorry I have not had the chance to try this, but my understanding is that "thumbnail" will return width=150px and height=150px (assuming the default settings) because it is a predefined size. I may not understand something in your code suggestion, but I am not sure how it would get the actual dimensions of the each thumbnail. When I get the chance, I will test it, of course. – hunterhogan Jan 19 '15 at 20:07
  • @HunterHogan I have tested several methods of doing what you want to achieve, if the output result using my code is still 150px by 150px please try re-uploading the image and let me know. By default WordPress will crop thumbs to 150x150 when they are uploaded. When you uncheck the box in Settings>Media wordpress will not regenerate existing thumbnails, it will only generate proportional images when you upload new images. In short I believe your issue is not with the code you are using to display the thumbnail but the image itself. – Aron Jan 19 '15 at 22:40
  • Ah. I unchecked that box on installation, so all of my thumbnails are proportional. And if they were not, I could use a plugin like Regenerate Thumbnails to make them proportional. Still, I will check the code, and I thank you for the answer. – hunterhogan Jan 19 '15 at 23:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.