Можно ли установить рекомендуемое изображение с URL внешнего изображения

20

Я знаю, что есть плагины, которые извлекают изображения с удаленного URL и хранят локально. Я просто хочу знать, возможно ли не хранить изображение в библиотеке мультимедиа, но использовать его в качестве избранного изображения ?

Volatil3
источник
Вы можете сделать это с помощью настраиваемого поля, в котором хранится URL-адрес внешнего изображения. Может быть трудно заставить его работать каждый раз, когда the_post_thumnail()он присутствует (или похожую функцию), или заставить его работать с различными размерами изображения, определенными темой или плагином.
Cybmeta
1
Вы можете использовать этот плагин, чтобы установить внешний URL-адрес изображения в качестве избранного: wordpress.org/plugins/wp-remote-thumbnail
Расширенный SEO
Хранит ли изображение локально или вызывает удаленно?
Volatil3
@ Volatil3 Я не тестировал, но, читая описание плагина, скажу, что он вызывается удаленно.
Энди Маколей-Брук,

Ответы:

35

Да, это возможно и довольно легко.

Это рабочий процесс, который я предлагаю:

  1. Положите куда-нибудь пользовательский интерфейс, чтобы вставить URL выбранного изображения. Вероятно, лучший выбор - использовать 'admin_post_thumbnail_html'фильтр
  2. Используйте 'save_post'ловушку действия, чтобы сохранить URL (после процедуры безопасности и проверки) в пользовательском мета-посте
  3. Используйте 'post_thumbnail_html'фильтр-ловушку для вывода правильной <img>разметки, переопределяя значение по умолчанию, если сообщение, для которого требуется выделенное изображение, имеет мета-запись публикации с внешним выделенным изображением

Для работы этого рабочего процесса необходимо, чтобы показанное изображение отображалось в шаблоне с помощью get_the_post_thumnbail()или the_post_thumbnail()функций.

Более того, мы должны быть уверены, что '_thumbnail_id'мета-значение имеет непустое значение, когда мы устанавливаем мета для внешнего URL-адреса, в противном случае has_post_thumbnail()будет возвращаться значение false для постов, которые имеют только внешнее выделенное изображение.

Фактически, возможно, что у поста есть и стандартное локальное изображение, и изображение, установленное в нашем рабочем процессе, и в этом случае будет использоваться внешнее.

Для реализации нашего рабочего процесса нам нужна функция для проверки URL, используемого в качестве внешнего изображения, потому что мы должны быть уверены, что это действительный URL изображения.

Есть разные способы сделать эту задачу; здесь я использую очень простой способ, который только смотрит на URL, не загружая изображение. Это работает только для статических URL-адресов изображений и не проверяет, действительно ли изображение существует, но это быстро. Измените его на что-то более продвинутое, если вам нужно ( вот некоторая помощь).

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 для показанного изображения: поле

И вот как это выглядит после добавления URL-адреса изображения и сохранения / обновления сообщения:

Внешний 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-адреса.

Последнее, что нужно сделать, это вывести разметку избранного изображения, когда наш внешний URL-адрес изображения установлен в meta:

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'фильтрации (это стандартная перехват WordPress ), или, возможно, вы можете изменить мой код, чтобы анализировать размер изображения и выводить связанные атрибуты и классы.

Плагин Гист

Весь код размещен здесь, за исключением добавления надлежащей инициализации текста домена, доступен как полноценный работающим плагин в Сущности здесь . Код там использует пространство имен, поэтому он требует PHP 5.3+.

Примечания

Конечно, вы должны быть уверены, что у вас есть лицензия и разрешение на использование и ссылки на ваш сайт с внешних ссылок.

Gmazzap
источник
где я должен поставить этот код
Ankit Agrawal
Можете ли вы объяснить, какой код, на какой странице мы должны написать. Я новичок в PHP / Wordpress, поэтому, пожалуйста, объясните шаг за шагом. Спасибо
Анкит Агравал
@AnkitAgrawal посмотрите здесь
gmazzap