Adding an Auto-Generated Sitemap to Your Jigsaw-based Static Site
!Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.
I love Tighten's static site generator, Jigsaw. I've tried a few other static site generators, and (of course, I'm biased) I think Jigsaw has the best combination of power and simplicity. Plus, it feels like I'm writing Laravel code—because, essentially, I am.
There are a few tasks that are still pretty tough with static sites—for example, search, and submitting forms (which we're trying to fix with FieldGoal). But there are other tasks that are tough-but-possible, and key among them are RSS and sitemaps.
Let's start with sitemaps. Our lead developer on Jigsaw, Keith Damiani, added a feature recently that allows you to add lifecycle hooks to your Jigsaw sites, and he even wrote up how to use those hooks to generate a sitemap. I wanted to try it out, so I did, and I extracted his instructions to this very simple post.
The simple steps
For such a powerful concept, I expected this to be a lot of work. Turns out it took less than fifteen minutes. Let's walk through it step by step:
1. Require the sitemap
package
First, we're going to require on an external package for actually generating the sitemap. Let's pull in samdark/sitemap:
composer require samdark/sitemap
1b. A brief interlude: introduction to Jigsaw's event listeners
Next, we're going to take advantage of the hooks Keith introduced. The new hook system has three events you can listen for: beforeBuild
, afterCollections
, and afterBuild
. Hopefully I can get him to write them up in more detail in a blog post, but for now if you're interested in learning more you can take a look at the pull request.
We'll be using afterBuild
, which allows our system to have access to the full list of the output files when it goes to generate the sitemap. Since the listener we're building is a bit complex, we'll pull this functionality out to a class in a dedicated Listeners
directory.
2. Create the GenerateSitemap
class
Let's start by creating our listener. Make a new directory called Listeners
, and create a new file in it named GenerateSitemap.php
. Paste in the following:
<?php namespace App\Listeners;
use TightenCo\Jigsaw\Jigsaw;
use samdark\sitemap\Sitemap;
class GenerateSitemap
{
public function handle(Jigsaw $jigsaw)
{
$baseUrl = $jigsaw->getConfig('baseUrl');
$sitemap = new Sitemap($jigsaw->getDestinationPath() . '/sitemap.xml');
collect($jigsaw->getOutputPaths())->each(function ($path) use ($baseUrl, $sitemap) {
if (! $this->isAsset($path)) {
$sitemap->addItem($baseUrl . $path, time(), Sitemap::DAILY);
}
});
$sitemap->write();
}
public function isAsset($path)
{
return starts_with($path, '/assets');
}
}
Let's read through this file. First, we're using the $jigsaw
object to pull information out of Jigsaw, including our baseUrl
from the config.
Next, we're creating an instance of our Sitemap
dependency. Its constructor wants us to pass the path the file should be built to, so we're just putting it in build_{environment}/sitemap.xml
.
Next, we work through all the files that are being output (which we get from $jigsaw
's getOutputPaths()
) and adding every file to the sitemap unless it lives in the assets
directory.
Finally, we rely on the Sitemap
package to write the file. Done! ... almost.
3. PSR-4 load the Listeners
directory
Let's get this new directory into our actual app using PSR-4 autoloading. Modify your composer.json
to add a PSR-4 autoloader; it'll look something like this when you're done:
{
"require": {
"tightenco/jigsaw": "^1.2",
"samdark/sitemap": "^2.2"
},
"autoload": {
"psr-4": {
"App\\Listeners\\": "Listeners"
}
}
}
Now just run composer dump-autoload
on the command line, and it's loaded up.
4. Register the GenerateSitemap
class in bootstrap.php
Finally, let's register the afterBuild
event listener in bootstrap.php
:
$events->afterBuild(App\Listeners\GenerateSitemap::class);
Now, as the last step of every Jigsaw build, our GenerateSitemap
class will be invoked and it'll generate our new sitemap.
5. Celebrate!
That's it! On your next build, you'll see sitemap.xml
sitting in your build directory. Boom. Just that easy.
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>
https://mattstauffer.com/why-i-love-jigsaw
</loc>
<lastmod>2017-05-23T00:00:00+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>
</url>
</urlset>
Comments? I'm @stauffermatt on Twitter
Tags: jigsaw