it-swarm.com.de

Ist es möglich ein ausgewähltes Bild mit einer externen Bild-URL einzustellen?

Ich weiß, dass es Plugins gibt, die Bilder von einer entfernten URL abrufen und lokal speichern. Ich möchte nur wissen, ob es möglich ist nicht ein Bild in der Medienbibliothek zu speichern und es dennoch als Ausgewähltes Bild zu verwenden.

17
Volatil3

Ja, das ist möglich und ziemlich einfach.

Dies ist der Workflow, den ich vorschlage:

  1. Fügen Sie irgendwo eine Benutzeroberfläche ein, um die URL des vorgestellten Bildes einzufügen. Die wahrscheinlich beste Wahl ist die Verwendung von 'admin_post_thumbnail_html' filter hook
  2. Verwenden Sie den Aktions-Hook 'save_post' , um die URL (nach der Sicherheits- und Validierungsroutine) in einem benutzerdefinierten Post-Meta zu speichern
  3. Verwenden Sie 'post_thumbnail_html' filter hook, um ein korrektes <img>-Markup auszugeben, das die Standardeinstellung überschreibt, wenn der Beitrag, für den das vorgestellte Bild erforderlich ist, das Beitrags-Meta mit dem externen vorgestellten Bild enthält

Damit dieser Workflow funktioniert, muss das vorgestellte Bild in der Vorlage mit den Funktionen get_the_post_thumnbail() oder the_post_thumbnail() angezeigt werden.

Darüber hinaus müssen wir sicherstellen, dass der '_thumbnail_id'-Metawert einen nicht leeren Wert hat, wenn wir das Meta für die externe URL festlegen. Andernfalls gibt has_post_thumbnail() false für Posts zurück, die nur ein externes Bild enthalten.

In der Tat ist es möglich, dass ein Beitrag sowohl ein Standard lokales Bild als auch ein über unseren Workflow festgelegtes Bild enthält. In diesem Fall wird das externe Bild verwendet.

Um unseren Workflow zu implementieren, benötigen wir eine Funktion zum Validieren der URL, die als externes Bild verwendet wird, da wir sicherstellen müssen, dass es sich um eine gültige Bild-URL handelt.

Es gibt verschiedene Möglichkeiten, diese Aufgabe zu erledigen. Hier benutze ich eine sehr einfache Methode, die nur die URL betrachtet, ohne das Bild herunterzuladen. Dies funktioniert nur für statische Bild-URLs und überprüft nicht, ob das Bild tatsächlich vorhanden ist, aber es ist schnell. Ändern Sie es auf etwas Fortgeschritteneres, wenn Sie dies benötigen ( hier ist eine Hilfe).

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

Ziemlich einfach. Fügen wir nun die drei im obigen Workflow beschriebenen Haken hinzu:

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

und die zugehörigen Funktionen. Zuerst der, der das Feld im Admin ausgibt:

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

Beachten Sie, dass ich 'txtdomain' als Textdomäne verwendet habe, Sie jedoch eine ordnungsgemäße, registrierte Textdomäne verwenden sollten.

So sieht die Ausgabe aus, wenn sie leer ist:

External URL for featured image: the field

Und so sieht es aus, nachdem Sie eine Bild-URL hinzugefügt und den Beitrag gespeichert/aktualisiert haben:

External URL for featured image: the field after filling up and saved

Nun ist unsere Admin-Benutzeroberfläche fertig und wir schreiben die Speicherroutine:

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

Die Funktion prüft nach einigen Sicherheitsüberprüfungen die angegebene URL und speichert sie, falls dies in Ordnung ist, in '_thumbnail_ext_url' post meta. Wenn die URL leer ist und das Meta gespeichert wurde, wird es gelöscht, sodass das Meta einfach durch Leeren des externen URL-Felds entfernt werden kann.

Als letztes müssen Sie das vorgestellte Bild-Markup ausgeben, wenn unsere externe Bild-URL in Meta festgelegt ist:

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

Wir sind fertig.

Was bleibt zu tun

In der vorgestellten Bildausgabe habe ich weder width- oder height-Eigenschaften noch von WordPress normalerweise hinzugefügte Klassen wie 'attachment-$size' verwendet. Dies liegt daran, dass das Schnüffeln der Größe eines Bildes zusätzliche Arbeit erfordert, die das Laden der Seite verlangsamt, insbesondere wenn die Seite mehr als ein Bild enthält.

Wenn Sie diese Attribute benötigen, können Sie meinen Code verwenden, um einen Rückruf zum wp_get_attachment_image_attributes'-Filter hinzuzufügen (es ist ein Standard-WordPress-Hook ), oder Sie können meinen Code ändern, um die Bildgröße zu ermitteln und damit verbundene Attribute und Klassen auszugeben.

Plugin Gist

Der gesamte hier veröffentlichte Code, mit Ausnahme des Hinzufügens einer korrekten Textdomäneninitialisierung, ist als voll funktionsfähiges Plugin in einem Gist hier verfügbar. Der dortige Code verwendet einen Namespace und benötigt daher PHP 5.3+.

Anmerkungen

Natürlich sollten Sie sicher sein, dass Sie die Lizenz und die Berechtigung haben, Bilder auf Ihrer Site von externen Seiten zu verwenden und zu verlinken.

33
gmazzap