阐述 WordPress `get_the_post_thumbnail()` 函数的源码:如何获取特色图片并生成 HTML。

WordPress 特色图片:get_the_post_thumbnail() 函数解剖讲座

各位同学,大家好!今天咱们来聊聊 WordPress 里的“颜值担当”——特色图片(Featured Image,也叫文章缩略图)。更具体地说,我们要扒一扒 get_the_post_thumbnail() 这个函数的源码,看看它是如何把一张图片变成一段 HTML 代码,最终展现在你的博客页面上的。

别害怕源码!我会尽量用通俗易懂的语言,加上一些小例子,让你觉得它其实也没那么神秘。准备好了吗?Let’s dive in!

特色图片:博客的门面担当

在开始之前,先简单回顾一下特色图片的概念。简单来说,特色图片就是代表一篇文章或页面的主要视觉元素。它可以让你的文章在列表页、搜索结果页等地方更加醒目,吸引读者点击。

在 WordPress 后台,你可以在编辑文章或页面时,找到“特色图片”或“文章缩略图”的选项,上传或选择一张图片。

get_the_post_thumbnail():核心函数

get_the_post_thumbnail() 函数就是用来获取指定文章的特色图片,并生成包含该图片的 HTML 代码。它的基本用法如下:

<?php
  if ( has_post_thumbnail() ) {
    echo get_the_post_thumbnail();
  }
?>

这段代码首先用 has_post_thumbnail() 函数检查当前文章是否有特色图片。如果有,就调用 get_the_post_thumbnail() 函数,并将返回的 HTML 代码输出到页面上。

函数签名和参数

我们先来看看 get_the_post_thumbnail() 函数的签名:

function get_the_post_thumbnail( $post = null, $size = 'post-thumbnail', $attr = '' ) {
  // 函数体
}

这个函数有三个参数:

  • $post (可选):文章 ID 或文章对象。如果省略,则默认为当前文章。
  • $size (可选):图片尺寸。可以是预定义的尺寸(如 ‘thumbnail’, ‘medium’, ‘large’, ‘full’, ‘post-thumbnail’),也可以是自定义的尺寸(通过 add_image_size() 函数定义)。默认为 ‘post-thumbnail’。
  • $attr (可选):HTML 属性数组。可以用来设置图片的 classalttitle 等属性。

源码剖析

现在,我们来深入了解一下 get_the_post_thumbnail() 函数的源码。源码位于 wp-includes/post-thumbnail-template.php 文件中。

1. 参数处理和默认值

function get_the_post_thumbnail( $post = null, $size = 'post-thumbnail', $attr = '' ) {
  $post = get_post( $post );

  if ( ! $post ) {
    return '';
  }

  $post_id = $post->ID;
  $size = $size ? $size : 'post-thumbnail';

  if ( is_array( $attr ) ) {
    $attr = wp_parse_args( $attr );
  } else {
    $attr = trim( $attr );
    if ( ! empty( $attr ) ) {
      $attr = array( 'class' => $attr );
    } else {
      $attr = array();
    }
  }

这段代码首先获取文章对象,如果传入的 $post 为空,则返回空字符串。然后,它处理 $size 参数,如果为空,则设置为默认值 ‘post-thumbnail’。最后,它处理 $attr 参数,将其转换为数组形式。

2. 获取特色图片 ID

  $post_thumbnail_id = get_post_thumbnail_id( $post_id );

  if ( empty( $post_thumbnail_id ) ) {
    return '';
  }

这里使用 get_post_thumbnail_id() 函数获取特色图片的 ID。如果文章没有设置特色图片,则返回空字符串。

3. 获取图片 HTML

  $hwstring = image_hwstring( $size, $post_thumbnail_id );

  $default_attr = array(
    'src'   => wp_get_attachment_image_src( $post_thumbnail_id, $size )[0],
    'class' => "attachment-$size size-$size",
    'alt'   => trim( strip_tags( get_post_meta( $post_thumbnail_id, '_wp_attachment_image_alt', true ) ) ), // Use Alt field first
  );

  $attr = wp_parse_args( $attr, $default_attr );

  // Generate 'srcset' and 'sizes' if not already present.
  if ( empty( $attr['srcset'] ) ) {
    $image_meta = wp_get_attachment_metadata( $post_thumbnail_id );
    if ( is_array( $image_meta ) ) {
      $size_array = array( absint( $image_meta['width'] ), absint( $image_meta['height'] ) );
      $srcset = wp_calculate_image_srcset( $post_thumbnail_id, $size_array, $image_meta, $post_id );
      $sizes  = wp_calculate_image_sizes( $size_array, $attr, $image_meta, $post_id );

      if ( $srcset && $sizes ) {
        $attr['srcset'] = $srcset;
        $attr['sizes']  = $sizes;
      }
    }
  }

  $attr = array_map( 'esc_attr', $attr );

  $html = rtrim( "<img $hwstring" );
  foreach ( $attr as $name => $value ) {
    $html .= " $name=" . '"' . $value . '"';
  }
  $html .= ' />';

  return apply_filters( 'post_thumbnail_html', $html, $post_id, $post_thumbnail_id, $size, $attr );
}

