Ich baue mit Euch ein WordPress Plugin um zusätzliche Meta Tags für einzelne Artikel zu erstellen. Dabei werden Opengraph, Rich Snippets und Twitter Card Tags angelegt, damit die Artikel später beim Teilen auch gut aussehen und Blicke auf sich ziehen.

Social Sharing z.B. über den Facebook Like- oder den Twitter Button sind heutzutage kaum mehr aus einer Webseite wegzudenken und es dürfte mittlerweile niemanden mehr geben, der nicht wenigstens einen dieser Buttons schon einmal gesehen hat.
Was aber vielleicht nicht jeder weiß ist, dass man seinen Content für das Teilen in sozialen Netzwerken wie z.B. Google Plus, Twitter oder Facebook und auch für die Anzeige in den großen Suchmaschinen wie Google, Bing und Yahoo optimieren kann.

Das Ganze lässt sich nämlich ziemlich gut über die sogenannten Metatags steuern. Aus diesem Grund möchte ich jetzt ein WordPress Plugin mit Euch bauen, welches dann automatisch die folgenden Metadaten aus dem Inhalt Eurer Artikel erstellt:

  • Opengraph Tags (Werden z.B. vom Facebook Like Button ausgelesen.).
  • Rich Snippets Tags (Werden z.B. von Google (und Google Plus) ausgelesen.).
  • Twitter Cards (Werden von Twitter ausgelesen. Allerdings muss man sich bei Twitter erst für diese Funktion anmelden und dann auf eine Freischaltung hoffen. Mehr Informationen dazu findet Ihr bei Twitter.).
    Wenn man einmal freigeschaltet ist, könnten die Tweets zu den eigenen Artikeln fortan so aussehen:

Also, Los geht’s.

Was brauchen wir?

  • Einen Texteditor (z.B. Editor oder Notepad++).
  • (Optional) Ein ftp Programm zum Hochladen des fertigen Plugins.

Schritt 1 – Datei anlegen:

Zunächst öffnen wir mal unseren Texteditor und speichern eine leere Datei mit dem Namen unseres Plugins und der Dateiendung .php (z.B. flodjimeta.php) ab.

Schritt 2 – Das Grundgerüst:

In die leere Datei fügen wir nun das Grundgerüst für ein WordPress Plugin ein:

<?php
/*
Plugin Name: flodjiMeta
Plugin URI: http://flodji.de
Description: Erweiterung der Artikel-Metadaten um Opengraph Tags, Rich Snippets Tags, Meta Description und Twitter Card Tags
Version: 1.0
Author: flodji
Author URI: http://flodji.de
License: GPL2
*/
?>

*Info*
Diese Daten werden später in der Plugin Übersicht angezeigt. Dort sieht das Ganze dann etwa so aus:

Schritt 3 – Die Funktionen:

Jetzt können wir auch schon die ersten Funktionen einbauen:

Fangen wir erst mal mit einer kleinen Funktion an, die später unerwünschte Zeichen aus dem Titel oder dem Auszug des Artikels entfernt:

function normTxt( $text )
{
$ntxt = $text;
$bad = array( '"',"'","n","r", "&#8211;");
$good = array( '','','','','-');
$ntxt = str_replace( $bad, $good, $ntxt );
$ntxt = trim($ntxt);
return $ntxt;
}

*Info*
Diese Funktion prüft ob sich eines der folgenden Zeichen im Titel oder Auszug befindet und filtert diese dann für die Meta Tags heraus.

Dann brauchen wir noch eine Funktion, die einen Artikel nach Bildern durchsucht um die URL zu diesen dann später in die Meta Tags einzubinden:

