WordPress Attachments, Bilder und Metadaten nutzen

Die Zeiten ändern sich.

Dieser Beitrag scheint älter als 14 Jahre zu sein – eine lange Zeit im Internet. Der Inhalt ist vielleicht veraltet.

WordPress erlaubt es recht einfach Bilder zu Beiträgen und Seiten hoch zu laden. Dabei werden diverse Daten gespeichert, die man nutzen kann.
Immer wieder kann man im Netz Tutorials lesen, wie man Bilder zu Beiträgen holt; in der Regel ist das eine Lösung via Benutzerdefinierten Felder, so zum Beispiel auch in einem älteren Beitrag von mir WordPress benutzerdefinierte Felder (Custom Fields). Es geht aber auch anders und einfacher, wie ich finde. Die Pflege der benutzerdefinierten Felder ist nicht immer notwendig.
Daher möchte ich ein wenig auf das Thema eingehen und Lösungen aufzeigen, die aus meiner Sicht viel besser sind und vielfältig ausgebaut werden können.

Mit Hilfe der benutzerdefinierten Felder

Im ersten Fall soll die Lösung mit Hilfe eines benutzerdefinierten Feldes dargestellt werden, dabei müssen die Daten in diesem Feld zu einem Schlüssel gepflegt werden.

In Version 1 wird zum Schlüssel authorlink der Wert des Autors gespeichert, so ist, so hoffe ich, die Nutzung der Felder leicht zu verstehen. Weitere Infos dazu findet man im Codex.

Version 1

Custom Fields
Die Ausgabe zum Schlüssel wird mir Hilfe des Template Tag get_post_meta() übergeben. Die Funktion erwartet die Id des Beitrags und den Schlüssel als Pflichtwert, alternativ kann übergeben werden, ob ein Wert oder auch Arrays als Rückgabe erlaubt sind. Setze auf true und es kommt nur ein String zurück.


/**
 * @param int $post_id Post ID.
 * @param string $key The meta key to retrieve.
 * @param bool $single Whether to return a single value.
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
 *  is true.
 */
function get_post_meta($post_id, $key, $single = false)

<?php $key = 'authorlink'; ?>
<p>Foto von <a href="<?php echo get_post_meta($post->ID, $key, true); ?>"></a>.</p>

Im nächsten Schritt ist das im Grunde nichts anderes, nur dass wir nun als Wert zu einem anderen Schlüssel die Adresse ablegen, wo das Bild liegt. Dazu muss der Autor die Adresse wissen und die URL speichern.
Custom Fields

In Version 2 gehen wir aber einen Schritt weiter und legen eine Funktion in der functions.php ab, die sich später darum kümmert und die wir mit Daten füttern können. Auch dies ist nur ein Beispiel und braucht in der Version den Schlüssel des benutzerdefinierten Feldes, die Breite und Höhe des Bildes. Diese drei Beispielwerte schreiben wir dann in den Tag zur Ausgabe des Bildes.

Version 2


/*Custom Field Images*/
function image_attachment($key, $width, $height) {
	global $post;

	$custom_field = get_post_meta($post->ID, $key, true);
	if ($custom_field) {
		echo '<img src="' . $custom_field . '" alt="Post Image" width="' . $width . '" height="' . $height . '" />';
	} else {
		return;
	}
}

Die Ausgabe im Template ist durch die obige Funktion dann wie folgt.


<?php
$image_key = 'image';
$myimage = get_post_meta($post->ID, $image_key, true);
if ($myimage) { ?>
	<div class="post-image">
		<?php image_attachment($image_key, 512, 200); ?>
	</div>
<?php } ?>

Damit kann man einige schöne Sachen machen und je nach Kenntnis umsetzen. Viele Theme-Autoren möchten aber einfach ein Bild zum Beitrag haben, was direkt an diversen Stellen gezogen wird und eventuell keine Verwendung im Inhalt des Beitrags hat. Oft wird dies über die obige Lösung realisiert. Dies sorgt aber dafür, dass die Autoren der Beiträge die Felder kennen und pflegen müssen, also Schlüssel des Feldes und URL zum Bild.

Nicht sehr komfortabel und daher möchte ich eine Lösung zeigen, wie man an das Bild kommt, welches zum Beitrag hoch geladen wurde, welches man quasi in der Gallery zum Beitrag wieder findet.

Gallery-Editor

WordPress eigene Funktionen für Bilder

Eine der vielen Möglichkeiten ist die Funktion wp_get_attachment_image(), welche aus meiner Sicht die einfachste Lösung darstellt. Dazu ein Beispiel, was es näher erklärt.

