É possível definir uma imagem em destaque com um URL de imagem externo?

16

Eu sei que existem plugins que buscam imagens de URLs remotas e armazenam localmente. Eu só quero saber se é possível não armazenar a imagem na Biblioteca de Mídia e usá-la como Imagem em Destaque ?

    
por Volatil3 20.08.2014 / 09:53

1 resposta

32

Sim, é possível e muito fácil.

Este é o fluxo de trabalho que eu sugiro:

  1. Coloque em algum lugar uma interface do usuário para inserir o URL da imagem em destaque. Provavelmente, a melhor opção é usar 'admin_post_thumbnail_html' gancho de filtro
  2. Use o 'save_post' gancho de ação para salvar a URL (após a rotina de segurança e validação) em um item personalizado post meta
  3. Use o 'post_thumbnail_html' gancho de filtro para gerar a marcação <img> adequada, substituindo o padrão, se a postagem para o qual a imagem em destaque é necessária tem o post meta com a imagem em destaque externa

Para funcionar, este fluxo de trabalho precisa que a imagem em destaque seja exibida no modelo usando get_the_post_thumnbail() ou the_post_thumbnail() funções.

Além disso, devemos ter certeza de que '_thumbnail_id' meta valor tem um valor não vazio quando definimos a meta para o URL externo, caso contrário has_post_thumbnail() retornará false para postagens que tenham apenas uma imagem em destaque externa.

De fato, é possível que uma postagem tenha uma imagem em destaque local padrão

Para implementar nosso fluxo de trabalho, precisamos de uma função para validar o URL usado como uma imagem em destaque externa, porque temos que ter certeza de que é um URL de imagem válido.

Existem diferentes maneiras de realizar essa tarefa; aqui eu uso uma maneira muito simples que só olha para o URL, sem baixar a imagem. Isso funciona apenas para URLs de imagem estática e não verifica se a imagem realmente existe, mas é rápida. Modifique-o para algo mais avançado se precisar ( aqui é alguma ajuda).

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 );
}

Bastante fácil. Agora vamos adicionar os 3 ganchos descritos no fluxo de trabalho acima:

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 );

e as funções relacionadas. Primeiro aquele que gera o campo no admin:

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;
}

Observe que usei 'txtdomain' como o domínio de texto, mas você deve usar um domínio de texto registrado apropriado.

Esta é a aparência da saída quando vazia:

EéassimqueparecedepoisdeadicionarumURLdeimagemesalvar/atualizaropost:

Então, agora que nossa interface do administrador está concluída, vamos escrever a rotina de salvamento:

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' );
        }
    }
}

A função, após algumas verificações de segurança, analisa o URL postado e, se estiver tudo bem, salva em '_thumbnail_ext_url' post meta. Se o URL estiver vazio e o meta tiver sido salvo, ele será excluído, permitindo remover o meta simplesmente esvaziando o campo do URL externo.

A última coisa a fazer é exibir a marcação de imagem em destaque quando o URL da imagem externa é definido em 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;
}

Estamos prontos.

O que resta fazer

Na saída da imagem em destaque, não usei as propriedades width ou height , nem as classes que o WordPress normalmente adiciona, como 'attachment-$size' . Isso ocorre porque farejar o tamanho de uma imagem requer trabalho extra que diminui o carregamento da página, especialmente se você tiver mais de uma imagem em destaque na página.

Se você precisar desses atributos, poderá usar meu código para adicionar um retorno de chamada ao filtro wp_get_attachment_image_attributes' (é um padrão do WordPress gancho ) ou talvez você possa alterar meu código para capturar o tamanho da imagem e produzir atributos e classes relacionados.

Plugin Gist

Todo o código postado aqui, com a exceção de adicionar uma inicialização de domínio de texto adequada, está disponível como um plug-in de trabalho completo em um Gist aqui . O código lá usa um namespace, então ele requer o PHP 5.3 +.

Notas

É claro que você deve ter certeza de que tem licença e autorização para usar e vincular imagens hot no seu site a partir de fontes externas.

    
por gmazzap 20.08.2014 / 22:39

Tags