function get_first_image_thumb()
{
$option_string = get_option('flodjiMeta');
$option = array();
$option = json_decode($option_string, true);
$Html = get_the_content();
$extrae = '/<img .*src=["']([^ ^"^']*)["']/';
preg_match_all( $extrae  , $Html , $matches );
$image = $matches[1][0];
if($image) {
return $image;
} else {
preg_match("#(.be/|/object/|/v/|/watch?v=)([A-Za-z0-9_-]{5,11})#", $Html, $matches);
$youimage = $matches[2];
if($youimage){
return 'http://img.youtube.com/vi/' . $youimage .'/0.jpg';
} else {
if($option['altimg'] != ''){
return stripslashes($option['altimg']);
} else {
return '';
}
}
}
}

*Info*
Diese Funktion durchsucht den Inhalt eines Artikels nach Bildern. Sollte kein Bild gefunden werden schaut die Funktion ob vielleicht stattdessen ein Youtube Video eingebunden wurde und liest die benötigten Bildinformationen aus dem Video aus. Sollte aber auch kein Video im Artikel vorhanden sein, kann man in den Plugin-Einstellungen später die URL eines Ersatzbildes angeben.

Weiter geht es mit den Informationen für das Schema:

function metaSchema($attr) {
	$attr .= "n xmlns:og="http://opengraphprotocol.org/schema/"";
	$attr .= "n xmlns:fb="http://www.facebook.com/2008/fbml"";
	$attr .= "n itemscope itemtype="http://schema.org/Article"";
	return $attr;
}
add_filter('language_attributes', 'metaSchema');

*Info*
Das Schema sagt der Suchmaschine oder dem Inhaltscrawler z.B. von Facebook um was für Art Inhalt es sich handelt, nämlich einen Blog-Artikel. So können die folgenden Informationen besser verarbeitet werden. (Grob ausgedrückt).

Jetzt kommen wir zur eigentlichen Hauptfunktion. Der folgende Code sorgt dafür, dass die neuen Meta Tags auch im Quelltext angezeigt werden und dann ausgelesen werden können:

function metaTags(){
$option_string = get_option('flodjiMeta');
$option = array();
$option = json_decode($option_string, true);
if(is_single()){
$title = get_the_title($post->post_title);
$url = get_permalink();
$img = get_first_image_thumb();
$sitename = get_option('blogname');
$desc = get_the_excerpt();
} else {
return;
}
	$txt.="n";
	$txt.="<meta property='og:title' content='".normTxt($title)."'/>";
	$txt.="n";
	$txt.="<meta property='og:url' content='".$url."'/>";
	$txt.="n";
	if($img != ''){
	$txt.="<meta property='og:image' content='".$img."'/>";
	$txt.="n";
	}
	$txt.="<meta property='og:site_name' content='".$sitename."'/>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta property='og:description' content='".normTxt($desc)."'/>";
	$txt.="n";
	}
	$txt.="<meta property='og:type' content='article'/>";
	$txt.="n";
	if($option['appid'] != ''){
	$txt.="<meta property='fb:app_id' content='".stripslashes($option['appid'])."'/>";
	$txt.="n";
	}
	if($option['fbadmin'] != ''){
	$txt.="<meta property='fb:admins' content='".stripslashes($option['fbadmin'])."'/>";
	$txt.="n";
	}
	$txt.="<meta itemprop='name' content='".normTxt($title)."'>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta itemprop='description' content='".normTxt($desc)."'>";
	$txt.="n";
	}
	if($img != ''){
	$txt.="<meta itemprop='image' content='".$img."'>";
	$txt.="n";
	}
	$txt.="<meta itemprop='url' content='".$url."'>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta name='description' content='".normTxt($desc)."'/>";
	$txt.="n";
	}
	$txt.='<meta name="twitter:card" content="summary">';
	$txt.="n";
	if($option['twitsite'] != ''){
	$txt.='<meta name="twitter:site" content="@'.stripslashes($option['twitsite']).'">';
	$txt.="n";
	}
	if($option['twituser'] != ''){
	$txt.='<meta name="twitter:creator" content="@'.stripslashes($option['twituser']).'">';
	$txt.="n";
	}
	$txt.='<meta name="twitter:url" content="'.$url.'">';
	$txt.="n";
	$txt.='<meta name="twitter:title" content="'.normTxt($title).'">';
	$txt.="n";
	if($desc != ''){
	$txt.='<meta name="twitter:description" content="'.normTxt($desc).'">';
	$txt.="n";
	}
	if($img != ''){
	$txt.='<meta name="twitter:image" content="'.$img.'">';
	$txt.="n";
	}
	echo $txt;
}
add_action('wp_head','metaTags');

*Info*
In dieser Funktion werden nun die Meta Tags in den Quellcode geschrieben. Dabei werden der Name des Artikels, der Link zum Artikel und der Auszug automatisch ausgelesen. Die übrigen Informationen holt sich dieser Code aus den vorherigen Funktionen.

