Liker
Discuter
Partager
Offrir
Youtube

Laravel : Créer un sitemap

Mis à jour il y a 1 mois

Un tutoriel pour mettre en place un sitemap (plan de site) dans un projet Laravel pour l'indexation automatique des URLs sur les moteurs de recherche.

Wilo Ahadi

Auteur

Wilo A.

Technologies

Laravel, PHP

Introduction au sitemap

Sitemap est un protocole qui permet au webmaster d’informer les moteurs de recherches des pages d’un site web disponibles pour l’indexation automatique.

Il s’agit d’un fichier, généralement présenté au format XML ou texte, qui répertorie ou liste les adresses (URLs) d’un site web en permettant d’inclure des informations complémentaires pour chaque adresse tels que la date de dernière modification, la fréquence de mise à jour, la priorité par rapport aux autres adresses, ...

Les moteurs de recherche tels que Google lisent le sitemap pour explorer plus intelligemment un site web, présenter les statistiques sur les recherches qui aboutissent aux pages de ce site, …

Nous voulons voir comment mettre en place un sitemap (plan de site) dynamique au format XML dans un projet Laravel.

Le protocole sitemap

Le protocole sitemap utilise des tags XML pour décrire l'information. Le fichier XML qui contient ces tags doit être encodé en UTF-8.

Voici l’exemple d’un sitemap au format XML avec une URL renseignée :

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.monsite.com/posts</loc>
      <lastmod>2020-06-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>

Décrivons ce schéma :

  • <urlset> (requis) : Encapsule les URLs et indique l'espace de noms (namespace)
  • <url> (requis) : Tag parent pour chaque entré d’URL
  • <loc> (requis) : L’URL de la page
  • <lastmod> (optionnel) : Date de la dernière mise à jour de la page. La valeur doit respecter l’un de formats Date and Time recommandé par W3C. 
  • <changefreq> (optionnel) : La fréquence (périodicité) de mise à jour de la page. Les valeurs valides sont « always », « hourly », « daily », « weekly », « monthly », « yearly », « never »
  • <priority> (optionnel) : L’importance de l’URL par rapport aux autres URLs. La valeur doit être comprise entre "0.0" et "1.0". La valeur de priorité par défaut est "0.5".

Seuls les tags <urlset>, <url> et <loc> sont requis. Les tags <lastmod>, <changefreq> et <changefreq> sont au choix.

Notez bien : Dans un fichier XML, la valeur d'un tag (y compris pour une URL) doit utiliser les codes d'échappement pour les caractères énumérés au tableau ci-dessous :

Caractère Code d'échappement
Ampersand & &amp;
Single Quote ' &apos;
Double Quote " &quot;
Greater Than > &gt;
Less Than < &lt;

Mettre en place un sitemap

Partant du schéma que nous venons de décrire au protocole sitemap, mettons en place un sitemap pour les publications d’un site web que nous supposons être représentées par le modèle « Post » (table « posts ») dans un projet Laravel.

Notez Bien : Pour bien organiser l’application, nous vous recommandons de toujours créer un sitemap spécifique à chaque modèle, c’est-à-dire aussi une route spécifique pour chaque sitemap. Voici comment le faire en trois étapes :

1. La route

Au fichier routes/web.php, ajoutons la ligne suivante :

Route::get("sitemap/posts", "SitemapController@posts")->name("sitemap.posts");

Cette URL « sitemap/posts » (GET) nommée « sitemap.posts » est gérée par la méthode « posts » du contrôleur « SitemapController ».

Si vous le désirez, vous pouvez ajouter l’extension à l’URL : « sitemap/posts.xml »

2. Le contrôleur

Générons le contrôleur « SitemapController » en exécutant la commande artisan suivante :

php artisan make:controller SitemapController

Au fichier App/http/SitemapController.php généré, décrivons la méthode « posts » où nous récupérons les publications (données) « Post » de la base de données puis retournons une réponse de contenu XML en passant les données à la vue « sitemaps.posts » :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Post;

class SitemapController extends Controller
{
    public function posts () {
    	$posts = Post::latest()->get();
    	return response()->view('sitemaps.posts', compact('posts'))->header('Content-Type', 'text/xml');
    }
}

3. La vue

Créons le fichier resources/views/sitemaps/posts.blade.php où nous parcourons les différentes publications (collection de « Post ») en présentant pour chacune d’elles une <url> du sitemap :

@php echo '<?xml version="1.0" encoding="UTF-8"?>' @endphp
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	@foreach ($posts as $post)
	<url>
	  <loc>{{ route('posts.show', $post) }}</loc>
	  <lastmod>{{ $post->updated_at->tz('UTC')->toAtomString() }}</lastmod>
	  <changefreq>monthly</changefreq>
	  <priority>0.8</priority>
	</url>
	@endforeach
</urlset>

