Google News Quelle mit WordPress werden

Die Zeiten ändern sich.

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

Google News
Die Google News können eine begehrte Plattform sein. Aktuell werden über 700 deutschsprachige Quellen gezogen und publiziert. Google benötigt aber für die Aggregierung ein spezielles Format – News-Sitemap.

Mit WordPress kann man dieses Format im Grunde auf zwei Wege erstellen. Beide Lösungen sollen hier vorgestellt werden. Auf das zweite Beispiel möchte ich dann näher eingehen, denn es zeigt meiner Ansicht sehr schön, wie man Inhalte aus WordPress außerhalb nutzen kann.

  1. Der erste Weg ist das Erstellen der Sitemap als Plugin, quasi ähnlich einem Feed in WordPress. Dies hat diverse Vorteile bei der Verwaltung in WordPress.
    Wie man einen Feed erstellt, dass habe ich im Tutorial „WordPress Feed für Entwürfe“ gezeigt. Im weiteren kann man dann die Lösung als Plugin downloaden und einfach die Google News-Sitemap nutzen.
  2. Eine zweite Möglichkeit ist es, einfach eine PHP-Datei im Root abzulegen und die letzten Beiträge dort in das entsprechende Format zu schreiben.

Zuvor aber einige Hinweise zu Google News. Hinweise und Tipps sind sehr schön auf SEO Scene im Beitrag „Google Newsquelle werden und Google News-Sitemap erstellen“ nachzulesen. Dort werden auch die Punkte im Bezug auf Suchmaschinenoptimierung, Vor- und Nachteile der Google News beleuchtet.

WordPress einbinden

Um an die Daten von WordPress zu kommen, muss man Zugriff auf die wp-load.php haben, daher binde ich diese ein und kann mich ab dann auf die globalen Variablen von WordPress beziehen, zum Beispiel die Datenbank $wpdb.
Dadurch kann man nun alle Daten aus der Datenbank holen, die relevant für das XML-Format der Google News Sitemap sind.

Das Format

Die Vorgabe von Google sieht die folgende XML-Struktur vor. Die bauen ich dann in der Datei nach und befülle sie lediglich mit den letzen 20 News.
Hintergründe und Tipps von Google gibt es auf der entsprechende Doku-Seite.


<urlset xmlns=“http://www.sitemaps.org/schemas/sitemap/0.9?
xmlns:news=“http://www.google.com/schemas/sitemap-news/0.9?>
	<url>
		<loc>http://www.domain.de/news/news1.html</loc>
		<news:news>
			<news:publication_date>2008-22-01T00:29:19+01:00</news:publication_date>
			<news:keywords>key1, key2, key3</news:keywords>
		</news:news>
	</url>
</urlset>

Update; Formatumstellung bei Google


<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:n="http://www.google.com/schemas/sitemap-news/0.9">
  <url>
    <loc>http://www.example.org/business/article55.html</loc>
    <n:news>
      <n:publication>
        <n:name>The Example Times</n:name>
        <n:language>en</n:language>
      </n:publication>
      <n:access>subscription</n:access>
      <n:genres>pressrelease, blog</n:genres>
      <n:publication_date>2008-12-23</n:publication_date>
      <n:title>Companies A, B in Merger Talks</n:title>
      <n:keywords>business, merger, acquisition, A, B</n:keywords>
      <n:stock_tickers>NASDAQ:A, NASDAQ:B</n:stock_tickers>
    </n:news>
  </url>
</urlset>

Die Datei

Im folgenden findet Ihr eine einfache Lösung, die man sicher erweitern kann. In der SQL-Abfrage ist das Beispiel auf eine Kategorie festgelegt. Dazu wird einfach die ID der Kategorie verglichen (AND $wpdb->term_taxonomy.term_id = (7)). Sollen alle Inhalte gezogen werden, dann genügt das Löschen dieser Zeile. Will man mehrere Kategorien einbinden, dann nutze die folgende Syntax und ändert in die IDs eurer Kategorien.
AND $wpdb->term_taxonomy.term_id IN (3,8,9)


<?php
require('wp-load.php');

// XML header
echo '<?xml version="1.0" encoding="utf-8"?>' . "n";

// urlset
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
				xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">' . "n";

