Laravel

Create Sitemap in Laravel 5.6

January 31, 2018

author:

Create Sitemap in Laravel 5.6

Developing a web application is only the half task done in today’s scenario. The other half is making it Search Engine ready! A sufficient amount of success of an application depends on its visibility in search engine. And one of its important aspects is generating and submitting a sitemap to the search engine webmasters.

So, today we will try and create a custom artisan command to generate sitemaps for any Laravel based application. Since Laravel has an ocean of ready to use packages for almost every task, we will also use one of them to create sitemaps.

# Sitemap Package Setup

In your laravel project, install this package from the root directory of your project:

composer require roumen/sitemap

Please verify its version in the composer.json file for different Laravel version. The stable version for Laravel 5.5+ is 2.7.* and for Laravel 5.4 and lower, it is 2.6.*

Since Laravel 5.5+ auto registers service providers, we do not need to add them manually, but for lower Laravel versions, please register the provider in config/app.php:

# config/app.php

'providers' => [
    ...
    Roumen\Sitemap\SitemapServiceProvider::class,
    ...
];

Since we will be creating a Laravel command, we do not really need to publish its assets.

# Sitemap Command Setup

• To build a custom artisan command in Laravel, run:

php artisan make:command GenerateSitemap

This will create a command file with all the necessary default set of properties and methods. It will be stored in app/console/commands/GenerateSitemap namespace:

# app/Console/Commands/GenerateSitemap.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class GenerateSitemap extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
    }
}

# Sitemap Command

  • Let’s first add a command signature that can be used in console as a command and description.
# app/Console/Commands/GenerateSitemap.php
...
class GenerateSitemap extends Command
{
    protected $signature = 'generate:sitemap';
    
    protected $description = 'Generate Sitemap';
    ...
    public function handle()
    {
     //logic
    }
}
  • We can add the custom command logic within handle() method in this file.
# app/Console/Commands/GenerateSitemap.php

use App\Product;
...
public function handle()
{
   // create new sitemap object
    $sitemap = \App::make("sitemap");

    //config
    $siteUrl = 'http://localhost:8000';
    $maxCount = 1000;


    // get all products from db (or wherever you store them)
    $products = Product::take(100)->get()->toArray();

    // counters
    $counter = 0;
    $sitemapCounter = 0;

    if ($counter == 0 && $sitemapCounter == 0) {
        $sitemap->add($siteUrl, date('Y-m-d H:i:s'), '1.0', 'daily');
    }

    // add every product to multiple sitemaps with one sitemapindex
    foreach ($products as $product) {
        if ($counter == $maxCount) {
            // generate new sitemap file
            $sitemap->store('xml', 'sitemap-product-' . $sitemapCounter, 'public/sitemap-sn');
            // add the file to the sitemaps array
            $sitemap->addSitemap($siteUrl . '/sitemap-sn/' . 'sitemap-product-' . $sitemapCounter . '.xml', date('Y-m-d H:i:s'));
            // reset items array (clear memory)
            $sitemap->model->resetItems();
            // reset the counter
            $counter = 0;
            // count generated sitemap
            $sitemapCounter++;
        }

        $final_slug = $siteUrl . '/' . $product['slug'];

        // add product to items array
        $sitemap->add($final_slug, date('Y-m-d H:i:s'), '1.0', 'daily');
        // count number of elements
        $counter++;
    }

    // you need to check for unused items
    if (!empty($sitemap->model->getItems())) {
        // generate sitemap with last items
        $sitemap->store('xml', 'sitemap-product-' . $sitemapCounter, 'public/sitemap-sn');
        // add sitemap to sitemaps array
        $sitemap->addSitemap($siteUrl . '/sitemap-sn/' . 'sitemap-product-' . $sitemapCounter . '.xml', date('Y-m-d H:i:s'));
        // reset items array
        $sitemap->model->resetItems();
    }
  }
}

• The next step is to register this command so that we can use it. To do so, add following line in app/console/Kernel.php file:

# app/Console/Kernel.php
...
protected $commands = [
    Commands\GenerateSitemap::class,
];
...

# Generate a Sitemap

Now, to generate the sitemap and store in our application, run the following command:

php artisan generate:sitemap
Laravel Command to generate sitemap

You can check the generated sitemap in the public directory of your project:
Sitemaps in Laravel

# public/sitemap-sn

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://localhost/vendor/sitemap/styles/sitemapindex.xsl" type="text/xsl"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <sitemap>
	<loc>http://localhost:8000/sitemap-sn/sitemap-product-0.xml</loc>
        <lastmod>2018-02-06T06:29:33+00:00</lastmod>
   </sitemap>	
</sitemapindex>
# public/sitemap-product-0
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://localhost/vendor/sitemap/styles/xml.xsl" type="text/xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  <url>
    <loc>http://localhost:8000</loc>
    <priority>1.0</priority>
    <lastmod>2018-02-06T06:29:33+00:00</lastmod>
    <changefreq>daily</changefreq>
  </url>
</urlset>

Conclusion:

To generate a sitemap, we used a third party library. Later, we generated a Laravel command to create a cron and configured it to suit our sitemap library and then ran the command to create the sitemap. It is important to note that each application has a different working model and thus each of them would need a little tweak to align sitemap generation.

QUESTIONS & COMMENTS:

Thank you for reading. If you suggestions and questions, share them in the comment section below.

Leave a comment

Your email address will not be published. Required fields are marked *