Notez la façon dont nous affichons à la première ligne le code <?xml version …> :

@php echo '<?xml version="1.0" encoding="UTF-8"?>' @endphp

C’est pour qu’il n’y ait pas de confusion entre la syntaxe XML et PHP.

L’index des sitemaps

Nous vous avions recommandé de créer un sitemap spécifique à chaque modèle pour bien organiser l’application. Ce qui peut nous faire plusieurs sitemaps si nous avons plusieurs modèles.

Il faut aussi noter qu’un fichier sitemap ne peut contenir plus de 50000 URLs, ni peser plus de 50Mo (52,428,800 bytes) d’où il faut encore avoir plusieurs sitemaps quand on dépasse ces limites.

Si nous avons plusieurs sitemaps, nous pouvons les grouper (les lister) dans un fichier sitemap index. Il ne doit lui aussi avoir plus de 50000 sitemaps, ni peser plus de 50Mo.

Voici l’exemple d’un sitemap index qui liste deux sitemaps :

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <sitemap>
      <loc>http://www.example.com/sitemap1.xml</loc>
      <lastmod>2020-03-02T22:31:39+00:00</lastmod>
   </sitemap>
   <sitemap>
      <loc>http://www.example.com/sitemap2.xml</loc>
      <lastmod>2020-04-01</lastmod>
   </sitemap>
</sitemapindex>

Décrivons ce schéma :

  • <sitemapindex> (requis) : Encapsule les informations de tous les sitemaps et indique le namespace
  • <sitemap> (requis) : Tag parent pour chaque entrée de sitemap
  • <loc> (requis) : L’URL du sitemap
  • <lasmod> (optionnel) : La date de la dernière mise à jour du sitemap. Sa valeur doit respecter l’un de formats Date and Time recommandé par W3C

Complétons le sitemap que nous avons mis en place précédemment en ajoutant pour le sitemap index :

  • La route « sitemap/index »
  • La méthode « index » au contrôleur « SitemapController »
  • La vue « index.blade.php »

1. La route

Ajoutons au fichier routes/web.php la route GET « sitemap/index » qui va être géré par la méthode « index » du contrôleur « SitemapController ». Nommons-la « sitemap.index » :

Route::get("sitemap/index", "SitemapController@index")->name("sitemap.index");

2. Le contrôleur

La méthode « index » du contrôleur « SitemapController » récupère la dernière entrée « Post » dont on utilisera la date pour indiquer la dernière mis à jour du sitemap « sitemap/posts », puis retourne une reponse de contenu XML en passant les données à la vue « sitemaps.index » :

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Post;

class SitemapController extends Controller
{
	// Sitemap index
	public function index () {
		$post = Post::latest()->first();
		return response()->view("sitemaps.index", compact('post'))->header('Content-Type', 'text/xml');
	}

	// Sitemap posts ...
}

3. La vue

Nous allons supposer avoir un sitemap supplémentaire de route nommée « sitemap.pages » et de vue resources/views/sitemaps/pages.blade.php qui liste les autres pages du site web.

Le code source de la vue resources/views/sitemaps/pages.blade.php avec les routes nommées « welcome », « login » et « register » peut se présenter de la manière suivante :

@php echo '<?xml version="1.0" encoding="UTF-8"?>' @endphp
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>{{ route('welcome') }}</loc>
  </url>
  <url>
    <loc>{{ route('login') }}</loc>
  </url>
  <url>
    <loc>{{ route('register') }}</loc>
  </url>
</urlset>

En intégrant ce sitemap supplémentaire dans l'index des sitemaps, la vue resources/views/sitemaps/index.blade.php devient :

@php echo '<?xml version="1.0" encoding="UTF-8"?>' @endphp
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <sitemap>
      <loc>{{ route('sitemap.pages') }}</loc>
   </sitemap>
   <sitemap>
      <loc>{{ route('sitemap.posts') }}</loc>
      <lastmod>{{ $post->updated_at->format("Y-m-d") }}</lastmod>
   </sitemap>
</sitemapindex>

Notez bien : C'est à travers l'adresse du sitemap index qu'on soumet tous les sitemaps d'un site web aux moteurs de recherches.

👉 Voir comment envoyer un sitemap à Google

Packages de sitemap pour Laravel

En parcourant le web, nous trouvons des packages Laravel qui traitent avec le protocole sitemap, voici deux d'entre eux qui peuvent vous inspirer :

Portez-vous bien ! 😉

Cette publication vous a plu ?
Encouragez-nous en la partageant sur les réseaux sociaux

Wilo Ahadi
Wilo Ahadi, l'auteur

Passionné de l'informatique, je suis spécialiste en techniques des systèmes et réseaux, développeur web et mobile, infographiste et designer, ... J'aime partager mon expérience en formant sur la plateforme Akili School

Voir profil Suivre

Commentaires