// Select posts; set limit 20
$rows = $wpdb->get_results("SELECT DISTINCT ID, post_date_gmt
                            FROM $wpdb->posts, $wpdb->term_relationships, $wpdb->term_taxonomy
                            WHERE $wpdb->term_relationships.object_id = $wpdb->posts.id
                            AND post_status = 'publish'
                            AND post_type = 'post'
                            AND $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
                            AND $wpdb->term_taxonomy.taxonomy = 'category'
                            AND $wpdb->term_taxonomy.term_id = 7
                            ORDER BY $wpdb->posts.post_date_gmt DESC
                            LIMIT 0, 20");

// sitemap data
// set keywords !

foreach ($rows as $row) {
	echo "t" . '<url>' . "n";

	echo "tt" . '<loc>';
	echo get_permalink($row->ID);
	echo '</loc>' . "n";
	echo "tt" . '<news:news>' . "n";
	echo "tt" . '<news:publication_date>';
	$thedate = substr($row->post_date_gmt, 0, 10);
	$thetime = substr($row->post_date_gmt, 11, 20);
	echo $thedate . 'T' . $thetime . 'Z';
	echo '</news:publication_date>' . "n";
	echo "tt" . '<news:keywords>online, news</news:keywords>' . "n"; // change keywords
	echo "tt" . '</news:news>' . "n";
	echo "t" . '</url>' . "n";
}

// End urlset
echo '</urlset>';
?>

Im obigen Syntax werden die Keywords einmalig statisch vergeben. Werden im Blog zum Beitrag Tags vergeben, dann empfiehlt es sich diese zu nutzen und dort auszulegen. Dazu hilft folgende Erweiterung.


	$tags     = wp_get_post_tags( $row->ID, array('fields' => 'all') );
	$tagcount = count($tags);
	echo "tt" . '<news:keywords>';
	for ($i = 1; $i < $tagcount; $i++) {
		echo $taglist  = str_replace( "'", '', str_replace( '"', '', urldecode($tags[$i]->name) ) );
		if ( $i != $tagcount-1 )
		 echo ', ';
	}
	echo '</news:keywords>' . "n";

Diese Erweiterung wird anstatt der Zeile
echo "tt" . '<news:keywords>online, news</news:keywords>' . "n"; // change keywords
gesetzt und vergibt nun die Tags automatisch, getrennt mit Komma.

Update; Formatumstellung bei Google

Mitte des Jahres 2009 gab es bei Google eine Formatumstellung und der folgende Code nimmt diese Umstellung auf und hat ebenso gleich die Lösung inklusive, die die Tags als Keywords mitgibt.


<?php
/**
 * Google news sitemap with WordPress
 * @author Frank Bueltge - bueltge.de
 * @link https://bueltge.de/google-news-quelle-mit-wordpress-werden/836/
 */
require('wp-load.php');

// XML header
echo '<?xml version="1.0" encoding="utf-8"?>' . "n";

// urlset
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">' . "n";

// Select posts; set limit 20
$rows = $wpdb->get_results("SELECT DISTINCT ID, post_date_gmt, post_title
                            FROM $wpdb->posts, $wpdb->term_relationships, $wpdb->term_taxonomy
                            WHERE $wpdb->term_relationships.object_id = $wpdb->posts.id
                            AND post_status = 'publish'
                            AND post_type = 'post'
                            AND $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
                            AND $wpdb->term_taxonomy.taxonomy = 'category'
                            AND $wpdb->term_taxonomy.term_id IN (7)
                            ORDER BY $wpdb->posts.post_date_gmt DESC
                            LIMIT 0, 20");

// sitemap data
foreach ($rows as $row) {
	echo "t" . '<url>' . "n";
	echo "tt" . '<loc>';
	echo get_permalink($row->ID);
	echo '</loc>' . "n";
	echo "tt" . '<news:news>' . "n";
	echo "ttt" . '<news:publication>' . "n";
	echo "tttt" . '<news:name>' . get_bloginfo('name') . '</news:name>' . "n"; //eventuell haendisch pflegen
	echo "tttt" . '<news:language>' . get_option('rss_language') . '</news:language>' . "n";
	echo "ttt" . '</news:publication>' . "n";
	echo "ttt" . '<news:genres>pressrelease, blog, UserGenerated</news:genres>' . "n"; //eventuell haendisch pflegen
	echo "ttt" . '<news:publication_date>';
	$thedate  = substr($row->post_date_gmt, 0, 10);
	$thetime  = substr($row->post_date_gmt, 11, 20);
	echo $thedate . 'T' . $thetime . 'Z';
	echo '</news:publication_date>' . "n";
	echo "ttt" . '<news:title>' . htmlspecialchars( $row->post_title ) . '</news:title>' . "n";
	$tags     = wp_get_post_tags( $row->ID, array('fields' => 'all') );
	$tagcount = count($tags);
	if ($tagcount > 0) {
		echo "ttt" . '<news:keywords>';
		for ($i = 0; $i < $tagcount; $i++) {
			echo $taglist  = str_replace( "'", '', str_replace( '"', '', urldecode($tags[$i]->name) ) );
			if ( $i != $tagcount-1 )
			 echo ', ';
		}
		echo '</news:keywords>' . "n";
	}
	echo "tt" . '</news:news>' . "n";
	echo "t" . '</url>' . "n";
}
echo '</urlset>';
?>

Aufnahme bei Google

Hat man den obigen Syntax als Datei im Root der Installation aufgerufen und erfolgreich getestet, dann muss man lediglich um die Aufnahme bei Google News bitten. Dazu steht ein Formular zur Verfügung. Dann heißt es abwarten auf die Rückmeldung.
Die Prüfung der Indizierung kann man einfach per Suche in den Google News absolvieren: site:domain.de.

Download:

Plugin „Google News Sitemap“: Download als zip-Datei: google-news-sitemap.zip – 1 kByte

Plugin „Google News Sitemap“ Version 2 mit neuem Format und Keywords (Tags): Download als zip-Datei: google-news-sitemap2.zip – 1 kByte

Datei für Root: Download als zip-Datei: news-sitemap.zip – 1 kByte

Datei für Root mit neuem Format: Download als zip-Datei: news-sitemap2.zip – 1 kByte

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.