这段代码是整个函数的关键部分。它做了以下几件事:

  • 获取图片尺寸字符串: 使用 image_hwstring() 函数根据 $size$post_thumbnail_id 生成图片的 heightwidth 属性字符串。
  • 设置默认属性: 创建一个包含默认属性的数组,包括 src(图片 URL)、classaltsrc 使用 wp_get_attachment_image_src() 函数获取图片 URL。alt 属性首先尝试从图片的 _wp_attachment_image_alt 自定义字段中获取,如果为空,则留空。
  • 合并属性: 使用 wp_parse_args() 函数将传入的 $attr 参数与默认属性合并。
  • 生成 srcset 和 sizes 属性: 如果 srcset 属性为空,则尝试使用 wp_calculate_image_srcset()wp_calculate_image_sizes() 函数生成 srcsetsizes 属性,用于响应式图片。
  • 转义属性: 使用 esc_attr() 函数对所有属性值进行转义,防止 XSS 攻击。
  • 生成 HTML 代码: 将所有属性拼接成一个 <img> 标签的 HTML 代码。
  • 应用过滤器: 使用 apply_filters() 函数应用 post_thumbnail_html 过滤器,允许其他插件或主题修改生成的 HTML 代码。

4. 返回 HTML 代码

最后,函数返回生成的 HTML 代码。

重点函数解析

让我们更详细地看一下几个重要的辅助函数:

  • get_post_thumbnail_id( $post_id ):

    • 作用: 获取指定文章的特色图片 ID。
    • 原理: 从文章的 _thumbnail_id 自定义字段中获取图片 ID。
    function get_post_thumbnail_id( $post_id = null ) {
      $post_id = (int) $post_id;
      if ( ! $post_id ) {
        $post_id = get_the_ID();
      }
    
      if ( ! $post_id ) {
        return false;
      }
    
      return get_post_meta( $post_id, '_thumbnail_id', true );
    }
  • wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ):

    • 作用: 获取附件图片的 URL、宽度和高度。
    • 原理: 根据 $size 参数获取不同尺寸的图片 URL。
    function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
      $attachment_id = (int) $attachment_id;
    
      $image = wp_get_attachment_metadata( $attachment_id );
      $width  = 0;
      $height = 0;
      $is_intermediate = true;
    
      if ( is_array( $image ) ) {
        // ... (省略部分代码) ...
      }
    
      $src = wp_get_attachment_url( $attachment_id );
      if ( $icon && 'image/svg+xml' === get_post_mime_type( $attachment_id ) ) {
        $src = wp_mime_type_icon( 'image/svg+xml' );
      }
    
      return array( $src, $width, $height, $is_intermediate );
    }
  • image_hwstring( $size, $attachment_id = null ):

    • 作用: 根据图片尺寸生成 heightwidth 属性字符串。
    • 原理: 根据 $size 参数获取图片的宽度和高度,并生成 height="xxx" width="xxx" 字符串。
    function image_hwstring( $size, $attachment_id = null ) {
      if ( ! $attachment_id ) {
        return '';
      }
    
      $hwstring = '';
      $size_array = image_resize_dimensions( get_post_meta( $attachment_id, '_wp_attachment_metadata', true )['width'], get_post_meta( $attachment_id, '_wp_attachment_metadata', true )['height'], $size['width'], $size['height'], false );
    
      if ($size_array){
        $hwstring = 'height="' . $size_array[5] . '" width="' . $size_array[4] . '"';
      }
    
      return $hwstring;
    }
  • wp_calculate_image_srcset( $attachment_id, $size_array, $image_meta, $post_id = 0 )wp_calculate_image_sizes( $size_array, $attr, $image_meta, $post_id = 0 ):

    • 作用: 生成 srcsetsizes 属性,用于响应式图片。
    • 原理: 根据图片尺寸、屏幕宽度等因素,计算出不同分辨率下的图片 URL 和尺寸,并生成 srcsetsizes 属性。 这两个函数相对比较复杂,涉及到一些响应式图片的原理和计算方法。