Zu erst holen wir einfach mal alle Bilder, nicht alle Attachments zum Beitrag, die man direkt zum Beitrag hoch geladen hat. Diese Bilder lassen wir direkt ausgeben. Die Syntax muss immer im Loop sein.


<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image($attachment_id);
} ?>

Zur Erklärung ist zu sagen, dass in dem obigen Beispiel über die Schleife alle Bilder geladen werden und direkt ausgegeben werden. Dabei kümmern wir uns aktuell nicht um die Größe des Bildes, es wird im Standard das Thumbnail ausgegeben. Durch die Festlegung post_mime_type = image, werden auch wirklich nur Bilder geholt und nicht noch andere Anhänge zum Beitrag.
Die Funktion von WordPress, welches uns dann das Bild mit dem HTML ausgibt, benötigt zwingend die ID des Attachment, daher muss im Vorfeld diese ID zum Beitrag geholt werden, erledigen wir mit get_children().

Einige Worte nun zur Funktion wp_get_attachment_image() von WP zum Ausgaben des Bildes. Wie schon angesprochen, es gibt mehrere Funktionen, alle haben einen ähnlichen Aufbau und geben entweder anderes Markup zurück oder lassen andere Parameter zu. Zur einfache Ausgabe eignet sich diese Funktion am besten. Sie ist auch im Codex beschrieben.

Die Funktion lässt 3 Parameter zu:


/**
 * Get an HTML img element representing an image attachment
 *
 * @param int $attachment_id Image attachment ID.
 * @param string $size Optional, default is 'thumbnail'.
 * @param bool $icon Optional, default is false. Whether it is an icon.
 * @return string HTML img element or empty string on failure.
 */
function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false)

Zurück bekommt man das Markup zum img-Tag, wie das folgende Beispiel.


<img width="150" height="150" src="http://example.com/wp-content/uploads/2009/08/DSC00261-150x150.jpg" class="attachment-thumbnail" alt="Image Example" title="Example Image" />

Der letzte der drei Parameter ist im Zusammenhang mit Bildern eigentlich wenig interessant, da er ein Icon ausgibt. Aber der zweite Parameter ist da schon spannender, denn dieser lässt die Übergabe der Größe des Bildes zu. Dabei kann man entweder einer der vorkonfigurierten Größen mitgeben, quasi die Größen, die WP in den Einstellungen konfigurieren lässt und die beim Upload über die Mediathek angelegt werden. Folgende Möglichkeiten stehen zur Verfügung.

  • Standard-Werte: thumbnail, medium, large oder full
  • Eigene Größen via Array: array( Breite, Höhe ) Bsp.: array(100, 100)

Wenn man eigene Werte übergibt, dann zieht WordPress in Abhängigkeit dieser Werte das jeweils passende Bild. Also wenn man bspw. 100×100 übergibt und die Thumbnails sind 150px150px, dann werden diese Bilder dafür gezogen und bei einem eigenen Array von 200×200 wird dann das Medium-Bild gezogen, da das Thumbnail zu klein wäre.


<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id, array(200, 250) );
} ?>

Bilder mit Links

Nun will aber nicht immer nur die Bilder zum Beitrag, sondern eventuell das Bild mit einem Link zum Bild in Originalgröße haben. Auch dazu gibt es eine Funktion wp_get_attachment_link() und man muss das Markup nicht zusammen stellen. Beispielsweise könnte die Nutzung der Funktion analog der obigen Beschreibung aussehen.


<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_link( $attachment_id, 'medium' );
} ?>

Das HTML sieht dann wie folgt aus.


<a href="http://example.com/wp-content/uploads/2009/08/DSC00261.JPG" title="Example Image"><img src="http://example.com/wp-content/uploads/2009/08/DSC00261-150x150.jpg" class="attachment-thumbnail" alt="Image Example" title="Example Image" height="150" width="150"></a>

Damit wird das Bild in der angeforderten Größe ausgegeben und der Link zum Bild in Originalgröße gesetzt.

Größe der Bilder bestimmen

mitunter will man im Vorfeld wissen, wie groß das Bild ist, abhängig von der Übergabe des Typ der Größe. Dazu gibt es eine Funktion, die die Werte als Array zurück gibt. Auch dazu ein Beispiel mit der Ausgabe.


<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	$src = wp_get_attachment_image_src( $attachment_id, 'full' );
	var_dump($src);
} ?>

Diese einfache Schleife zur Ausgabe der Werte gibt ein Array zurück.