Schritt 4 – Die Plugin Einstellungen:

Ein paar Dinge können leider nicht automatisch durch irgendwelche Funktionen ausgelesen werden. Um dem Skript diese Informationen nachzureichen, legen wir noch einen Menüpunkt im WordPress Admin Bereich an um von dort aus die nötigen Einstellungen vorzunehmen:

add_action('admin_menu', 'flodjiMeta_menu');
function flodjiMeta_menu() {
	add_options_page('flodjiMeta Optionen', 'flodjiMeta', 'manage_options', 'flodjiMeta', 'flodjiMeta_options');
}

function flodjiMeta_options(){
	$option_name = 'flodjiMeta';
	if (!current_user_can('manage_options')) {
		wp_die( __('You do not have sufficient permissions to access this page.') );
	}
	if(isset($_POST['appid'])){
		$option = array();
		$option['appid'] = esc_html($_POST['appid']);
		$option['fbadmin'] = esc_html($_POST['fbadmin']);
		$option['altimg'] = esc_html($_POST['altimg']);
		$option['twituser'] = esc_html($_POST['twituser']);
		$option['twitsite'] = esc_html($_POST['twitsite']);
		update_option($option_name, json_encode($option));
		$outputa .= '<div class="updated"><p><strong>'.__('Einstellungen gespeichert.', 'menu' ).'</strong></p></div>';
	}
	$option = array();
	$option_string = get_option($option_name);
	if ($option_string===false) {
		$option = array();
		$option['appid'] = array('appid'=>true);
		$option['fbadmin'] = array('fbadmin'=>true);
		$option['altimg'] = array('altimg'=>true);
		$option['twituser'] = array('twituser'=>true);
		$option['twitsite'] = array('twitsite'=>true);
		$option_string = get_option($option_name);
	}
	$option = json_decode($option_string, true);
	$outputa .= '
	<div class="wrap">
		<h2>'.__( 'flodjiMeta', 'menu' ).'</h2>
		<form name="form1" method="post" action="">
		<table>
		<tr><td valign="top"><b>'.__("Facebook AppID", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="appid" value="'.stripslashes($option['appid']).'" size="100"><br />
		<span class="description">z.B.: '.htmlentities('123456789132456789123').'</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Facebook Admin Username", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="fbadmin" value="'.stripslashes($option['fbadmin']).'" size="100"><br />
		<span class="description">z.B.: Dein Facebook Username oder User ID</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("URL zum Ersatzbild", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="altimg" value="'.stripslashes($option['altimg']).'" size="100"><br />
		<span class="description">z.B.: '.home_url().'/wp-content/plugins/flodjimeta/images/fs_header_logo.jpg</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Twitter User", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="twituser" value="'.stripslashes($option['twituser']).'" size="100"><br />
		<span class="description">Dein Twitter Username</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Twitter Seite", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="twitsite" value="'.stripslashes($option['twitsite']).'" size="100"><br />
		<span class="description">Falls Du f&uuml;r Deine WordPress Seite einen eigenen Twitter Account hast, kommt hier der Username rein. Falls nicht, dann trage einfach Deinen Usernamen hier ein.</span>
		</td></tr>
		</table>
		<hr />
		<p class="submit">
			<input type="submit" name="Submit" class="button-primary" value="'.esc_attr('Speichern').'" />
		</p>
		</form>
	</div>';
	echo $outputa; 
}

*Info*
Duch diesen Code wird das „Admin“ Menü angelegt wo dann die Adresse zum Ersatzbild und zu zwei Facebook Spezifischen Daten (Facebook Admins und Facebook App ID) eingetragen werden können.

Schritt 5 – Der fertige Code:

Der Code des fertigen Plugins sieht jetzt in etwa so aus:

<?php
/*
Plugin Name: flodjiMeta
Plugin URI: http://flodji.de
Description: Erweiterung der Artikel-Metadaten um Opengraph Tags, Rich Snippets Tags, Meta Description und Twitter Card Tags
Version: 1.0
Author: flodji
Author URI: http://flodji.de
License: GPL2
*/
function normTxt( $text )
{
$ntxt = $text;
$bad = array( '"',"'","n","r", "&#8211;");
$good = array( '','','','','-');
$ntxt = str_replace( $bad, $good, $ntxt );
$ntxt = trim($ntxt);
return $ntxt;
}

function get_first_image_thumb()
{
$option_string = get_option('flodjiMeta');
$option = array();
$option = json_decode($option_string, true);
$Html = get_the_content();
$extrae = '/<img .*src=["']([^ ^"^']*)["']/';
preg_match_all( $extrae  , $Html , $matches );
$image = $matches[1][0];
if($image) {
return $image;
} else {
preg_match("#(.be/|/object/|/v/|/watch?v=)([A-Za-z0-9_-]{5,11})#", $Html, $matches);
$youimage = $matches[2];
if($youimage){
return 'http://img.youtube.com/vi/' . $youimage .'/0.jpg';
} else {
if($option['altimg'] != ''){
return stripslashes($option['altimg']);
} else {
return '';
}
}
}
}

function metaSchema($attr) {
	$attr .= "n xmlns:og="http://opengraphprotocol.org/schema/"";
	$attr .= "n xmlns:fb="http://www.facebook.com/2008/fbml"";
	$attr .= "n itemscope itemtype="http://schema.org/Article"";
	return $attr;
}
add_filter('language_attributes', 'metaSchema');

function metaTags(){
$option_string = get_option('flodjiMeta');
$option = array();
$option = json_decode($option_string, true);
if(is_single()){
$title = get_the_title($post->post_title);
$url = get_permalink();
$img = get_first_image_thumb();
$sitename = get_option('blogname');
$desc = get_the_excerpt();
} else {
return;
}
	$txt.="n";
	$txt.="<meta property='og:title' content='".normTxt($title)."'/>";
	$txt.="n";
	$txt.="<meta property='og:url' content='".$url."'/>";
	$txt.="n";
	if($img != ''){
	$txt.="<meta property='og:image' content='".$img."'/>";
	$txt.="n";
	}
	$txt.="<meta property='og:site_name' content='".$sitename."'/>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta property='og:description' content='".normTxt($desc)."'/>";
	$txt.="n";
	}
	$txt.="<meta property='og:type' content='article'/>";
	$txt.="n";
	if($option['appid'] != ''){
	$txt.="<meta property='fb:app_id' content='".stripslashes($option['appid'])."'/>";
	$txt.="n";
	}
	if($option['fbadmin'] != ''){
	$txt.="<meta property='fb:admins' content='".stripslashes($option['fbadmin'])."'/>";
	$txt.="n";
	}
	$txt.="<meta itemprop='name' content='".normTxt($title)."'>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta itemprop='description' content='".normTxt($desc)."'>";
	$txt.="n";
	}
	if($img != ''){
	$txt.="<meta itemprop='image' content='".$img."'>";
	$txt.="n";
	}
	$txt.="<meta itemprop='url' content='".$url."'>";
	$txt.="n";
	if($desc != ''){
	$txt.="<meta name='description' content='".normTxt($desc)."'/>";
	$txt.="n";
	}
	$txt.='<meta name="twitter:card" content="summary">';
	$txt.="n";
	if($option['twitsite'] != ''){
	$txt.='<meta name="twitter:site" content="@'.stripslashes($option['twitsite']).'">';
	$txt.="n";
	}
	if($option['twituser'] != ''){
	$txt.='<meta name="twitter:creator" content="@'.stripslashes($option['twituser']).'">';
	$txt.="n";
	}
	$txt.='<meta name="twitter:url" content="'.$url.'">';
	$txt.="n";
	$txt.='<meta name="twitter:title" content="'.normTxt($title).'">';
	$txt.="n";
	if($desc != ''){
	$txt.='<meta name="twitter:description" content="'.normTxt($desc).'">';
	$txt.="n";
	}
	if($img != ''){
	$txt.='<meta name="twitter:image" content="'.$img.'">';
	$txt.="n";
	}
	echo $txt;
}
add_action('wp_head','metaTags');

