问题描述
我知道有从远程 URL 获取图像并在本地存储的插件。我只是想知道是否可能不将图像存储在媒体库中,但将其用作精选图像?
最佳解决方案
是的,这是可能的,很简单。
这是我建议的工作流程
-
在某个地方放置一个 UI 来插入特征图像的 URL 。可能最好的选择是使用
'admin_post_thumbnail_html'
过滤器钩 -
使用
'save_post'
动作挂钩来保存 URL(在安全性和验证程序之后) 在自定义后期元 -
使用
'post_thumbnail_html'
过滤器钩子输出正确的<img>
标记,覆盖默认值,如果需要特征图像的帖子具有外部特征图像的后期元素
要工作,此工作流程需要使用 get_the_post_thumnbail()
或 the_post_thumbnail()
功能在模板中显示特征图像。
此外,当我们设置外部 URL 的元数据时,我们必须确保'_thumbnail_id'
元值具有 non-empty 值,否则 has_post_thumbnail()
将只返回只有外部特征图像的帖子。
事实上,通过我们的工作流程,一个职位有可能同时具有标准的本地特征图像和一组,在这种情况下,将使用外部功能。
为了实现我们的工作流程,我们需要一个函数来验证用作外部特征图像的 URL,因为我们必须确保它是一个有效的图像 URL 。
有不同的方法来做这个任务; 这里我使用一个非常简单的方式,只看网址,而不下载图像。这仅适用于静态图像 URL,并且不会验证图像是否真实存在,但速度很快。如果需要 (here 是一些帮助),将其修改为更高级的东西。
function url_is_image( $url ) {
if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
return FALSE;
}
$ext = array( 'jpeg', 'jpg', 'gif', 'png' );
$info = (array) pathinfo( parse_url( $url, PHP_URL_PATH ) );
return isset( $info['extension'] )
&& in_array( strtolower( $info['extension'] ), $ext, TRUE );
}
挺容易。现在我们来添加上面工作流中描述的 3 个钩子:
add_filter( 'admin_post_thumbnail_html', 'thumbnail_url_field' );
add_action( 'save_post', 'thumbnail_url_field_save', 10, 2 );
add_filter( 'post_thumbnail_html', 'thumbnail_external_replace', 10, PHP_INT_MAX );
和相关功能。首先输出管理员中的字段:
function thumbnail_url_field( $html ) {
global $post;
$value = get_post_meta( $post->ID, '_thumbnail_ext_url', TRUE ) ? : "";
$nonce = wp_create_nonce( 'thumbnail_ext_url_' . $post->ID . get_current_blog_id() );
$html .= '<input type="hidden" name="thumbnail_ext_url_nonce" value="'
. esc_attr( $nonce ) . '">';
$html .= '<div><p>' . __('Or', 'txtdomain') . '</p>';
$html .= '<p>' . __( 'Enter the url for external image', 'txtdomain' ) . '</p>';
$html .= '<p><input type="url" name="thumbnail_ext_url" value="' . $value . '"></p>';
if ( ! empty($value) && url_is_image( $value ) ) {
$html .= '<p><img style="max-width:150px;height:auto;" src="'
. esc_url($value) . '"></p>';
$html .= '<p>' . __( 'Leave url blank to remove.', 'txtdomain' ) . '</p>';
}
$html .= '</div>';
return $html;
}
请注意,我使用'txtdomain'
作为文本域,但您应该使用正确的注册文本域。
这是输出如何看起来空:
这是添加图像 URL 并保存/更新帖子后的样子:
所以现在我们的管理界面完成了,我们来写保存例程:
function thumbnail_url_field_save( $pid, $post ) {
$cap = $post->post_type === 'page' ? 'edit_page' : 'edit_post';
if (
! current_user_can( $cap, $pid )
|| ! post_type_supports( $post->post_type, 'thumbnail' )
|| defined( 'DOING_AUTOSAVE' )
) {
return;
}
$action = 'thumbnail_ext_url_' . $pid . get_current_blog_id();
$nonce = filter_input( INPUT_POST, 'thumbnail_ext_url_nonce', FILTER_SANITIZE_STRING );
$url = filter_input( INPUT_POST, 'thumbnail_ext_url', FILTER_VALIDATE_URL );
if (
empty( $nonce )
|| ! wp_verify_nonce( $nonce, $action )
|| ( ! empty( $url ) && ! url_is_image( $url ) )
) {
return;
}
if ( ! empty( $url ) ) {
update_post_meta( $pid, '_thumbnail_ext_url', esc_url($url) );
if ( ! get_post_meta( $pid, '_thumbnail_id', TRUE ) ) {
update_post_meta( $pid, '_thumbnail_id', 'by_url' );
}
} elseif ( get_post_meta( $pid, '_thumbnail_ext_url', TRUE ) ) {
delete_post_meta( $pid, '_thumbnail_ext_url' );
if ( get_post_meta( $pid, '_thumbnail_id', TRUE ) === 'by_url' ) {
delete_post_meta( $pid, '_thumbnail_id' );
}
}
}
该功能经过一些安全检查,查看发布的 URL,如果没有,请将其保存在'_thumbnail_ext_url'
后期元。如果 URL 为空,元数据已保存,则会被删除,从而可以通过清空外部 URL 字段来清除元数据。
当我们的外部图像网址设置在元中时,最后要做的是输出特色图像标记:
function thumbnail_external_replace( $html, $post_id ) {
$url = get_post_meta( $post_id, '_thumbnail_ext_url', TRUE );
if ( empty( $url ) || ! url_is_image( $url ) ) {
return $html;
}
$alt = get_post_field( 'post_title', $post_id ) . ' ' . __( 'thumbnail', 'txtdomain' );
$attr = array( 'alt' => $alt );
$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, NULL );
$attr = array_map( 'esc_attr', $attr );
$html = sprintf( '<img src="%s"', esc_url($url) );
foreach ( $attr as $name => $value ) {
$html .= " $name=" . '"' . $value . '"';
}
$html .= ' />';
return $html;
}
我们完了。
剩下什么
在特色图像输出中,我没有使用 width
或 height
属性,也不使用 WordPress 通常添加的类,如'attachment-$size'
。这是因为嗅探图像的大小需要额外的工作,这将减慢页面加载速度,特别是如果您在页面中有多个特色图像。
如果您需要这些属性,可以使用我的代码向 wp_get_attachment_image_attributes'
过滤器添加回调 (它是一个 standard WordPress hook),也可以改变我的代码来嗅探图像大小并输出相关的属性和类。
插件 Gist
在这里发布的所有代码,除了添加适当的文本域初始化之外,可以作为 Gist here 中的 full-working 插件。那里的代码使用了一个命名空间,所以它需要 PHP 5.3+。
说明
当然,您应该确保您拥有使用许可和授权的权限,并将您的站点中的图像与外部图像进行热链接。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。