How to Generate Sitemap in laravel ?

Posted by

I’m going to learn how to create a sitemap in this tutorial. I’ll explain how to create a dynamic sitemap using laravel 9 in this tutorial.

SitemapController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;
use Spatie\Sitemap\Tags\Tag;
use DOMDocument;
use Log;
class SitemapController extends Controller
{
    public function index()
    {
        return view('sitemap');
    }
  
    public function generateSitemapXML($url)
    {
        log::info("generateSitemapXML");
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">' . PHP_EOL;
    
        // Add the homepage URL
        $homepageUrl = $url;
        $homepageTotalImages = $this->getTotalImages($homepageUrl);
        $homepageLastModification = $this->getLastModificationDate($homepageUrl);
    
        $xml .= '<url>' . PHP_EOL;
        $xml .= '<loc>' . $homepageUrl . '</loc>' . PHP_EOL;
        $xml .= '<changefreq>daily</changefreq>' . PHP_EOL;
        $xml .= '<priority>1.0</priority>' . PHP_EOL;
    
        for ($i = 1; $i <= $homepageTotalImages; $i++) {
            $xml .= '<image:image>' . PHP_EOL;
            $xml .= '<image:loc>' . $homepageUrl . '/image' . $i . '.jpg</image:loc>' . PHP_EOL;
            $xml .= '<image:title>Image ' . $i . '</image:title>' . PHP_EOL;
            $xml .= '</image:image>' . PHP_EOL;
        }
    
        $xml .= '<lastmod>' . $homepageLastModification . '</lastmod>' . PHP_EOL;
        $xml .= '</url>' . PHP_EOL;
    
        // Fetch all available pages from the website
        $pageUrls = $this->getWebsitePages($url);
    
        // Add other pages to the sitemap
        foreach ($pageUrls as $pageUrl) {
            $pageTotalImages = $this->getTotalImages($pageUrl);

            $pageLastModification = $this->getLastModificationDate($pageUrl);
    
            $xml .= '<url>' . PHP_EOL;
            $xml .= '<loc>' . $pageUrl . '</loc>' . PHP_EOL;
            $xml .= '<changefreq>weekly</changefreq>' . PHP_EOL;
            $xml .= '<priority>0.8</priority>' . PHP_EOL;
    
            for ($i = 1; $i <= $pageTotalImages; $i++) {
                $xml .= '<image:image>' . PHP_EOL;
                $xml .= '<image:loc>' . $pageUrl . '/image' . $i . '.jpg</image:loc>' . PHP_EOL;
                $xml .= '<image:title>Image ' . $i . '</image:title>' . PHP_EOL;
                $xml .= '</image:image>' . PHP_EOL;
            }

            $xml .= '<lastmod>' . $pageLastModification . '</lastmod>' . PHP_EOL;
            $xml .= '</url>' . PHP_EOL;
        }
    
        $xml .= '</urlset>' . PHP_EOL;
        log::info("xmlSSS");
        log::info($xml);
        return $xml;
    }


    public function getTotalImages($url)
{
    // Example array representing website pages and their total images
    $pagesWithTotalImages = [];

    // Check if the URL exists in the array, and return the total images if found
    if (array_key_exists($url, $pagesWithTotalImages)) {
        return $pagesWithTotalImages[$url];
    } else {
        // Return a default value (e.g., 0) if the URL is not found
        return 0;
    }
}

public function getLastModificationDate($url)
{
    // Example array representing website pages and their last modification dates
    $pagesWithLastModificationDates = [];

    // Check if the URL exists in the array, and return the last modification date if found
    if (array_key_exists($url, $pagesWithLastModificationDates)) {
        return $pagesWithLastModificationDates[$url];
    } else {
        // Return a default value (e.g., a current date) if the URL is not found
        return date('Y-m-d'); // Current date as a default value
    }
}

    
    