示例

假设我们有一篇文章,其 ID 为 123,并且设置了特色图片,图片 ID 为 456。当我们调用 get_the_post_thumbnail( 123, 'medium', array( 'class' => 'my-image', 'alt' => '我的图片' ) ) 时,函数可能会生成如下 HTML 代码:

<img width="300" height="200" src="http://example.com/wp-content/uploads/2023/10/image-456-medium.jpg" class="attachment-medium size-medium my-image" alt="我的图片" srcset="http://example.com/wp-content/uploads/2023/10/image-456-medium.jpg 300w, http://example.com/wp-content/uploads/2023/10/image-456-large.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px" />

可选尺寸

WordPress 预定义了一些常用的图片尺寸,你可以在后台的“媒体设置”中查看和修改。常见的尺寸包括:

尺寸名称 描述
thumbnail 缩略图,通常用于文章列表页或相关文章列表中。
medium 中等尺寸图片,通常用于文章内容中。
large 大尺寸图片,通常用于文章内容中,或者作为全屏背景图片。
full 原始尺寸图片,未经任何缩放或裁剪。
post-thumbnail 特色图片尺寸,通常与主题相关,可以在主题的 functions.php 文件中定义。

你也可以使用 add_image_size() 函数自定义图片尺寸。例如,在主题的 functions.php 文件中添加以下代码:

add_action( 'after_setup_theme', 'my_theme_setup' );
function my_theme_setup() {
  add_image_size( 'my-custom-size', 600, 400, true ); // 600px 宽,400px 高,裁剪
}

这样就定义了一个名为 my-custom-size 的自定义尺寸。你可以像使用预定义尺寸一样,在 get_the_post_thumbnail() 函数中使用它:

<?php
  if ( has_post_thumbnail() ) {
    echo get_the_post_thumbnail( null, 'my-custom-size' );
  }
?>

过滤器

get_the_post_thumbnail() 函数应用了 post_thumbnail_html 过滤器,允许你修改生成的 HTML 代码。你可以使用 add_filter() 函数添加自己的过滤器函数。

例如,以下代码可以为所有特色图片添加一个额外的 class

add_filter( 'post_thumbnail_html', 'my_add_class_to_thumbnail', 10, 5 );
function my_add_class_to_thumbnail( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
  $html = str_replace( 'class="', 'class="my-extra-class ', $html );
  return $html;
}

这个过滤器函数接收五个参数:

  • $html:原始的 HTML 代码。
  • $post_id:文章 ID。
  • $post_thumbnail_id:特色图片 ID。
  • $size:图片尺寸。
  • $attr:属性数组。

总结

get_the_post_thumbnail() 函数是 WordPress 中一个非常常用的函数,用于获取和显示文章的特色图片。通过深入了解其源码,我们可以更好地理解其工作原理,并根据自己的需求进行定制。

记住,理解源码并不是为了背诵每一行代码,而是为了理解其背后的逻辑和思想。希望今天的讲座能帮助你更好地掌握 get_the_post_thumbnail() 函数,并将其应用到你的 WordPress 项目中。

下课!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注