WordPress 无忧响应式图片

Avatar of Tim Evko
Tim Evko

DigitalOcean 提供适用于旅程各个阶段的云产品。 立即开始使用 $200 免费赠送额度!

最新更新: 该插件已合并到 WordPress 核心。 因此,如果您运行的是 WordPress 4.4 或更高版本,则会自动拥有它。

更新: 本文创建的插件 已移至此处,现在使用 更合适的 srcset 属性。 它是响应式图像社区小组的官方 WordPress 插件,并得到 WordPress 核心团队的认可。 它很可能最终会被纳入 WordPress 核心。 太酷了!

以下文章由 Tim Evko (@tevko) 客串撰写。 WordPress 具有内置的媒体上传系统。 当您上传图像时,它会自动创建并保存该图像的不同版本。 Tim 将向我们展示如何定制和利用该功能来帮助我们处理内容中的响应式图片。

如果您像我一样,需要构建一个相对容易更新的响应式网站,那么 WordPress 通常是您构建该网站的 CMS。 如果您更像我,您可能会跳过响应式图片解决方案,转而使更新工作更轻松。 幸运的是,使用几行 PHP 和一些 JavaScript,您现在可以将自动响应式图片功能添加到您的 WordPress 网站。

在这里,我将向您展示如何以 一个小型 WordPress 插件 的形式,为您的 WordPress 网站添加响应式图片支持。

我们最终想要的标记

我们将在此处使用 Picturefill 库。 现在,我们将使用该库建议的标记,它与 <picture> 元素 即将推出的内容非常相似。

更新:<picture> 元素正在进入浏览器,因此本文中的插件/代码已更新,可以直接使用该语法。
<picture>
  <source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
  <source srcset="examples/images/large.jpg" media="(min-width: 800px)">
  <source srcset="examples/images/medium.jpg">
 
  <!-- fallback -->
  <img srcset="examples/images/medium.jpg" alt="alt text">
</picture>

这是基本的标记模式,虽然它可能变得 稍微复杂 以适应一些浏览器错误。

我们不会直接在博文帖子中使用该标记,我们将让 WordPress 来帮助我们完成这项工作。

主题

您只需确保主题的 functions.php 文件中存在这行代码即可。

add_theme_support('post-thumbnails');

这将确保您的主题授予 WordPress 调整上传图像大小的权限。 没有它,插件将无法正常工作。

插件

将其作为 WordPress 插件进行处理很有意义,因为无论激活哪个主题,我们都希望它保持活动状态。 我们可以将其制作成一个包含 PHP 文件的文件夹,作为插件代码本身,以及 Picturefill 库的副本。

添加库

负责任地排队

function get_picturefill() {
  wp_enqueue_script('picturefill', plugins_url( '/js/picturefill.js', __FILE__ ));
}
add_action('init', 'get_picturefill');

这将确保 WordPress 在前端加载此 JavaScript 库。

定义尺寸

告诉 WordPress 您希望在上传时创建哪些尺寸的图片。

add_image_size('large-img', 1000, 702);
add_image_size('medium-img', 700, 372);
add_image_size('small-img', 300, 200);

您可以根据需要进行设置。 add_image_size 具有可以调整的各种参数。 在我上传的 1024×768 兔子 JPG 的情况下,会创建一些版本。

创建 936×702 的原因是,我们指定了想要一个最大高度为 702 的图片。 创建 150×150 的原因是,WordPress 会自动制作一个这种尺寸的方形缩略图。

制作一个 [shortcode]

让我们通过制作一个响应式图片短代码来扩展此插件,使其具有真正的功能。 这样,我们就可以将其直接放在文章内容中。

[responsive imageid="12" size1="0" size2="500" size3="1000"]

它将输出我们需要 Picturefill 的标记。

我们将将其分为三个函数。 一个用于定义短代码和输出 HTML,一个辅助函数用于返回 alt 文本,以及一个专门用于循环遍历并输出图像源的函数。

function tevkori_get_img_alt( $image ) {
    $img_alt = trim( strip_tags( get_post_meta( $image, '_wp_attachment_image_alt', true ) ) );
    return $img_alt;
}

function tevkori_get_picture_srcs( $image, $mappings ) {
    $arr = array();
    foreach ( $mappings as $size => $type ) {
        $image_src = wp_get_attachment_image_src( $image, $type );
        $arr[] = '<source srcset="'. $image_src[0] . '" media="(min-width: '. $size .'px)">';
    }
    return implode( array_reverse ( $arr ) );
}

function tevkori_responsive_shortcode( $atts ) {
    extract( shortcode_atts( array(
        'imageid'    => 1,
        // You can add more sizes for your shortcodes here
        'size1' => 0,
        'size2' => 600,
        'size3' => 1000,
    ), $atts ) );

    $mappings = array(
        $size1 => 'small-img',
        $size2 => 'medium-img',
        $size3 => 'large-img'
    );

   return
        '<picture>
            <!--[if IE 9]><video style="display: none;"><![endif]-->'
            . tevkori_get_picture_srcs( $imageid, $mappings ) .
            '<!--[if IE 9]></video><![endif]-->
            <img srcset="' . wp_get_attachment_image_src( $imageid[0] ) . '" alt="' . tevkori_get_img_alt( $imageid ) . '">
            <noscript>' . wp_get_attachment_image( $imageid, $mappings[0] ) . ' </noscript>
        </picture>';
}

然后启用短代码

add_shortcode( 'responsive', 'tevkori_responsive_shortcode' );

理想情况下,您在这里的插件中定义断点,然后在使用短代码时根本不传递它们,例如

[responsive imageid="12"]

然后,仅在您需要覆盖断点的极少数情况下才使用短代码属性。

更改媒体上传器输出

此短代码将非常有用(请记住,我们甚至可以在将来以编程方式调整标记以使其成为正确的 <picture>)。 但是,我们如何知道要使用的图片 ID? 媒体上传器 UI 并未提供该信息。 不过,它知道该 ID,通过一个简单的过滤器,我们可以调整发送到编辑器的内容。

function responsive_insert_image($html, $id, $caption, $title, $align, $url) {
  return "[responsive imageid='$id' size1='0' size2='600' size3='1000']";
}
add_filter('image_send_to_editor', 'responsive_insert_image', 10, 9);

现在,从编辑器中选择并插入图片将按如下方式工作

就这样! 您可以在这里看到它的工作原理

您还可以做的事情

  • 如果您希望获得更广泛的支持,请考虑安装 Matchmedia.js。 它将使 @media 查询在旧版浏览器中开始工作,然后自动使 Picturefill 也正常工作。
  • 除了使用短代码或调整媒体上传器输出外,您还可以使用 高级自定义字段 使其与特殊图片字段一起工作。
  • 您可以调整标记以允许使用 WordPress 喜欢使用的 align-*。 或者使用 <figure><figcaption> 元素。 还有 alt 标签。
  • 您可以让断点的设置通过插件创建的 UI 进行设置,而不是硬编码到插件中。
  • 以下是 另一种方法,它使用 Picturefill 2 且不使用短代码。

如果您想贡献,以下是 GitHub 代码库