Una sitemap "al volo" per WordPress

mysql logoRipeto l’esperienza – per me nuova – di pubblicare codice su questo blog con una sitemap per WordPress . Non si tratta di un plugin, neppure di qualcosa di complicato. Non potendo io per primo far affidamento su un fopen() (per modificare un file tipo sitemap.xml), infatti, perché nella configurazione del mio hosting non è attivato, non mi è rimasto altro da fare che creare uno script (un file) che generasse la sitemap al volo. Tanto i Web Master Tools di Google sarebbero stati l’unico visitatore. Il codice che segue deve essere trascritto in un file (i.e. wp-sitemap.php) da porre nella root dell blog di WordPress.

<?php echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; ?>
<?php
// loading WP vars, functions and dB link
require( './wp-load.php' );
wp();
global $wpdb;
// DEFAULT CASE: no parameters (/wp-sitemap.php) -> posts and pages (sorted)
if (empty($_GET["type"])): ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	<?php
	$locations = $wpdb->get_results("SELECT guid as loc, substr(post_date_gmt,1,10) as lastmod 
		FROM $wpdb->posts WHERE post_status='publish' ORDER BY post_type DESC, post_date_gmt DESC");
	foreach ($locations as $location): ?>
<url>
		<loc><?php echo $location->loc; ?></loc>
		<lastmod><?php echo $location->lastmod; ?></lastmod>
	</url>
	<?php endforeach; ?>
<?php else :
	// SITEMAP-NEWS (Google) CASE: post type parameter sent to script (/wp-sitemap?type=post) -> posts only
	// Note: You should be __already__ indexed by Google News to successfully use this case
	if($_GET["type"]=="post"): ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
	<?php
		$locations = $wpdb->get_results("SELECT guid as loc, post_title as news_title, substr(post_date_gmt,1,10) AS news_date,
			group_concat(name SEPARATOR ', ') AS news_keywords FROM $wpdb->posts INNER JOIN $wpdb->term_relationships ON 
			$wpdb->posts.ID=$wpdb->term_relationships.object_id INNER JOIN $wpdb->term_taxonomy ON 
			$wpdb->term_relationships.term_taxonomy_id=$wpdb->term_taxonomy.term_taxonomy_id INNER JOIN $wpdb->terms ON 
			$wpdb->term_relationships.term_taxonomy_id=$wpdb->terms.term_id WHERE post_status='publish' AND post_type='post' 
			AND taxonomy='post_tag' GROUP BY ID ORDER BY post_date_gmt DESC");
		$blogname=get_bloginfo('name');
		$bloglang=get_bloginfo('language');
		foreach ($locations as $location): ?>
<url>
		<loc><?php echo $location->loc; ?></loc>
		<news:news>
			<news:publication>
				<news:name><?php echo $blogname; ?></news:name>
				<news:language><?php echo $bloglang; ?></news:language>
			</news:publication>
			<news:genres>Blog</news:genres>
			<news:publication_date><?php echo $location->news_date; ?></news:publication_date>
			<news:title><?php echo apply_filters('the_title_rss', $location->news_title); ?></news:title>
			<news:keywords><?php echo wp_specialchars(strtolower($location->news_keywords)); ?></news:keywords>			
		</news:news>
	</url>
		<?php endforeach; ?>
		
	<?php
	// STANDARD SITEMAP CASE: post type parameter sent to script (/wp-sitemap?type=page) -> pages only
	elseif($_GET["type"]=="page"): ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
		<?php
		$locations = $wpdb->get_results("SELECT guid as loc, substr(post_date_gmt,1,10) as lastmod 
			FROM $wpdb->posts WHERE post_status='publish' AND post_type='page' ORDER BY post_date_gmt DESC");
		foreach ($locations as $location): ?>
<url>
		<loc><?php echo $location->loc; ?></loc>
		<lastmod><?php echo $location->lastmod; ?></lastmod>
	</url>
		<?php endforeach; ?>
	<?php else: ?>
	
	<?php endif; ?>
<?php endif; ?>
</urlset>

Si noti che lo script da tre possibilità: se eseguito senza parametri restituisce sia le pagine che i post del blog, altrimenti è possibile specificare se far restituire solo le prime od i secondi (rispettando le specifiche per le sitemap di Google News).

Ecco alcuni esempi usando le sitemap di questo sito:

Si consiglia di visualizzare anche il sorgente delle pagine generate..