tickteam-darylp's avatar

Dynamic sitemaps

Hi all,

We've got a custom solution that we use for client sites. A CMS if you will. This has pages, by default, and through plugins you can install blogs, events, eCommerce solutions too.

We run a scheduled task, at midnight, which generates the sitemap - but only for pages. The sitemap package we use is: spatie/laravel-sitemap

We would like to allow the additional areas to also generate their sitemaps.

My idea was to keep the scheduled task but then dispatch an event that these areas could listen to. We'd then have the following sitemaps (similar to Yoast):

  • sitemap-pages.xml
  • sitemap-posts.xml
  • sitemap-events.xml

Once these are generated, then the original command could then generate the sitemap index, with these files.

I can't quite work out how to get this setup, so that each area finishes before the sitemap index is generated. I looked at queues, job or bus chain's. Although not 100% sure if this is the right way.

Thanks in advance.

0 likes
1 reply
LaryAI's avatar
Level 58

To achieve dynamic sitemaps for different areas of your CMS using the spatie/laravel-sitemap package, you can follow these steps:

  1. Create Individual Sitemap Generation Commands:

    Create separate Artisan commands for generating each type of sitemap (pages, posts, events, etc.). This will allow you to modularize the sitemap generation process.

    For example, create a command for generating the pages sitemap:

    php artisan make:command GeneratePagesSitemap
    

    In the handle method of this command, use the spatie/laravel-sitemap package to generate the sitemap:

    use Spatie\Sitemap\Sitemap;
    use Spatie\Sitemap\Tags\Url;
    
    public function handle()
    {
        Sitemap::create()
            ->add(Url::create('/page1'))
            ->add(Url::create('/page2'))
            // Add more pages dynamically
            ->writeToFile(public_path('sitemap-pages.xml'));
    }
    

    Repeat this process for posts, events, etc.

  2. Create a Command to Generate the Sitemap Index:

    Create another command to generate the sitemap index file, which will reference the individual sitemaps.

    php artisan make:command GenerateSitemapIndex
    

    In the handle method, generate the sitemap index:

    use Spatie\Sitemap\SitemapIndex;
    
    public function handle()
    {
        SitemapIndex::create()
            ->add('/sitemap-pages.xml')
            ->add('/sitemap-posts.xml')
            ->add('/sitemap-events.xml')
            // Add more sitemaps as needed
            ->writeToFile(public_path('sitemap.xml'));
    }
    
  3. Set Up a Scheduled Task:

    In your App\Console\Kernel.php, schedule the commands to run in sequence. This ensures that each sitemap is generated before the index is created.

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('sitemap:generate-pages')->dailyAt('00:00');
        $schedule->command('sitemap:generate-posts')->dailyAt('00:05');
        $schedule->command('sitemap:generate-events')->dailyAt('00:10');
        $schedule->command('sitemap:generate-index')->dailyAt('00:15');
    }
    

    Adjust the timing as necessary to ensure each command has enough time to complete before the next one starts.

  4. Consider Using Queues:

    If the sitemap generation process is resource-intensive, consider dispatching each command as a queued job. This can help manage server load and ensure that each task completes successfully.

    Modify each command to dispatch a job:

    use Illuminate\Support\Facades\Bus;
    
    public function handle()
    {
        Bus::chain([
            new GeneratePagesSitemapJob(),
            new GeneratePostsSitemapJob(),
            new GenerateEventsSitemapJob(),
            new GenerateSitemapIndexJob(),
        ])->dispatch();
    }
    

By following these steps, you can dynamically generate sitemaps for different areas of your CMS and ensure that the sitemap index is created only after all individual sitemaps are generated.

Please or to participate in this conversation.