1

I am creating a shortcode which looks like this:

[hpLocationSquare locationimage="...wp-content/uploads/2017/04/Enfielddetails.jpg"  /]

The locationimage attribute is the URL to an image in the media library.

In my functions.php I have the following code:

function hplocationsfn($atts, $content = null){
extract(shortcode_atts(array(
    'locationimage'=>''
    ), $atts));                     
return '<div class="locationSquare">
<a href="'.esc_attr($locationlink).'">
<img src="'.esc_attr($locationimage).'" />
</a>
</div><!-- locationSquare -->';
}

It works fine.

What I really want though is to somehow pick up the alt text for the image from the library. I could just add another attribute, but that would seem silly if it's already there. Is there a way I can get the alt text for the image?

Thanks

2

Instead of using the locationimage attribute, why not use the attachment ID?

This will allow you to dynamically grab the URL to the file and will make getting other meta data such as the alt text much easier. Below is a rewritten version of hplocationsfn().

Usage example: [hpLocationSquare id='2299' link='http://example.com']

Note that the link attribute is optional.

function hplocationsfn( $atts ) {
    // Set up shortcode attributes.
    // User provided values are stored in $atts.
    // Default values are passed to shortcode_atts below.
    // Merged values are stored in the $a array.
    $a = shortcode_atts( [
                'id'   => false,
                'size' => 'thumbnail',
                'link' => false,
    ], $atts );

    // Bail if we don't have an image.
    if ( ! $a['id'] ) {
        return;
    }

    // Get the image and the image's alt value.
    $image     = wp_get_attachment_image_src( $a['id'], $a['size'] );
    $image_alt = get_post_meta( $a['id'], '_wp_attachment_image_alt', true );

    // Bail if our image is invalid.
    if ( ! $image || empty ( $image ) ) {
        return;
    }

    // Generate the output.
    $output = '<div class="locationSquare">';
    if ( $a['link'] ) {
        $output .= '<a href="' . esc_attr( $a['link'] ) .'">';
    }

    $output .= '<img src="' . esc_attr( $image[0] ) . '" alt="' . esc_attr( $image_alt ) . '"/>';

    if ( $a['link'] ) {
        $output .= '</a>';
    }
    $output .= '</div><!-- locationSquare -->';

    return $output;
}
add_shortcode( 'hpLocationSquare', 'hplocationsfn' );

It can be a bit of a pain for users to find the attachment ID, so here is a function that will add the attachment ID to the media overlay screen:

/**
 * Add custom field to media
 */
add_filter( 'attachment_fields_to_edit', 'wpse_attachment_fields_id', 10, 2 );
function wpse_attachment_fields_id( $fields, $post ) {

    $fields['attachment_id'] = [
            'label' =>  __( 'Attachment ID', 'text-domain' ),
            'input' => 'html',
            'value' => $post->ID,
            'html'  => "<input type='text' class='text attachment_idfield' readonly='readonly' name='attachments[{$post->ID}][attachment_id]' value='" . esc_attr( $post->ID ) . "' /><br />",
            'show_in_edit' => true,
    ];

    return $fields;         
}

Edit: Getting the attachment ID from the image URL

Alternatively, we can get the attachment ID from the image's URL using attachment_url_to_postid().

Example usage:

[hpLocationSquare2 locationimage='http://domain.com/wp-content/uploads/2017/02/my-image.jpg' link='http://example.com/2/']

function hplocationsfn2( $atts ) {
    // Set up shortcode attrubutes.
    // User provided values are stored in $atts.
    // Default valued are passed to shortcode_atts below.
    // Merged valued are stored in the $a array.
    $a = shortcode_atts( [
                'locationimage' => false,
                'link'          => false,
    ], $atts );

    // Bail if we don't have an image.
    if ( ! $a['locationimage'] ) {
        return;
    }

    $image_id = attachment_url_to_postid( $a['locationimage'] );
    if ( ! $image_id ) {
        return;
    }

    // Get the image and the image's alt value.
    $image_alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true );

    // Generate the output.
    $output = '<div class="locationSquare">';
    if ( $a['link'] ) {
        $output .= '<a href="' . esc_attr( $a['link'] ) .'">';
    }

    $output .= '<img src="' . esc_attr( $a['locationimage'] ) . '" alt="' . esc_attr( $image_alt ) . '"/>';

    if ( $a['link'] ) {
        $output .= '</a>';
    }
    $output .= '</div><!-- locationSquare -->';

    return $output;
}
add_shortcode( 'hpLocationSquare2', 'hplocationsfn2' );
  • thanks for your reply Dave - that's an interesting approach that I wasn't aware of. Thing is we're half way into the build, and the client is happily adding content so this would a bit of a change in approach. Is there no way of getting the image id from the url? – maxelcat Apr 21 '17 at 10:57
  • Turns out there's an easy way to do just that! Although it's not quite as efficient, I understand your situation :-) – Dave Romsey Apr 21 '17 at 18:23
  • thanks again Dave - I am trying to use the second method with a line $image_id = wpse_get_attachment_id_from_url( $locationimage); and it keeps coming back with 'undefined function' - where / what is this function please? – maxelcat Apr 24 '17 at 10:06
  • 1
    fantastic Dave - really helpful and all working. Thanks so much for your help! – maxelcat Apr 26 '17 at 8:14
  • 1
    just to say I used the two functions you suggested from the $locationimage – maxelcat Apr 26 '17 at 8:15

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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