Générer un sitemap

Générer automatiquement un fichier sitemap.xml pour un site web

Problématique

Le sitemap.xml est un fichier nécessaire pour améliorer le référencement d'un site web. Il peut être maintenu manuellement. Mais il pourrait être utile de se libérer de cette tâche en le générant automatiquement.

Solution

La difficulté provient de la génération de la date de modification pour chaque fichier. Mais le shell unix permet de résoudre rapidement ce problème grâce à la combinaison find + ls pour tous les fichiers de type html :

find . -type f -name "*.html" | xargs ls -l -D %Y-%m-%d

Il convient ensuite d'extraire les informations requises, soit le nom du fichier et la date de modification (au format %Y-%m-%d), qui correspondent aux champs 7 et 6.

Ces champs doivent être encapsulés dans du xml :

awk '{ print "<url>\n<loc>" $7 "</loc>\n<lastmod>" $6 "</lastmod>\n</url>" }'

Puis, chaque fichier étant positionné en ./, il convient de tous les repositionner à la bonne URL :

sed "s/<loc\>.\//<loc\>${BASE_HTTP}/g"

Avec :

BASE_HTTP="http:\/\/monsite.ext\/chemin\/"

Ensuite, il ne suffit que de créer l'en-tête, la racine, de générer le fichier, de sauver l'ancienne version et de la remplacer par la nouvelle :

#!/bin/sh
#------------------------------------------------------------------
# Fonctions
#------------------------------------------------------------------
extract_base () {
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">'
find . -type f -name "*.html" | xargs ls -l -D %Y-%m-%d | awk -v changefreq="${CHANGE_FREQ:-never}" '{ print "<url>\n<loc>" $7 "</loc>\n<lastmod>" $6 "</lastmod>\n<changefreq>" changefreq "</changefreq></url>" }' | sed "s/<loc\>.\//<loc\>${BASE_HTTP}/g"
echo '</urlset>'
}
#------------------------------------------------------------------
# Variables
#------------------------------------------------------------------
BACKUP_DIR=".bak"
BASE_FILE="sitemap.base.xml"
BASE_HTTP="http:\/\/monsite.ext\/chemin\/"
SITEMAP_FILE="sitemap.xml"
# CHANGE_FREQ valeurs possibles : 
#   always (Utilisez cette valeur pour les pages qui sont modifiées à chaque ouverture.)
#   hourly (chaque heure)
#   daily (chaque jour)
#   weekly (chaque semaine)
#   monthly (chaque mois)
#   yearly (chaque année)
#   never (Utilisez cette valeur pour les URL archivées.)
CHANGE_FREQ=monthly
timestamp=$(date '+%Y%m%d%H%M%S')
#------------------------------------------------------------------
# Programme
#------------------------------------------------------------------
# génération de la liste des fichiers
extract_base > ${BASE_FILE}

# calcul des hashages
[ -f ${BASE_FILE} ] && md5_base=$(md5 -q ${BASE_FILE})
[ -f ${SITEMAP_FILE} ] && md5_sitemap=$(md5 -q ${SITEMAP_FILE})

# sauvegarde de l'ancienne version si le fichier est modifié
[ "${md5_base:-1}" != "${md5_sitemap:-0}" ] && {
# création du répertoire de sauvegarde
[ ! -d ${BACKUP_DIR} ] && mkdir ${BACKUP_DIR}
[ -f ${SITEMAP_FILE} ] && mv ${SITEMAP_FILE} ${BACKUP_DIR}/${SITEMAP_FILE}.${timestamp}
# remplacement par la nouvelle version
mv ${BASE_FILE} ${SITEMAP_FILE}
}
# supprime le fichier temporaire si les fichiers sont identiques
[ "${md5_base:-1}" = "${md5_sitemap:-0}" ] && rm -f ${SITEMAP_FILE}

exit 0

Mise en oeuvre

Il suffit juste d'automatiser la génération du sitemap grâce à une ligne supplémentaire dans /etc/crontab. Par exemple, une exécution une fois par semaine.

La fréquence dépend de la fréquence des modifications des pages du site.