array
  0 => string 'http://example.com/wp-content/uploads/2009/08/DSC00261.JPG' (length=63)
  1 => int 1632
  2 => int 1224
  3 => boolean false

Die Reihenfolge im Array wird wie folgt zugeordnet.

  • $src[0] => url
  • $src[1] => width
  • $src[2] => height
  • $src[3] => icon

Somit kann auf die Größe reagiert werden, je nach Anforderung. Alternativ kann mit der Funktion image_get_intermediate_size($post_id, $size='thumbnail') gearbeitet werden, die noch einige Werte mehr zurück gibt. Ein Ausgabebeispiel bei der Übergabe ‚medium‘ dazu:


array
  'file' => string 'DSC00261-300x225.jpg' (length=20)
  'width' => string '300' (length=3)
  'height' => string '225' (length=3)
  'path' => string '2009/08/example-300x225.jpg' (length=28)
  'url' => string 'http://example.com/wp-content/uploads/2009/08/DSC00261-300x225.jpg' (length=71)

Weitere Funktionen und Möglichkeiten

In diesem Zusammenhang gibt es noch einige weitere Funktion, die die Arbeit mit Anhängen bzw. Bildern zu Beiträgen ermöglichen. Ich möchte nicht jede einzelne erklären und stelle nachfolgend eine kleine Schleife zum Testen zur Verfügung. Damit sind recht viele Möglichkeiten abgedeckt und erklären sich in einem Test sicher selbst.


<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo '<p>';
	echo 'wp_get_attachment_image: ' . wp_get_attachment_image( $attachment_id, array(200,250) ) . '<br />';
	echo 'wp_get_attachment_link: ' . wp_get_attachment_link( $attachment_id ) . '<br />';
	echo 'wp_get_attachment_url: ' . wp_get_attachment_url( $attachment_id ) . '<br />';
	echo 'wp_get_attachment_thumb_url: ' . wp_get_attachment_thumb_url( $attachment_id ) . '<br />';
	echo 'get_attachment_link: ' . get_attachment_link( $attachment_id ) . '<br />';
	$src = image_get_intermediate_size( $attachment_id, 'medium'	 );
	echo 'image_get_intermediate_size. '; var_dump($src); echo '<br />';
	$src = wp_get_attachment_image_src( $attachment_id, 'full', true );
	echo 'wp_get_attachment_image_src. '; var_dump($src); echo '<br />';
	echo 'Title des Attachment: ' . apply_filters( 'the_title', $attachment->post_title ) . '<br />';
	echo 'Link zum Beitrag: ' . get_permalink($image->post_parent) . '<br />';
	echo '<hr style="clear:both;" /></p>';
} ?>

Bitte daran denken, die Syntax muss im Loop von WordPress sein.

Nur ein Bild zum Beitrag

Nun habe ich schon einige Punkte zum Holen der Bilder erklärt und in der Regel wird man wohl nicht alle Bilder zum Beitrag benötigen, sondern man möchte ein Bild. Dies findet zum Beispiel Anwendung in Magazin-Themes, wo ein kleines Bild Lust auf den Beitrag machen soll. Durch diese Funktionen kann ich damit dem Autor der jeweiligen Beiträge die Kontrolle über dieses Bild in die Hand geben. In der Regel mache ich das so, das explizit das erste Bild aus der Galerie zum Beitrag gezogen wird. Damit kann der Autor in der Galerie das Bild per Drag&Drop an die richtige Stelle bewegen.

Drag&Drop in der Galerie

Dies ist keine eigene Funktion, dazu muss die Funktion get_children() entsprechend gefüttert werden. Die Ausgabe des Bildes und andere Werte zum Bild ist dann wieder wie oben beschrieben.

Im ersten Wurf holen wir nur das erste Bild aus der Galerie.


<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Nun kann der Autor des Beitrages immer das erste Bild festlegen, was er nutzen möchte.

Alternativ drehen wir den Spieß um und holen das letzte Bild aus der Galerie.


<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'DESC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Mit Hilfe von numberposts legen wir fest, wie viele Bilder geholt werden sollen. So holen wir im folgenden Beispiel die ersten 2 Bilder und im Anschluss die letzten 2 Bilder.


<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 2, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Nun also die letzten beiden Bilder, beginnend mit dem letzten Bild.


<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 2, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'DESC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Meta-Daten zu Bildern

Nun werden durch WordPress zu den Bildern diverse Meta-Daten gespeichert. Ab und an sind diese sehr nützlich und warum nicht einfach darauf zugreifen und nutzen.