add_action('admin_menu', 'flodjiMeta_menu');
function flodjiMeta_menu() {
	add_options_page('flodjiMeta Optionen', 'flodjiMeta', 'manage_options', 'flodjiMeta', 'flodjiMeta_options');
}

function flodjiMeta_options(){
	$option_name = 'flodjiMeta';
	if (!current_user_can('manage_options')) {
		wp_die( __('You do not have sufficient permissions to access this page.') );
	}
	if(isset($_POST['appid'])){
		$option = array();
		$option['appid'] = esc_html($_POST['appid']);
		$option['fbadmin'] = esc_html($_POST['fbadmin']);
		$option['altimg'] = esc_html($_POST['altimg']);
		$option['twituser'] = esc_html($_POST['twituser']);
		$option['twitsite'] = esc_html($_POST['twitsite']);
		update_option($option_name, json_encode($option));
		$outputa .= '<div class="updated"><p><strong>'.__('Einstellungen gespeichert.', 'menu' ).'</strong></p></div>';
	}
	$option = array();
	$option_string = get_option($option_name);
	if ($option_string===false) {
		$option = array();
		$option['appid'] = array('appid'=>true);
		$option['fbadmin'] = array('fbadmin'=>true);
		$option['altimg'] = array('altimg'=>true);
		$option['twituser'] = array('twituser'=>true);
		$option['twitsite'] = array('twitsite'=>true);
		$option_string = get_option($option_name);
	}
	$option = json_decode($option_string, true);
	$outputa .= '
	<div class="wrap">
		<h2>'.__( 'flodjiMeta', 'menu' ).'</h2>
		<form name="form1" method="post" action="">
		<table>
		<tr><td valign="top"><b>'.__("Facebook AppID", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="appid" value="'.stripslashes($option['appid']).'" size="100"><br />
		<span class="description">z.B.: '.htmlentities('123456789132456789123').'</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Facebook Admin Username", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="fbadmin" value="'.stripslashes($option['fbadmin']).'" size="100"><br />
		<span class="description">z.B.: Dein Facebook Username oder User ID</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("URL zum Ersatzbild", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="altimg" value="'.stripslashes($option['altimg']).'" size="100"><br />
		<span class="description">z.B.: '.home_url().'/wp-content/plugins/flodjimeta/images/fs_header_logo.jpg</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Twitter User", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="twituser" value="'.stripslashes($option['twituser']).'" size="100"><br />
		<span class="description">Dein Twitter Username</span>
		</td></tr>
		
		<tr><td valign="top"><b>'.__("Twitter Seite", 'menu' ).':</b></td>
		<td style="padding-bottom:20px;">
		<input type="text" name="twitsite" value="'.stripslashes($option['twitsite']).'" size="100"><br />
		<span class="description">Falls Du f&uuml;r Deine WordPress Seite einen eigenen Twitter Account hast, kommt hier der Username rein. Falls nicht, dann trage einfach Deinen Usernamen hier ein.</span>
		</td></tr>
		</table>
		<hr />
		<p class="submit">
			<input type="submit" name="Submit" class="button-primary" value="'.esc_attr('Speichern').'" />
		</p>
		</form>
	</div>';
	echo $outputa; 
}
?>

Schritt 6 – Datei speichern und installieren:

Das wars eigentlich auch schon. Jetzt müssen wir die Datei nur noch speichern und dann installieren. Zum Installieren gibt es zwei Möglichkeieten:

  • Ihr packt Eure .php Datei mit einem Packprogramm als .zip Datei (z.B. flodjimeta.zip).
  • Ihr öffnet dann den Adminbereich Eures WordPress Blogs.
  • Ihr klickt links im Menü auf Plugins, dann auf installieren und anschließend noch auf Hochladen.
  • Hier wählt Ihr dann die .zip Datei aus und ladet sie hoch.

oder

  • Ihr ladet die .php Datei per ftp in den Ordner /wp-content/plugins/ hoch.

Schritt 7 – Das Plugin aktivieren:

Jetzt müsst Ihr das Plugin nur noch aktivieren und tadaaaaa 🙂

Wer sich die Arbeit des Tippens ersparen möchte, kann sich das fertige Plugin gleich hier herunterladen:

Download

Wie hat Euch dieses WordPress Tutorial gefallen? War es hilfreich und verständlich? Ich freue mich auf Euer Feedback.

4 Kommentare

  1. Hallo, schönes Plugin.
    Wie könnte man den einen Caunter eibauen der die geteilte Artikel zählt.
    Wäre es für dich interessant, bei der nächsten Version darüber nachzu denken.
    Ich habe dein Plugin Instaliert und vermisse dich Zählerfunktion.

    Vielen Dank.

Hinterlasse einen Kommentar

Hier ist Platz für Deinen Kommentar
Hier gehört Dein Name hin