How to create a simple sitemap for Wink

Posted on: 11/09/2021. Last updated at: 14/09/2021


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.



Picture of Daniel Ord
Daniel Ord

Building things for the Web. Follow me on Twitter or checkout my GitHub.

More Posts

How to set file permissions for Laravel 5 on mac OSX
Every time I do a fresh install of Laravel I always run into the same error where laravel.log couldn't be...
Perfect PageSpeed score using Bootstrap and mod_pagespeed
I've never really gave the PageSpeed score of the websites that i've built too much consideration, as long as they...
Can't write image data to path - Intervention Image
I recently came across the following error when using Intervention Image with Laravel 5.6: "Can't write image data to path...
How to Install Laravel Spark
Doing a fresh install of Laravel Spark or even an upgrade has proved problematic almost every time i attempt it....
Laravel PDF API
As part of my day job I was required to make PDF's from HTML templates and expose this via an...

Other Categories