Auch dazu erstmal ein Beispiel um an die Daten zu kommen. Dies machen wir mit der Funktion wp_get_attachment_metadata(). Diese Funktion gibt recht viele Daten zurück und so kann man mit dieser auf die Größe der Bilder, auf deren Pfad und ebenso die Meta-Daten zugreifen.


<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
	$imagemeta = wp_get_attachment_metadata( $attachment_id );
	var_dump($imagemeta); // list values in array
	
	$aperture          = $imagemeta['image_meta']['aperture'];
	$credit            = $imagemeta['image_meta']['credit'];
	$camera            = $imagemeta['image_meta']['camera'];
	$caption           = $imagemeta['image_meta']['caption'];
	$created_timestamp = $imagemeta['image_meta']['created_timestamp'];
	$copyright         = $imagemeta['image_meta']['copyright'];
	$focal_length      = $imagemeta['image_meta']['focal_length'];
	$iso               = $imagemeta['image_meta']['iso'];
	$shutter_speed     = $imagemeta['image_meta']['shutter_speed'];
	$title             = $imagemeta['image_meta']['title'];
} ?>

Im obige Code ist zur Ausgabe aller Wert ein var_dump() drin. Damit erkennt man recht schnell, welche Inahtle im Array existieren und an welcher Stelle man zugreifen kann.
Alle Werte der Meta-Daten habe ich beispielhaft in jeweils eine Variable geschrieben, so dass auch nicht so versierte Nutzer damit zurecht kommen sollten.

Bei einem einfachen Bild, was via Handy-Kamera entstanden ist würde beispielsweise das Array wie folgt aussehen.


array
  'width' => string '1632' (length=4)
  'height' => string '1224' (length=4)
  'hwstring_small' => string 'height='96' width='128'' (length=23)
  'file' => string '2009/08/DSC00261.JPG' (length=20)
  'sizes' => 
    array
      'thumbnail' => 
        array
          'file' => string 'DSC00261-150x150.jpg' (length=20)
          'width' => string '150' (length=3)
          'height' => string '150' (length=3)
      'medium' => 
        array
          'file' => string 'DSC00261-300x225.jpg' (length=20)
          'width' => string '300' (length=3)
          'height' => string '225' (length=3)
      'large' => 
        array
          'file' => string 'DSC00261-1024x768.jpg' (length=21)
          'width' => string '1024' (length=4)
          'height' => string '768' (length=3)
  'image_meta' => 
    array
      'aperture' => string '2.8' (length=3)
      'credit' => string '' (length=0)
      'camera' => string 'W800i' (length=5)
      'caption' => string '' (length=0)
      'created_timestamp' => string '1184253323' (length=10)
      'copyright' => string '' (length=0)
      'focal_length' => string '0' (length=1)
      'iso' => string '100' (length=3)
      'shutter_speed' => string '0.0166666666667' (length=15)
      'title' => string '' (length=0)

Alternative ab WordPress 2.9

Mit WordPress Version 2.9 gibt es einen Template Tag genau für diese Anforderung, damit wird es einfacher und verständlicher. Man nutze einfach die Funktion the_post_thumbnail() und kann die Größe mitgeben. Standard ist thumbnail, möglich ist thumbnail, medium, large oder full.


the_post_thumbnail(); // without parameter -> Thumbnail
the_post_thumbnail('post-thumbnail'); // Thumbnail
the_post_thumbnail('post-medium'); // Medium resolution - use full

Als kleine Alternative steht noch get_the_post_image() zur Verfügung, wobei die Funktion kein echo hat und optional die ID des Post bekommen kann.
get_the_post_thumbnail( $post_id = NULL, $size = 'post-thumbnail', $attr = '' )

Fazit

WordPress bietet sehr viele unterschiedliche Funktionen um auf Anhänge, ob Bilder oder andere Art ist egal, zuzugreifen. Ebenso wird ein Teil an Meta-Daten gespeichert, die man nutzen kann. Viele Ansätze findet man im Code, vorrangig in der wp-includes/media.php. Vielleicht konnte ich einige Lösungen aufzeigen, leicht ist es nicht. Aber es stellt aus meiner Sicht eine bessere Alternative dar als die Nutzung der Benutzerdefinierten Felder oder gar dem Scannen des Content.

Von Frank Bültge

bueltge.de [by:ltge.de] wird von Frank Bültge geführt, administriert und gestaltet. Alle Inhalte sind persönlich von mir ausgewählt und erstellt, nach bestem Gewissen und Können, was die Möglichkeit von Fehlern nicht ausschließt.