    public function getWebsitePages($url)
    {
    $pageUrls = [];
    $response = Http::get($url);
    if ($response->successful()) {
    // Create a DOMDocument object to parse the HTML
    $dom = new DOMDocument();
    libxml_use_internal_errors(true); // Suppress any HTML parsing errors
    $dom->loadHTML($response->body());
    libxml_use_internal_errors(false);
    // Find all anchor (a) tags in the HTML
    $anchors = $dom->getElementsByTagName('a');
    foreach ($anchors as $anchor) {
    $href = $anchor->getAttribute('href');
    // Check if the href attribute contains a valid URL and is not empty
    if (filter_var($href, FILTER_VALIDATE_URL) && !empty($href)) {
    $pageUrls[] = $href;
    }
    }
    }
    return $pageUrls;
    }
    public function generateSitemap(Request $request)
    {
    $websiteUrl = $request->url;
    // Generate the sitemap XML
    $sitemapXml = $this->generateSitemapXML($websiteUrl);
    return view('table', ['sitemapXml' => $sitemapXml, 'websiteUrl' => $websiteUrl]);
     }
     public function downloadSitemap(Request $request)
  {
    $websiteUrl = $request->url;
     // Generate the sitemap XML
    $sitemapXml = $this->generateSitemapXML($websiteUrl);
    // Set the appropriate headers for download
    return response($sitemapXml)
        ->header('Content-Type', 'application/xml')
        ->header('Content-Disposition', 'attachment; filename="sitemap.xml"');
}
}
    

This is sitemap.blade.php

    <div class="container-wrapper">
        <div class="containers">
            <h1>Sitemap Generator</h1>
            @if (session('success'))
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
            @endif   
            @if (session('error'))
            <div class="alert alert-danger">
                {{ session('error') }}
            </div>
            @endif
            <form method="POST" action="{{ route('sitemap.generate') }}">
                @csrf
                <input type="text" name="url" placeholder="Enter Website URL">
                <button type="submit">Generate Sitemap</button>
            </form>
        </div>
    </div>

And this table.blade.php

 <h1>Sitemap of "{{ $websiteUrl }}" </h1>
    <table>
        <thead>
            <tr>
                <th>URL</th>
                <th>Last Modification</th>
                <!-- <th>Priority</th> -->
            </tr>
        </thead>
        <tbody>
            <?php
            // Parse the sitemap XML
            $xml = simplexml_load_string($sitemapXml);
            foreach ($xml->url as $url) {
                $loc = $url->loc;
                $changefreq = $url->image;
                $priority = $url->priority;
                $lastmod = $url->lastmod;
            ?>
            <tr>
                <td><a href="{{ $loc }}">{{ $loc }}</td>
                <td>{{ $lastmod }}</td> 
                <!-- <td>{{ $changefreq }}</td> -->
            </tr>
            <?php } ?>
        </tbody>
    </table>
    <div class="center-btn-container">
        <a id="download-sitemap-btn" href="{{ route('download', ['url' => '']) }}" class="btn btn-primary">Download
            Sitemap</a>
    </div>
    <!-- <a id="download-sitemap-btn" href="{{ route('download', ['url' => '']) }}" class="btn btn-primary">Download Sitemap</a> -->
    <script>
    // Get the current URL
    var currentUrl = "{{ $websiteUrl }}";

    // Update the href attribute of the Download Sitemap button
    var downloadUrl = "{{ route('download', ['url' => '']) }}"; // The route with a placeholder for the URL parameter
    var updatedDownloadUrl = downloadUrl.replace('url=', 'url=' + encodeURIComponent(currentUrl));
    document.getElementById("download-sitemap-btn").setAttribute("href", updatedDownloadUrl);
    </script>

web.php

Route::get('/', [SitemapController::class, 'index'])->name('sitemap.index');
Route::post('/generate', [SitemapController::class, 'generateSitemap'])->name('sitemap.generate');
Route::get('/download-sitemap', [SitemapController::class, 'downloadSitemap'])->name('download');

after this run this command

php artisan serve

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x