Flux RSS

Les tutoriels - Créer un sitemap pour son site


sitemap.jpg

Dans ce tutoriel, nous allons voir à quoi va nous servir un Sitemap et comment le créer.

Pour apparaître sur un moteur de recherche, il faut que les pages de votre site soient indexées dans leur base de données.
Pour cela il faut attendre qu'un crawler (également appelé bot ou spider) passe par votre site, enregistre la page, trouve tous les liens qu'il y a sur celle-ci et les stockent pour un futur passage.
En faisant cela, il ne trouve qu'une partie des pages de votre site il faudra attendre plusieurs autres passages avant qu'il ne découvre tous les liens menant aux autres pages de votre site web. On appelle ça l'indexation naturelle.

Maintenant, un outil peut vous permettre d'indiquer aux crawler toutes les pages de votre site et ce dès son premier passage.
C'est le protocole Sitemaps, proposé en 2005 par Google et adopté en novembre 2006 par les principaux moteur de recherche de l'époque Google, Yhaoo et Microsoft.

Un Sitemap c'est quoi ?

C'est un fichier au format XML qui liste :
  • Les urls du site (maximum 50000 ou 10 Mo).
  • La date de sa dernière mise à jour.
  • A quelle fréquence des changements sont effectués sur la page.
  • Et son importance par rapport aux autres pages du site.

Grâce à toutes ces informations, les moteurs de recherche pourront indexer intelligemment votre site web.
Voici un exemple de Sitemap.

Code : XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
<?xml version='1.0' encoding='UTF-8' ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://www.mon-site-web.com</loc>
    <lastmod>2007-06-03</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>http://www.mon-site-web.com/une-page-web.html</loc>
    <lastmod>2007-05-15</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.1</priority>
  </url>
  <url>
    <loc>http://www.mon-site-web.com/une-autre-page-web.html</loc>
    <lastmod>2007-06-06</lastmod>
    <changefreq>daily</changefreq>
    <priority>0.1</priority>
  </url>
</urlset>

Un sitemap pour notre site web


Comment créer un sitemap

C'est une bonne question, il y a plusieurs solutions possibles.
  • A la main avec un éditeur de texte, si vous n'avez que deux ou trois pages qui ne changent jamais cela suffira largement. Mais c'est une solution à oublier dans le cas d'un site web dynamique avec beaucoup de contenu.
  • Il existe des logiciels externe qui peuvent se charger de créer votre sitemap, mais la solution peut s'avérer fastidieuse à la longue. Une fois généré vous devrez uploader le fichier sur votre serveur ce qui n'est pas forcement pratique. De plus il y a souvent des limitations d'utilisation.
  • La dernière solution est d'utiliser un script ou une classe qui va se charger du travail à notre place. On lui envoie les données qu'on veut voir afficher dans notre sitemap et il fait tout le reste. C'est cette solution que l'on va utiliser dans ce tutoriel.

Un sitemap c'est la Class

Pour que le code PHP utilisé dans ce tutoriel fonctionne correctement, vous devez utiliser une version de PHP supérieur ou égale à la 5.1.2
Car dans ce tutoriel, nous allons utiliser des fonctions récentes de PHP

Pour nous faciliter le travail on va faire une petite Class PHP qui va nous permettre de générer notre sitemap.

Dans ce tutoriel, nous allons prendre pour habitude d'utiliser le format CamelCase pour nommer les fichiers et pour le nom des Class, attribues et méthodes.
Pour améliorer la lisibilité des fichiers que l'on va utiliser, un fichier contenant une Class se terminera toujours par .class.php
Un attribue ou une méthode déclarée en Private commencera toujours par un underscore (_), toujours dans le but d'augmenter la lisibilité.

On crée donc un nouveau fichier, que l'on va appeler SitemapGenerator.class.php
Voyons voir la structure de notre Class.

Code : PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
class SitemapGenerator {
 
