How to create a simple sitemap for Wink
I recently switched over to Mohamed Said' Writing Ink, or Wink for short. It's a great feature rich tool for creating blog posts. I was previously using Voyager from TCG.
This also meant that i needed to update my sitemap to pull the posts and categories from a new Model / Database. There are quite a few ways to generate a sitemap, including the fantastic Spatie Laravel Sitemap package.
However for my blog, i know exactly what posts and categories i wanted to be indexed, so I only needed something simple to achieve this.
Step 1 - Create a Sitemap Controller
In your terminal create a new controller, you can call it whatever you want, but i've called mine SitemapController.
php artisan create:controller SitemapController
Seeing that I have more than one section that i want to index (posts and categories), I've created a sitemap index which lists out the two pages. These pages also have their own corresponding sitemaps. To create this you only need 3 methods. Here is the contents of my SitemapController:
namespace App\Http\Controllers;
use Wink\WinkPost;
use Wink\WinkTag;
class SitemapController extends Controller
{
public function index()
{
$article = WinkPost::live()->orderBy('updated_at', 'desc')->first();
return response()->view('sitemap.index', ['article' => $article])->header('Content-Type', 'text/xml');
}
public function articles()
{
$articles = WinkPost::live()->get();
return response()->view('sitemap.posts', ['articles' => $articles])->header('Content-Type', 'text/xml');
}
public function categories()
{
$categories = WinkTag::all();
return response()->view('sitemap.categories', ['categories' => $categories])->header('Content-Type', 'text/xml');
}
}
As you can see, All we need to do is fetch all the posts and categories (Referred to as Tags in Wink) and return the data to blade views with a additional header of text/xml
.
This will output the content type as XML which is what search engines need to read and parse your sitemaps. Next we'll create 3 new views in the resources/views/sitemap
directory and enter the following code into each of them.
Step 2 - Create the sitemap views
resources/views/sitemap/index.blade.php
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://www.danielord.co.uk/sitemap/articles</loc>
<lastmod>{{ $article->created_at->tz('UTC')->toAtomString() }}</lastmod>
</sitemap>
<sitemap>
<loc>https://www.danielord.co.uk/sitemap/categories</loc>
<lastmod>{{ $article->created_at->tz('UTC')->toAtomString() }}</lastmod>
</sitemap>
</sitemapindex>
resources/views/sitemap/posts.blade.php
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($posts as $post)
<url>
<loc>https://www.danielord.co.uk/{{ $post->slug }}</loc>
<lastmod>{{ $post->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>
</url>
@endforeach
</urlset>
resources/views/sitemap/categories.blade.php
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach ($categories as $category)
<url>
<loc>https://www.danielord.co.uk/categories/{{ $category->slug }}</loc>
<lastmod>{{ $category->created_at->tz('UTC')->toAtomString() }}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>
</url>
@endforeach
</urlset>
The XML is pretty standard as far as sitemaps go and we simply iterate over each article / category using a foreach loop.
Step 3 - Create the routes
The final step is to create some routes in the routes/web.php
file.
Route::get('/sitemap', 'App\Http\Controllers\SitemapController@index');
Route::get('/sitemap/articles', 'App\Http\Controllers\SitemapController@posts');
Route::get('/sitemap/categories', 'App\Http\Controllers\SitemapController@categories');
Now you can setup your sitemap urls in Google Search Console or any other search engines. You can use /sitemap
and /sitemap/posts
and this will render the XML we created earlier.