Una sitemap "al volo" per WordPress
Ripeto 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. 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 :
// POSTS SITEMAP CASE: post type parameter sent to script (/wp-sitemap?type=post) -> posts only
if($_GET["type"]=="post"): ?>
<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='post' 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
// PAGES 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
// SITEMAP-NEWS (Google) CASE: post type parameter sent to script (/wp-sitemap?type=posttogoogle) -> posts only
// Note: You should be __already__ indexed by Google News to successfully use this case
elseif($_GET["type"]=="posttogoogle"): ?>
<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
// TAGS SITEMAP CASE: (/wp-sitemap?type=tag) -> tags only
elseif($_GET["type"]=="tag"): ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<?php
$locations = $wpdb->get_results("SELECT slug, tag_history.tagdate AS lastmod FROM (SELECT $wpdb->term_relationships.term_taxonomy_id AS tagid, substr($wpdb->posts.post_date_gmt,1,10) AS tagdate FROM $wpdb->term_relationships INNER JOIN $wpdb->term_taxonomy ON $wpdb->term_taxonomy.term_taxonomy_id=$wpdb->term_relationships.term_taxonomy_id INNER JOIN $wpdb->posts ON $wpdb->posts.ID=$wpdb->term_relationships.object_id WHERE taxonomy='post_tag' AND description!='' ORDER BY post_date_gmt DESC, $wpdb->posts.post_title) AS tag_history INNER JOIN $wpdb->terms ON $wpdb->terms.term_id=tag_history.tagid GROUP BY tag_history.tagid ORDER BY tag_history.tagdate DESC");
foreach ($locations as $location): ?>
<url>
<loc><?php echo site_url(); ?>/tag/<?php echo $location->slug; ?>/</loc>
<lastmod><?php echo $location->lastmod; ?></lastmod>
</url>
<?php endforeach; ?>
<?php else:
endif; ?>
<?php endif; ?>
</urlset>
Si noti che lo script da cinque 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 (anche rispettando le specifiche per le sitemap di Google News); infine è possibile visualizzare una sitemap per i soli tag ordinati cronologicamente in senso decrescente (da quello più recentemente utilizzato) *.
Ecco alcuni esempi usando le sitemap di questo sito:
- cappelli.net/sitemap.php (post e pagine);
- cappelli.net/sitemap.php?type=post (solo post);
- cappelli.net/sitemap.php?type=posttogoogle (solo post, secondo specifiche Google);
- cappelli.net/sitemap.php?type=page (solo pagine).
- cappelli.net/sitemap.php?type=tag (solo tag).
* Si noti che ho aggiunto alla clausola per i tag “.. AND description!='' ..“, che esclude dalla sitemap i tag per i quali non è stata specificata una descrizione (facoltativa in WordPress).
Si consiglia di visualizzare anche il sorgente delle pagine generate..