  //Nombre d'urls maximum par fichier
  private $_maxUrlsPerFile = 50000;
  //Nombre d'urls ajoutés au sitemap
  private $_totalUrls = 0;
  //L'url de base du site web
  private $_rootUrl = "";
  //Le chemin où l'on va enregistrer notre sitemap
  private $_savePath = "";
  //Contient notre objet XmlWriter
  private $_xml;
  //Fichier sitemap en cours d'utilisation
  private $_file;
  //Stocke dans un tableau toutes les urls qu'on veut enregistrer
  private $_urls = array();
 
  public function __construct() {
 
  }
 
  //Un setter pour pouvoir modifier l'attribut savePath
  public function setSavePath($savePath) {
    $this->_savePath = $savePath;
  }
 
  //Ici on va préparer notre fichier sitemap
  private function _newSitemapFile() {
 
  }
 
  //C'est grâce à cette méthode qu'on va pouvoir ajouter des liens dans notre sitemap
  public function addUrl() {
 
  }
 
  //Il nous reste plus qu'à créer et enregistrer les fichiers
  public function generate() {
 
  }
}

On a défini nos attribues et nos méthodes, on va maintenant commencer la partie technique de ce tutoriel.

Construire une base solide

Le constructeur va nous permettre d'initialiser nos attribues.

Code : PHP
1
2
3
4
public function __construct($rootUrl = "") {
  //On définit l'url de base de notre site web
  $this -> _rootUrl = !empty($rootUrl) ? $rootUrl : 'http://' . $_SERVER['SERVER_NAME'];
}

On a utilisé une condition ternaire pour définir $this -> _rootUrl.
C'est une version courte d'un if/else, dans notre cas si $rootUrl n'est pas vide $this -> _rootUrl égal $rootUrl sinon $this -> _rootUrl égal 'http://' . $_SERVER['SERVER_NAME'].

Les if et else sont remplacés par les symboles ( ? et : ), une condition ternaire est toujours utilisée sous cette forme (if puis else). On ne peut jamais utiliser de elseif.
$_SERVER['SERVER_NAME'] nous retourne le nom du serveur qui exécute le script, par exemple www.mon-site-web.com

Ajoutons des Urls à notre sitemap

On doit d'abord savoir ce qu'on veut ajouter !
Comme on l'a vu plus haut pour bien faire un sitemap utilise plusieurs données (dans notre cas quatre suffiront). Il faut les transmettre à notre Class pour quelle puisse les enregistrer.
Le seul argument obligatoire est l'url. Les autres sont facultatifs, mais on ne doit pas les négliger.

Code : PHP
1
2
3
4
5
//L'url, la dernière modification, la fréquence à laquelle la page est modifiée 
//et pour finir l'importance de cette page par rapport au-autre.
public function addUrl($url, $lastmod = "", $freq = "", $prio = "") {
 
}

On aurait très bien pu passer un tableau à notre méthode, mais de cette manière on évite les éventuelles erreurs

Traitons ces données pour pouvoir les ajouter à notre sitemap.
Pour chaque appel à la méthode addUrl() on va créer une entrée dans un tableau avec les informations qui sont passées en arguments.

Code : PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//On vérifie si l'url commence par un / sinon on l'ajoute
$url = $url[0] === '/' ? $url : '/'.$url;
 
//On vérifie si la dernière date de modification n'est pas vide
//et si elle est au bon format année-mois-jour
if ($lastmod != "" AND preg_match ('`^[0-9]{4}\-[0-1][0-9]\-[0-3][0-9]$`i',$lastmod)) {
  //On sépare les jours, mois et année au niveau des tirets
  $date = $date = explode('-', $lastmod);
  //On vérifie si la date existe, si oui on l'utilise et sinon on la vide
  $lastmod = checkdate($date[1], $date[2], $date[0]) ? $lastmod : "";
} else {
  //Sinon on vide la date
  $lastmod = "";
}
 
//On vérifie si la fréquence n'est pas vide
if ($freq != "") {
  //Ce tableau contient toutes les options possibles pour la fréquence de changement de la page
  $change = array('always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never');
  //L'argument $freq dois faire partie de ce tableau sinon on le vide.
  $freq = in_array($freq, $change) ? $freq : "";
}
 
 
//On vérifie si la priorité n'est pas vide
if ($prio != "") {
  //on vérifie si la priorité est numérique ou pas comprise entre 0 et 1
  if (!is_numeric($prio) OR $prio < 0 OR $prio > 1) {
    $prio = "";
  }
}
 
//On a tout vérifié, on ajoute une ligne dans notre tableau d'urls
$this -> _urls[] = array('loc' => $url, 'mod' => $lastmod, 'freq' => $freq, 'prio' => $prio);

Comme vous avez surement du le remarquer, ici je ne gère pas les erreurs, je me contente juste de vider la variable.
La raison est très simple, faire une bonne gestion des erreurs est très long et comme ce n'est pas le sujet de ce tutoriel, je ne préfère pas les gérer ici.

Un nouveau sitemap

Comme on le verra plus loin dans ce tutoriel, un fichier sitemap ne peut comporter plus de 50000 urls. Pour beaucoup de site c'est largement suffisant, mais pour de gros sites cette limite est rapidement atteinte. La solution la plus simple est de créer un nouveau fichier à chaque fois qu'on atteint cette limite.

Nous allons maintenant voir comment sont créés ces fichier.
Pour commencer, il va falloir définir le nom de chaque fichier en fonction du nombre d'urls déjà enregistrées.
Pour préparer le fichier on utilisera fopen et XmlWriter.

Code : PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private function _newSitemapFile() {
  //On definie notre variable
  $fileNbr = "";
  //Si le nombre d'urls est supérieur a 0, on détermine le nom du fichier
  if($this->_totalUrls > 0)
    $fileNbr = intval($this -> _totalUrls / $this -> _maxUrlsPerFile +1);
  //Si le nombre est supérieur à 1, on l'utilise dans le nom du fichier sinon on laisse vide
  $fileNbr = $fileNbr > 1 ? $fileNbr : "";
  //On définit le nom du fichier
  $filename = $this->_savePath . 'sitemap' . $fileNbr . '.xml';
  //On récupère le répertoire
  $dirname = dirname($filename);
  //On vérifie si le répertoire existe
  if (!is_dir($dirname)) {
    //Sinon on crée le répertoire
    mkdir($dirname, 0755, true);
  }
  //Et on crée le fichier
  $this -> _file = fopen($filename, "w");
 
  //On instancie XmlWriter
  $this -> _xml = new XmlWriter();
  //On utilise la mémoire pour l'affichage
  $this -> _xml -> openMemory();
  //On active l'indentation
  $this -> _xml -> setIndent(TRUE);
  //On définit comment sera indenté chaque élément, ici deux espaces
  $this -> _xml -> setIndentString('  ');
  //On commence un nouveau document en indiquant la version ici 1.0 et l'encodage
  $this -> _xml -> startDocument('1.0', 'UTF-8');
  //On crée un nouvel élément, comme on l'a vu un sitemap commence toujours par un urlset.
  $this -> _xml -> startElement("urlset");
  //Qui possède un attribut xmlns
  $this -> _xml -> writeAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
}

Notre fichier est créé et prêt à être rempli.

Enregistrer le contenu

Pour le moment, on a vu dans ce tutoriel comment ajouter des liens et créer un nouveau fichier. Nous allons voir maintenant comment tout réunir dans notre sitemap et l’enregistrer sur notre site.

Pour commencer, une petite explication. Le protocole Sitemaps comporte une limitation, deux en fait :p

  • Un fichier sitemap ne peut pas contenir plus de 50 000 urls
  • Et un fichier sitemap ne peut pas peser plus de 10 Mo (Méga octets)

Vous allez me dire, c'est très embêtant, comment va t'on faire. 50 000 urls ça fait déjà beaucoup, je ne suis pas sûr que beaucoup de site (sans parler des très gros sites) arrivent à cette limite. Malgré tout on va en tenir compte et adapter notre code, on n'est peut-être limité en nombre d'urls, mais pas en nombre de sitemap.
Vous avez bien lu, on peut avoir plusieurs sitemap pour le même site, donc plusieurs fois 50 000 ça peut faire beaucoup d'urls voir même une infinité :D

Qu'allons-nous faire? On va d'abord vérifier le nombre d'urls pour savoir si on doit créer un nouveau fichier ou pas.
Puis on va remplir le fichier en cours avec les urls que l'on a stockées. Une fois fini, on enregistre et on ferme le sitemap.

Comme je l'ai déjà dit plus haut dans le tutoriel, on a aucune gestion des erreurs. Car ce n'est pas le but de ce tutoriel.

Code : PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public function generate() {
  //On parcourt les urls enregistrées
  foreach ($this -> _urls as $v) {
    //on va utiliser un modulo "%" si le résultat est de 0 il faut créer un nouveau fichier
    if ($this -> _totalUrls % $this -> _maxUrlsPerFile == 0) {
      //Si on est déjà en train d'écrire dans un fichier, on ferme le dernier élément
      if($this -> _file) {
        $this -> _xml -> endElement();
        //On complète le fichier puis on le ferme
        fwrite($this -> _file, $this -> _xml -> flush());
        fclose($this -> _file);
      }
      //On crée un nouveau fichier
      $this -> _newSitemapFile();
    }
   
    //On commence une nouvel url
    $this -> _xml -> startElement("url");
    //On écrit l'url
    $this -> _xml -> writeElement("loc", $this -> _rootUrl . $v["loc"]);
 
    //Si on a une date de modification, on l'ajoute
    if(!empty($v["mod"]))
      $this -> _xml -> writeElement("lastmod", $v["mod"]);
 
    //Si on a une fréquence de modification, on l'ajoute
    if(!empty($v["freq"]))
      $this -> _xml -> writeElement("changefreq", $v["freq"]);
 
    //Et enfin si on a une priorité, on l'ajoute
    if(!empty($v["prio"]))
      $this -> _xml -> writeElement("priority", $v["prio"]);
 
    //On ferme l'élement url
    $this -> _xml -> endElement();
    //Pour ne pas saturer la mémoire du serveur on écrit déjà ça dans le fichier
    fwrite($this -> _file, $this -> _xml -> flush());
//Puis on la comptabilise
$this->_totalUrls++;
 
  //fin du foreach
  }
  //Comme au-dessus, on ferme le dernier élément
  $this -> _xml -> endElement();
  //On complète le fichier puis on le ferme
  fwrite($this -> _file, $this -> _xml -> flush());
  fclose($this -> _file);
}

Mise en place et fonctionnement


Il va nous falloir deux nouveaux fichiers: un qui va nous permettre de récupérer toutes les données qu'on veut enregistrer sur notre sitemap et un qui va nous permettre d'indiquer au robot l'emplacement de nos sitemaps, commençons par celui-ci.

Ce fichier doit se nommer robots.txt et doit contenir l'adresse de tous les sitemap de votre site sous ce format.

Code : Texte
1
Sitemap: http://www.mon-site-web.com/sitemaps/sitemap.xml

Donc nous n'avons ici qu'un seul fichier sitemap et il se trouve dans le répertoire sitemaps.

Ici on a un petit site donc on peut créer le fichier robots.txt à la main.
Pour un gros site qui possède plusieurs sitemap, il sera plus simple de modifier ce fichier automatiquement au fur et à mesure que sont créés les sitemap.

Pour le deuxième fichier, vous pouvez l'appeler comme vous voulez et le stocker comme bon vous semble. Il faudra le sécuriser pour que seuls les administrateurs du site puissent y accéder et créer un lien dans votre administration.
On a tout ce qu'il faut pour créer nos fichiers sitemaps, mais on doit encore envoyer les informations vers notre Class si on veut que cela marche.
Occupons nous de remplir le dernier fichier que l'on vient de créer.

Dans ce tutoriel on ne va pas voir comment faire pour récupérer les urls de votre site. Il y a trop de possibilités différentes en fonction du système que vous utilisez.
Je pars du principe que vous savez déjà le faire, sinon vous ne seriez pas ici :-°

Pour l'exemple, je vais utiliser un tableau que j'aurais pu récupérer depuis une base de données et qui va me servir à construire mes urls.

Code : PHP
1
2
3
4
5
6
7
8
$urls = array(
  array("type" => "blog", "id" => 1, "date" => "2011-12-22"),
  array("type" => "blog", "id" => 2, "date" => "2011-12-25"),
  array("type" => "blog", "id" => 3, "date" => "2011-12-31"),
  array("type" => "blog", "id" => 4, "date" => "2012-01-15"),
  array("type" => "tutoriel", "id" => 1, "date" => "2011-12-28"),
  array("type" => "tutoriel", "id" => 2, "date" => "2012-01-23")
);

On a donc quatre messages venant du blog et deux tutoriels.

On va commencer par instancier notre Class et la configurer.

Code : PHP
1
2
3
4
5
6
//j'instancie ma Class et afin d'être sur je lui passe qu'en même l'adresse de mon site
//Normalement il doit la trouver tout seul grâce au constructeur, mais comme ça je vous montre cette option
$mapsgen = new SitemapGenerator("http://www.mon-site-web.com");
//De base les sitemaps s'enregistrent à la racine du site, je préfère les mettre dans un répertoire.
//Donc je configure le chemin du répertoire
$mapsgen -> setSavePath("sitemaps/");

Notre Class est prête, il n'y a plus qu'à envoyer les données.

Mais comment on fait pour les pages qui ne sont pas dans le tableau ?

Pour toutes les pages, celles qui viennent d'une base de données ou autre, la technique d'enregistrement est la même. On rentre les pages "static" (Accueil, Contact...) à la main .

Code : PHP
1
2
3
4
5
//La page d'accueil, premier paramètre vide pour l'url, pas de date de modification, 
//elle change tout le temps et elle est très importante
$mapsgen -> addUrl("", "", "always", "1.0");
//La page de contact, on donne l'url complète, pas de date, elle ne change jamais et n'est que moyennement importante
$mapsgen -> addUrl("contact.html", "", "never", "0.5");

Passons à notre tableau, la technique est la même sauf qu'il faut parcourir le tableau.

Code : PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
foreach ($urls as $u) {
  //Crée nos variables avec les valeurs de base
  $freq = "";
  $prio = "0.5";
 
  //On définit la priorité et la fréquence en fonction du contenu
  if($u["type"] == "blog") {
    $freq = "weekly";
    $prio = "0.8";
  }
  if($u["type"] == "tutoriel") {
    //Les tutoriels sont mis à jour très régulièrement donc on met la fréquence à journalière
    $freq = "daily";
    //Pour ce site les tutoriels sont très importants
    $prio = "1.0";
  }
  //Puis on ajoute chaque url en construisant correctement l'adresse
  $mapsgen -> addUrl($u["type"]."/".$u["id"].".html", $u["date"], $freq, $prio);
}

Pour finir on génère le sitemap.

Code : PHP
1
2
//On utilise la fonction generate() pour créer les fichier sitemap et les enregistrer.
$mapsgen -> generate();

Si tout s'est bien passé, le fichier sitemap a été correctement créé.

Voilà ce tutoriel touche à sa fin, j'espère qu'il vous aura été utile.
En cas de problème avec ce tutoriel n'hésitez pas à laisser un commentaire, je me ferais un plaisir de vous répondre.

Veuillez vous connecter pour laisser un commentaire


#1 | Ecrit par porquetlerouge le 11/12/2013 à 11h00

le deuxiemème fichier pour la connexion

avatar.png
#2 | Ecrit par lunariel le 16/12/2013 à 01h16

J'ai pas bien compris la question, il dois manquer quelques morceau à ta phrase euh .