简体   繁体   中英

Wordpress: how to hook get_the_post_thumbnail_url() function

I'm new to Wordpress. What I am trying to do is to hook the get_the_post_thumbnail_url() and return slightly different URL. I know that I can use WP add_action() for hooking. If I write my function and return required string how can I make sure that the get_the_post_thumbnail_url() will return my customized code?

get_the_post_thumbnail_url in wp-includes/post-thumbnail-template.php has no hooks or actions, it's defined as follows:

function get_the_post_thumbnail_url( $post = null, $size = 'post-thumbnail' ) {
  $post_thumbnail_id = get_post_thumbnail_id( $post );
  if ( ! $post_thumbnail_id ) {
    return false;
  }
  return wp_get_attachment_image_url( $post_thumbnail_id, $size );
}

If you follow the wp_get_attachment_image_url function you find it uses the wp_get_attachment_image_src function which DOES apply filters so you are able to create a filter for it using wp_get_attachment_image_src

That will be your only way to interact with that function, albeit a little further up the functionality tree.

Usage instructions are as follows:

/**
     * Filters the image src result.
     *
     * @since 4.3.0
     *
     * @param array|false  $image         Either array with src, width & height, icon src, or false.
     * @param int          $attachment_id Image attachment ID.
     * @param string|array $size          Size of image. Image size or array of width and height values
     *                                    (in that order). Default 'thumbnail'.
     * @param bool         $icon          Whether the image should be treated as an icon. Default false.
     */
    apply_filters( 'wp_get_attachment_image_src', $image, $attachment_id, $size, $icon );

I can see two different ways to achieve this.

Solution 1 (file from the media library)

There is a filter that you can use to override (or provide a default value) for the get_the_post_thumbnail_url() function.

During the process, the function will call get_post_meta() which will eventually call the filter get_{$meta_type}_metadata .

What you can do is hook this filter with something like :

add_filter( 'get_post_metadata', function ( $metadata, int $object_id, string $meta_key, bool $single, string $meta_type ) {
    // @todo fetch a predefined file ID (this must be an existing file from the media library).

    return $metadata;
}, 10, );

The drawback form this method is that you cannot provide some random URL, but you need to use an existing file from the media library.

Solution 2 (any custom URL)

In order to provide a fully customizable URL for your post thumbnail, you will need to hook 3 different functions.

add_filter( 'has_post_thumbnail', 'so52332168_hasPostThumbnail', 10, 3 );
add_filter( 'get_post_metadata', 'so52332168_getPostThumbnailFileId', 10, 4 );
add_filter( 'wp_get_attachment_image_src', 'so52332168_getPostThumbnailSrc', 10, 4 );

/**
 * Use any way you want to determine if your post should have a custom thumbnail URL.
 *
 * @param $has_thumbnail
 * @param $post_id
 * @param $thumbnail_id
 *
 * @return bool
 */
function so52332168_hasPostThumbnail( $has_thumbnail, $post_id, $thumbnail_id ) {
    if ( ! $has_thumbnail ) {
        // @todo check if the $post_id match any rule to get a custom thumbnail.
        // if so, return true here

        return true;
    }
    
    return $has_thumbnail;
}

/**
 * Force override the thumbnail URL.
 *
 * @param $value
 * @param $object_id
 * @param $meta_key
 * @param $single
 *
 * @return int
 */
function so52332168_getPostThumbnailFileId( $value, $object_id, $meta_key, $single ) {
    if ( '_thumbnail_id' === $meta_key ) {
        // @todo check if the current $object_id should get a custom thumbnail (probably the same check as above)
            global $customPostThumbnailUrl;
            $customPostThumbnailUrl = 'https://placekitten.com/300/300';

            // return the fake thumbnail id -> this should absolutely never match an actual file id
            return PHP_INT_MAX;
            }
        }
    }
    
    return $value;
}

/**
 * Eventually return the URL that we "calculate" for the post.
 *
 * @param $image
 * @param $attachment_id
 * @param $size
 * @param $icon
 *
 * @return array
 */
function so52332168_getPostThumbnailSrc( $image, $attachment_id, $size, $icon ) {
    global $customPostThumbnailUrl;

    // check that the attachment id is the one we returned previously
    if ( (PHP_INT_MAX === $attachment_id) && $customPostThumbnailUrl ) {
        // return our custom image URL
        return [ $customPostThumbnailUrl ];
    }
    
    return $image;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM