PrestaSitemapBundle

repository·4.x·Indexed 18 days ago

https://github.com/prestaconcept/prestasitemapbundle

A Symfony bundle for managing and generating XML sitemaps. It supports sitemapindex and urlset files, route-based configuration, and the ability to deliver sitemaps on-the-fly via a controller or as static files. Key features include support for hreflang translated routes, URL decoration for images and video, and a SitemapPopulateEvent for adding dynamic routes via event subscribers.

Tokens
15.3K
Snippets
53
Records
57
Agent score
63%

What's inside PrestaSitemapBundle

  1. Overview of PrestaSitemapBundle

    4.x

    PrestaSitemapBundle is a Symfony bundle designed to manage XML sitemaps. It supports the generation of a sitemapindex file that points to multiple urlset files, allowing you to scale beyond the standard limits.

    Key capabilities include:

    • Route-based configuration: Include specific routes in your sitemap via a single configuration option.
    • Scalability: Automatically complies with URL set specifications (up to 50,000 items or 10MB per file).
    • Flexible delivery: Access sitemaps on-the-fly via a Symfony controller or dump them to static files for improved performance.
    • Rich metadata: Supports decorating URLs with images, video, mobile, and multi-language information.
    • Lightweight: Requires no database to function.
  2. How URL decorators work in PrestaSitemapBundle

    4.x

    The Presta\SitemapBundle\Service\UrlContainerInterface::addUrl method accepts any object implementing the Presta\SitemapBundle\Sitemap\Url\Url interface. While the bundle automatically registers UrlConcrete instances for your configured static routes, you must manually register and use decorators to add advanced metadata (like images, video, or multilingual links).

    All decorators follow the Decorator Pattern, allowing you to nest them to add multiple layers of information to a single URL.

    Important: All URLs (routes, assets, etc.) must be absolute.

    <?php
    // Example of nesting decorators
    $url = new Sitemap\UrlConcrete($router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL));
    
    // Wrap with mobile decorator
    $url = new Sitemap\GoogleMobileUrlDecorator($url);
    
    // Wrap with image decorator
    $url = new Sitemap\GoogleImageUrlDecorator($url);
    $url->addImage(new Sitemap\GoogleImage('https://acme.com/image.png'));
    
    // Wrap with multilang decorator
    $url = new Sitemap\GoogleMultilangUrlDecorator($url);
    $url->addLink($router->generate('homepage_fr', [], UrlGeneratorInterface::ABSOLUTE_URL), 'fr');
    
    $urls->addUrl($url, 'default');
  3. Sitemap Formats Supported

    4.x

    The bundle generates standard XML sitemaps following the official specifications. It supports both sitemapindex files (to index multiple sitemaps) and urlset files (containing the actual URLs).

    ### Example sitemapindex
    ```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <sitemapindex 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/siteindex.xsd"
                  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        <sitemap>
            <loc>https://acme.org/sitemap.static.xml</loc>
            <lastmod>2020-01-01T10:00:00+02:00</lastmod>
        </sitemap>
    </sitemapindex>

    Example urlset

    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" 
            xmlns:xhtml="http://www.w3.org/1999/xhtml">
        <url>
            <loc>https://acme.org/</loc>
            <lastmod>2020-01-01T10:00:00+02:00</lastmod>
            <changefreq>daily</changefreq>
            <priority>0.5</priority>
        </url>
    </urlset>
  4. Enable PrestaSitemapBundle in Symfony or Legacy applications

    4.x

    After installing the package, you must register the bundle in your application kernel.

    For Symfony applications

    Add the bundle to your config/bundles.php file:

    For legacy applications

    Register the bundle within the registerBundles() method of your AppKernel class.

    // Symfony: config/bundles.php
    return [
        //...
        Presta\SitemapBundle\PrestaSitemapBundle::class => ['all' => true],
    ];
    
    // Legacy: app/AppKernel.php
    class AppKernel
    {
        public function registerBundles()
        {
            $bundles = [
                //...
                new Presta\SitemapBundle\PrestaSitemapBundle(),
            ];
    
            return $bundles;
        }
    }
  5. Configure application base URL for CLI usage

    4.x

    When using the Sitemap Dumper via CLI commands, you must set the base URL of your application so the Router can generate absolute URLs with the correct hostname. This is a standard Symfony configuration.

    # config/packages/routing.yaml
    framework:
        router:
            default_uri: 'https://your-domain.com'
  6. Register a Sitemap Event Subscriber in Symfony

    4.x

    If you are not using PSR-4 service discovery, you must manually register your event subscriber in your service configuration. Ensure you tag the service with kernel.event_subscriber so Symfony recognizes it.

    services:
        app.sitemap.blog_post_subscriber:
            class: App\EventListener\SitemapSubscriber
            arguments:
                - "@<your repository service id>"
            tags:
                - { name: "kernel.event_subscriber", priority: 100 }
  7. Dump sitemaps to static files

    4.x

    Instead of building sitemaps on demand via HTTP routes (which can be slow for large sites), you can "dump" them. This process generates XML files and saves them to a public directory so your web server can serve them directly.

    Important: To use this method, you must configure your Symfony router to be able to generate absolute URLs from the command line (see the bundle configuration guide).

    $ bin/console presta:sitemaps:dump
  8. Populate sitemaps with dynamic routes using Event Subscribers

    4.x

    To include dynamic content (like blog posts, products, or custom entities) in your sitemap, you can register a Symfony EventSubscriber or EventListener that listens to the SitemapPopulateEvent.

    When the event is dispatched, your subscriber receives a SitemapPopulateEvent object containing:

    1. getUrlContainer(): A UrlContainerInterface used to add URLs to the sitemap.
    2. getUrlGenerator(): A UrlGeneratorInterface (the Symfony router) to generate absolute URLs for your entities.

    To add a URL, use the addUrl() method on the container. This method requires:

    • A UrlConcrete object containing the generated absolute URL.
    • A string identifier (e.g., 'blog') to categorize the URL.

    Warning: When dealing with large datasets, avoid using Doctrine's findAll(). Instead, use iterators or array hydration to manage memory efficiently.

    ```php
    namespace App\EventListener;
    
    use App\\
  9. Dump a single sitemap section

    4.x

    To avoid regenerating the entire sitemap, you can use the --section option to regenerate only a specific part. This updates the corresponding section files and the main sitemap index while leaving other sections untouched.

    Requirement: When using this feature, you must wrap your custom URL registration logic in a condition that checks the current section being dumped. Otherwise, all URLs will be added to every section dump.

    <?php
    
    use Presta\
    SitemapBundle\\Event\\SitemapPopulateEvent;
    use Presta\\SitemapBundle\\Sitemap\\Url as Sitemap;
    use Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;
    
    /** @var SitemapPopulateEvent $event */
    /** @var UrlGeneratorInterface $urlGenerator */
    
    // Check if the current section being dumped matches your target section
    if (in_array($event->getSection(), [null, 'mysection'], true)) {
        $event->getUrlContainer()->addUrl(
            new Sitemap\\UrlConcrete($urlGenerator->generate('route_in_my_section', [], UrlGeneratorInterface::ABSOLUTE_URL)),
            'mysection'
        );
    }
  10. Import PrestaSitemapBundle routing

    4.x

    To enable the bundle's routing features, import the bundle's routing configuration in your application's routing setup.

    Note: If you only intend to use dumped sitemaps and do not need the bundle's dynamic routing features, importing this routing configuration may not be required.

    # config/routes/presta_sitemap.yaml
    presta_sitemap:
        resource: "@PrestaSitemapBundle/config/routing.php"
  11. Integrate PrestaSitemapBundle with Symfony Messenger

    4.x

    If you have Symfony Messenger installed, you can offload sitemap generation to an asynchronous process by dispatching the Presta\SitemapBundle\Messenger\DumpSitemapMessage to a Messenger transport. This prevents sitemap generation from blocking the main request/response cycle.

    To enable this, you must route the specific message class to your configured transport in your Messenger configuration.

    # config/packages/messenger.yaml
    framework:
        messenger:
            transports:
                async: "%env(MESSENGER_TRANSPORT_DSN)"
    
            routing:
                # 'async' is the name of the transport defined above
                'Presta\SitemapBundle\Messenger\DumpSitemapMessage':  async