Generera en enkel XML-sitemap i Laravel 5
Har du utvecklat applikationer och webbplatser med Laravel har för förmodligen upptäckt hur bra detta ramverk är. Är du även involverad i SEO vet du säkert också att XML-sitemaps kan vara bra att generera till sökmotorer.
Eftersom Laravel bara är ett skal finns ingen inbyggd funktion för att generera XML-kartor, så jag ska förklara hur du enkelt kan göra det. Man kan generera XML-sitemaps för många olika innehållstyper men de vanligaste är webbadresser och bilder. Hur enkelt det är att generera olika typer i Laravel 5 beror på hur du byggt din applikation, men jag tänkte visa hur jag genererar XML-sitemap för artiklar på denna sajten.
1. Generera en dynamisk robots.txt.
Laravel har en robots.txt i public-mappen som default, men vill man lägga till dynamiskt innehåll är det simpelt att generera denna fil med en vy-fil. Börja med att radera robos.txt i public-mappen och skapa en route för "/robots.txt" i routes.php:
<?php
Route::get('robots.txt', function()
{
return view('robots.robotsTxt');
});
Hur du döper vy-filen och placerar den i mappstrukturen spelar ingen roll, huvudsaken är att du skapar en vy som presenteras vid anrop till "/robots.txt". Jag vill ha flera olika XML-sitemaps så därför väljer jag att generera en index-sitemap som i sin tur listar de sitemaps jag vill ha. Min vy-fil robotsTxt.blade.php ser därför ut såhär:
User-agent: *
Disallow: /sok*
Sitemap: {{ UrlHelper::GetFrontEndUrl() }}/index-sitemap.xml
Då jag har flera olika utvecklingsmiljöer har jag skapat helper-funktionen GetFrontEndUrl() som bara hämtar applikationens domän som jag har i .env-filen. Här kan du ange hela URL:en till sidkartan statiskt om du vill.
2. Skapa routes för sidkartorna.
Nu måste vi även skapa routes för de sidkartor vi vill ha. Jag har en för min index-sitemap och en för artiklar, så routes.php ser ut såhär när jag är klar:
<?php
Route::get('robots.txt', function()
{
return view('robots.robotsTxt');
});
Route::get('index-sitemap.xml', 'WebpageController@sitemapIndex');
Route::get('articles-sitemap.xml', 'WebpageController@sitemapArticles');
Jag använder min controller WebpageController för att hämta data och skicka vidare till vyerna.
3. Hämta artiklar och skicka till vyn.
Min index-sitemap är statisk men jag lägger den i min controller ändå. Funktionen sitemapArticles hämtar alla publicerade artiklar och skickar tillbaka till vyn. Funktionerna i WebpageController ser ut enligt följande:
<?php
public function sitemapIndex()
{
return view('sitemap.index');
}
public function sitemapArticles()
{
$aricle_list = Article::where('status', 'publish')
->orderBy('date', 'DESC')->get();
return view('sitemap.articles', ['aricle_list' => $aricle_list]);
}
4. Lista XML-sitemaps i index-sitemapen
I index-sitemapen sitemap/index.blade.php länkar vi sedan in artikel-sidkartan:
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>{{ UrlHelper::GetFrontEndUrl() }}/articles-sitemap.xml</loc>
</sitemap>
</sitemapindex>
5. Loopa ut artiklar i artikel-sidkartan
Nu behöver vi bara loopa ut alla artiklar i sitemap/articles.blade.php och då ser det ut såhär:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@if($aricle_list && $aricle_list->count() >= 1)
@foreach($aricle_list as $article)
<url>
<loc>{{ action('ArticleController@read', ['slug' => $article->slug]) }}</loc>
</url>
@endforeach
@endif
</urlset>
Även om det går att lägga till fler taggar är adressen i <loc> det enda som egentligen är intressant. Nu är allt klart och http://pereriksson.net/index-sitemap.xml listar http://pereriksson.net/articles-sitemap.xml som det ska.
Ska man verkligen generera XML-sitemaps vid varje anrop?
Givetvis är det inte effektivt att generera XML-sidkartor vid varje anrop, speciellt inte om man har många sidkartor och adresser. En del sajter genererar XML-sitemaps på nytt när artiklar eller sidor skapas, tas bort eller uppdateras, men inte heller det är optimalt. Det bästa är att ha en schemaläggare, exempelvis ett cron job, som genererar dina sidkartor varje dag.