### Install and Configure Bundle Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Commands and configuration to register the bundle in a Symfony application. ```bash composer require presta/sitemap-bundle ``` ```php ['all' => true], ]; ``` ```yaml # config/routes/presta_sitemap.yaml presta_sitemap: resource: "@PrestaSitemapBundle/config/routing.php" ``` -------------------------------- ### Install PrestaSitemapBundle via Composer Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/1-installation.md Use composer to add the bundle as a project dependency. ```bash composer require presta/sitemap-bundle ``` -------------------------------- ### Dispatch Sitemap Refresh Jobs (All Locales) Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Dispatch multiple `DumpSitemapMessage` jobs for different locales to generate sitemaps for each language. This example iterates through a map of locales and domains. ```php 'acme.com', 'fr' => 'acme.fr', 'de' => 'acme.de']; foreach ($locales as $locale => $domain) { $bus->dispatch(new DumpSitemapMessage( null, "https://{$domain}/", "/var/www/acme/public/sitemaps/{$locale}/", ['gzip' => true] )); } return $this->json(['status' => 'All locale sitemaps queued for refresh']); } } ``` -------------------------------- ### Configure Bundle Defaults Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Global settings for sitemap generation, including cache, file limits, and multilingual support. ```yaml # config/packages/presta_sitemap.yaml presta_sitemap: # Default values for URLs defaults: priority: 0.5 changefreq: daily lastmod: now # Section name for static routes default_section: default # Cache time-to-live in seconds timetolive: 3600 # Maximum URLs per sitemap file (max 50000) items_by_set: 50000 # Directory for dumped sitemaps dump_directory: '%kernel.project_dir%/public' # Sitemap filename prefix sitemap_file_prefix: sitemap # Enable/disable route annotation listener route_annotation_listener: true # Multilingual alternate URLs configuration alternate: enabled: true default_locale: 'en' locales: ['en', 'fr', 'de'] i18n: symfony # or 'jms' for JMSI18nRoutingBundle ``` -------------------------------- ### Define Static Routes with YAML Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Configure sitemap options within YAML routing files. ```yaml # config/routes.yaml homepage: path: / controller: App\Controller\DefaultController::index options: sitemap: true faq: path: /faq controller: App\Controller\DefaultController::faq options: sitemap: priority: 0.7 about: path: /about controller: App\Controller\DefaultController::about options: sitemap: priority: 0.7 changefreq: weekly contact: path: /contact controller: App\Controller\DefaultController::contact options: sitemap: priority: 0.7 changefreq: weekly section: misc # Localized routes (works with alternate configuration) blog_index: path: en: /blog fr: /blogue de: /blog controller: App\Controller\BlogController::index options: sitemap: priority: 0.8 ``` -------------------------------- ### Create Basic Sitemap URL Entries Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Instantiate the UrlConcrete class to define sitemap entries. You can provide all parameters or use fluent setters for modification. ```php setLastmod(new \DateTime()) ->setChangefreq(UrlConcrete::CHANGEFREQ_DAILY) ->setPriority(0.5); // Generated XML output: // // https://acme.com/article/my-post // 2024-01-15T10:30:00+00:00 // weekly // 0.8 // ``` -------------------------------- ### Import Routing Configuration Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/1-installation.md Configure the bundle routing. This step is optional if you only intend to use dumped sitemaps. ```yaml # config/routes/presta_sitemap.yaml presta_sitemap: resource: "@PrestaSitemapBundle/config/routing.php" ``` -------------------------------- ### Configure Static Routes with XML Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/3-static-routes-usage.md Specify sitemap configuration for static routes using XML. The 'sitemap' option within the route definition allows setting parameters like priority, change frequency, and section. ```xml App\Controller\DefaultController::index App\Controller\DefaultController::faq App\Controller\DefaultController::about App\Controller\DefaultController::contact ``` -------------------------------- ### Nest Multiple URL Decorators Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/5-decorating-urls.md Demonstrates chaining multiple decorators (mobile, images, multilang, and video) on a single URL instance. ```php generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL)); // 1st wrap: mobile $url = new Sitemap\\GoogleMobileUrlDecorator($url); // 2nd wrap: images $url = new Sitemap\\GoogleImageUrlDecorator($url); $url->addImage(new Sitemap\\GoogleImage('https://acme.com/assets/carousel/php.gif')); $url->addImage(new Sitemap\\GoogleImage('https://acme.com/assets/carousel/symfony.jpg')); $url->addImage(new Sitemap\\GoogleImage('https://acme.com/assets/carousel/love.png')); // 3rd wrap: multilang $url = new Sitemap\\GoogleMultilangUrlDecorator($url); $url->addLink($router->generate('homepage_fr', [], UrlGeneratorInterface::ABSOLUTE_URL), 'fr'); $url->addLink($router->generate('homepage_de', [], UrlGeneratorInterface::ABSOLUTE_URL), 'de'); // 4th wrap: video $video = new Sitemap\\GoogleVideo( 'https://img.youtube.com/vi/j6IKRxH8PTg/0.jpg', 'How to use PrestaSitemapBundle in Symfony 2.6 [1/2]', 'In this video you will learn how to use PrestaSitemapBundle in your Symfony 2.6 projects', ['content_loc' => 'https://www.youtube.com/watch?v=j6IKRxH8PTg'] ); $video->addTag('php') ->addTag('symfony') ->addTag('sitemap'); $url = new Sitemap\\GoogleVideoUrlDecorator($url); $url->addVideo($video); $urls->addUrl($url, 'default'); ``` -------------------------------- ### Configure Static Routes with Annotations Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/3-static-routes-usage.md Utilize route annotations to specify sitemap parameters such as priority, change frequency, and section. Setting 'sitemap' to true enables sitemap generation for the route. ```php true])] public function indexAction() { //... } #[Route('/faq', name: 'faq', options: ['sitemap' => ['priority' => 0.7]])] public function faqAction() { //... } #[Route('/about', name: 'about', options: ['sitemap' => ['priority' => 0.7, 'changefreq' => UrlConcrete::CHANGEFREQ_WEEKLY]])] public function aboutAction() { //... } #[Route('/contact', name: 'contact', options: ['sitemap' => ['priority' => 0.7, 'changefreq' => UrlConcrete::CHANGEFREQ_WEEKLY, 'section' => 'misc']])] public function contactAction() { //... } } ``` -------------------------------- ### Dump Sitemaps via CLI Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Executes console commands to generate static sitemap files with options for custom directories, specific sections, base URL overrides, and gzip compression. ```bash # Dump all sitemaps to default public directory bin/console presta:sitemaps:dump # Output: # Dumping all sections of sitemaps into public directory # Created/Updated the following sitemap files: # sitemap.default.xml # sitemap.blog.xml # sitemap.products.xml # sitemap.xml # Dump to custom directory bin/console presta:sitemaps:dump var/sitemaps/ # Dump specific section only bin/console presta:sitemaps:dump --section=blog # Force base URL (useful for multi-domain setups) bin/console presta:sitemaps:dump public/sitemap/es/ --base-url=https://es.acme.com/ # Enable gzip compression bin/console presta:sitemaps:dump --gzip # Output with compression: # Created/Updated the following sitemap files: # sitemap.default.xml.gz # sitemap.blog.xml.gz # sitemap.xml # Combine options bin/console presta:sitemaps:dump public/sitemaps/ --base-url=https://acme.com/ --section=products --gzip ``` -------------------------------- ### Configure Static Routes with YAML Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/3-static-routes-usage.md Define sitemap options within the 'options' section of your route configuration in YAML. This includes setting priority, change frequency, and section for sitemap entries. ```yaml homepage: path: / defaults: { _controller: App\Controller\DefaultController::index } options: sitemap: true faq: path: /faq defaults: { _controller: App\Controller\DefaultController::faq } options: sitemap: priority: 0.7 about: path: /about defaults: { _controller: App\Controller\DefaultController::about } options: sitemap: priority: 0.7 changefreq: weekly contact: path: /contact defaults: { _controller: App\Controller\DefaultController::contact } options: sitemap: priority: 0.7 changefreq: weekly section: misc ``` -------------------------------- ### Dump sitemap with gzip compression Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/6-dumping-sitemap.md Enables gzip compression for the generated sitemap files. ```bash $ bin/console presta:sitemaps:dump --gzip Dumping all sections of sitemaps into public directory Created/Updated the following sitemap files: sitemap.default.xml.gz sitemap.image.xml.gz [...] sitemap.xml ``` -------------------------------- ### Register Dynamic Blog Posts in Sitemap Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Implement an event subscriber to populate the sitemap with dynamic blog post URLs. Ensure to check the event section to avoid unnecessary processing. ```php 'populate', ]; } public function populate(SitemapPopulateEvent $event): void { // Check section for partial dumps if (!in_array($event->getSection(), [null, 'blog'], true)) { return; } $this->registerBlogPosts( $event->getUrlContainer(), $event->getUrlGenerator() ); } private function registerBlogPosts( UrlContainerInterface $urls, UrlGeneratorInterface $router ): void { // For large datasets, use Doctrine's iterate() or batch processing $posts = $this->blogPostRepository->findPublished(); foreach ($posts as $post) { $urls->addUrl( new UrlConcrete( $router->generate( 'blog_show', ['slug' => $post->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL ), $post->getUpdatedAt(), UrlConcrete::CHANGEFREQ_WEEKLY, 0.8 ), 'blog' ); } } } ``` -------------------------------- ### Configure dump directory Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/6-dumping-sitemap.md Sets a custom directory for sitemap files in the bundle configuration. ```yaml # config/packages/presta_sitemap.yaml presta_sitemap: dump_directory: some/dir ``` -------------------------------- ### Implement SitemapSubscriber Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/4-dynamic-routes-usage.md Create an event subscriber that listens for SitemapPopulateEvent to inject custom URLs into the sitemap. Avoid using findAll() on large datasets to prevent memory issues. ```php blogPostRepository = $blogPostRepository; } /** * @inheritdoc */ public static function getSubscribedEvents() { return [ SitemapPopulateEvent::class => 'populate', ]; } /** * @param SitemapPopulateEvent $event */ public function populate(SitemapPopulateEvent $event): void { $this->registerBlogPostsUrls($event->getUrlContainer(), $event->getUrlGenerator()); } /** * @param UrlContainerInterface $urls * @param UrlGeneratorInterface $router */ public function registerBlogPostsUrls(UrlContainerInterface $urls, UrlGeneratorInterface $router): void { $posts = $this->blogPostRepository->findAll(); foreach ($posts as $post) { $urls->addUrl( new UrlConcrete( $router->generate( 'blog_post', ['slug' => $post->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL ) ), 'blog' ); } } } ``` -------------------------------- ### Dump sitemaps command Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/6-dumping-sitemap.md Executes the command to generate sitemap files in the public directory. ```bash $ bin/console presta:sitemaps:dump Dumping all sections of sitemaps into public directory Created the following sitemap files main.xml main_0.xml sitemap.xml ``` -------------------------------- ### Define Static Routes with PHP Attributes Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Configure sitemap options directly in controller methods using PHP 8 attributes. ```php true])] public function index(): Response { return $this->render('default/index.html.twig'); } // Custom priority #[Route('/faq', name: 'faq', options: ['sitemap' => ['priority' => 0.7]])] public function faq(): Response { return $this->render('default/faq.html.twig'); } // Priority and change frequency #[Route('/about', name: 'about', options: ['sitemap' => [ 'priority' => 0.7, 'changefreq' => UrlConcrete::CHANGEFREQ_WEEKLY ]])] public function about(): Response { return $this->render('default/about.html.twig'); } // Full configuration with custom section #[Route('/contact', name: 'contact', options: ['sitemap' => [ 'priority' => 0.7, 'changefreq' => UrlConcrete::CHANGEFREQ_WEEKLY, 'section' => 'misc', 'lastmod' => '2024-01-01' ]])] public function contact(): Response { return $this->render('default/contact.html.twig'); } } ``` -------------------------------- ### Configure URL as Mobile Resource Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/5-decorating-urls.md Use GoogleMobileUrlDecorator to mark a URL as a mobile-friendly resource. Ensure the URL is absolute. ```php generate('mobile_homepage', [], UrlGeneratorInterface::ABSOLUTE_URL)); $decoratedUrl = new Sitemap\GoogleMobileUrlDecorator($url); $urls->addUrl($decoratedUrl, 'default'); ``` ```xml https://m.acme.com/ ``` -------------------------------- ### Define a sitemapindex XML structure Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/README.md Represents the root index file for multiple sitemaps. ```xml https://acme.org/sitemap.static.xml 2020-01-01T10:00:00+02:00 ``` -------------------------------- ### Implement a Complete Sitemap Event Listener Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Use this listener to register dynamic content types into the sitemap. It supports section filtering and advanced URL decorators for images and multilingual content. ```php 'onSitemapPopulate', ]; } public function onSitemapPopulate(SitemapPopulateEvent $event): void { $section = $event->getSection(); $urls = $event->getUrlContainer(); $router = $event->getUrlGenerator(); // Register products if section matches or is null (all sections) if (in_array($section, [null, 'products'], true)) { $this->addProducts($urls, $router); } // Register categories if (in_array($section, [null, 'categories'], true)) { $this->addCategories($urls, $router); } // Register blog articles if (in_array($section, [null, 'blog'], true)) { $this->addArticles($urls, $router); } } private function addProducts(UrlContainerInterface $urls, UrlGeneratorInterface $router): void { foreach ($this->products->findActive() as $product) { $url = new Sitemap\\UrlConcrete( $router->generate('product_show', ['slug' => $product->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL), $product->getUpdatedAt(), Sitemap\\UrlConcrete::CHANGEFREQ_WEEKLY, 0.8 ); // Add product images if ($product->getImages()->count() > 0) { $url = new Sitemap\\GoogleImageUrlDecorator($url); foreach ($product->getImages() as $image) { $url->addImage(new Sitemap\\GoogleImage( $router->generate('product_image', ['id' => $image->getId()], UrlGeneratorInterface::ABSOLUTE_URL), $image->getAlt(), null, $product->getName() . ' - ' . $image->getPosition() )); } } $urls->addUrl($url, 'products'); } } private function addCategories(UrlContainerInterface $urls, UrlGeneratorInterface $router): void { foreach ($this->categories->findAll() as $category) { $urls->addUrl( new Sitemap\\UrlConcrete( $router->generate('category_show', ['slug' => $category->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL), $category->getUpdatedAt(), Sitemap\\UrlConcrete::CHANGEFREQ_DAILY, 0.7 ), 'categories' ); } } private function addArticles(UrlContainerInterface $urls, UrlGeneratorInterface $router): void { foreach ($this->articles->findPublished() as $article) { $url = new Sitemap\\UrlConcrete( $router->generate('article_show', ['slug' => $article->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL), $article->getPublishedAt(), Sitemap\\UrlConcrete::CHANGEFREQ_MONTHLY, 0.6 ); // Add multilingual versions if ($article->getTranslations()->count() > 0) { $url = new Sitemap\\GoogleMultilangUrlDecorator($url); foreach ($article->getTranslations() as $locale => $translation) { $url->addLink( $router->generate('article_show', ['slug' => $translation->getSlug(), '_locale' => $locale], UrlGeneratorInterface::ABSOLUTE_URL), $locale ); } } $urls->addUrl($url, 'blog'); } } } ``` -------------------------------- ### Register URLs for a specific section Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/6-dumping-sitemap.md Wraps URL registration logic to ensure only the requested section is processed during a dump. ```php getSection(), [null, 'mysection'], true)) { $event->getUrlContainer()->addUrl( new Sitemap\UrlConcrete($urlGenerator->generate('route_in_my_section', [], UrlGeneratorInterface::ABSOLUTE_URL)), 'mysection' ); } ``` -------------------------------- ### Dispatch Sitemap Refresh Job (All Sections) Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Dispatch a `DumpSitemapMessage` to queue the generation of all sitemap sections. This is useful for a full sitemap refresh. ```php dispatch(new DumpSitemapMessage()); return $this->json(['status' => 'Sitemap refresh queued']); } // ... other methods ``` -------------------------------- ### Dump sitemap with custom base URL Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/6-dumping-sitemap.md Overrides the routing host when generating sitemaps for specific domains. ```bash $ bin/console presta:sitemaps:dump public/sitemap/es/ --base-url=http://es.mysite.com/ Dumping all sections of sitemaps into public/sitemap/es/ directory Created the following sitemap files main.xml main_0.xml sitemap.xml ``` -------------------------------- ### Configure Messenger Transport and Routing Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Configure the messenger transport and routing in `config/packages/messenger.yaml` to enable asynchronous sitemap generation. Ensure the `MESSENGER_TRANSPORT_DSN` environment variable is set. ```yaml framework: messenger: transports: async: '%env(MESSENGER_TRANSPORT_DSN)%' routing: 'Presta\SitemapBundle\Messenger\DumpSitemapMessage': async ``` -------------------------------- ### Add Google Video to Sitemap Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/5-decorating-urls.md Uses the GoogleVideoUrlDecorator to attach video metadata to a URL. The XML output shows the required video tag structure. ```php generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL)); $video = new Sitemap\\GoogleVideo( 'https://img.youtube.com/vi/j6IKRxH8PTg/0.jpg', 'How to use PrestaSitemapBundle in Symfony 2.6 [1/2]', 'In this video you will learn how to use PrestaSitemapBundle in your Symfony 2.6 projects', ['content_loc' => 'https://www.youtube.com/watch?v=j6IKRxH8PTg'] ); $video->addTag('php') ->addTag('symfony') ->addTag('sitemap'); $decoratedUrl = new Sitemap\\GoogleVideoUrlDecorator($url); $decoratedUrl->addVideo($video); $urls->addUrl($decoratedUrl, 'default'); ``` ```xml https://acme.com/ https://img.youtube.com/vi/j6IKRxH8PTg/0.jpg https://www.youtube.com/watch?v=j6IKRxH8PTg php symfony sitemap ``` -------------------------------- ### Add Images to Sitemap URL Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/5-decorating-urls.md Use GoogleImageUrlDecorator to associate multiple images with a sitemap URL. Ensure all URLs are absolute. ```php generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL)); $decoratedUrl = new Sitemap\GoogleImageUrlDecorator($url); $decoratedUrl->addImage(new Sitemap\GoogleImage('https://acme.com/assets/carousel/php.gif')); $decoratedUrl->addImage(new Sitemap\GoogleImage('https://acme.com/assets/carousel/symfony.jpg')); $decoratedUrl->addImage(new Sitemap\GoogleImage('https://acme.com/assets/carousel/love.png')); $urls->addUrl($decoratedUrl, 'default'); ``` ```xml https://acme.com/ https://acme.com/assets/carousel/php.gif https://acme.com/assets/carousel/symfony.jpg https://acme.com/assets/carousel/love.png ``` -------------------------------- ### Register Bundle in Symfony Kernel Source: https://github.com/prestaconcept/prestasitemapbundle/blob/4.x/doc/1-installation.md Enable the bundle in the application kernel. Choose the appropriate format based on your Symfony version. ```php ['all' => true], ]; ``` ```php generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL)); $decoratedUrl = new Sitemap\GoogleMultilangUrlDecorator($url); $decoratedUrl->addLink($router->generate('homepage_fr', [], UrlGeneratorInterface::ABSOLUTE_URL), 'fr'); $decoratedUrl->addLink($router->generate('homepage_de', [], UrlGeneratorInterface::ABSOLUTE_URL), 'de'); $urls->addUrl($decoratedUrl, 'default'); ``` ```xml https://acme.com/ ``` -------------------------------- ### Nest Multiple URL Decorators in PHP Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Wraps a base URL object with multiple decorators to add mobile, image, multilingual, and video metadata. Ensure the final decorated object is added to the UrlContainerInterface. ```php generate('product_show', ['id' => 100], UrlGeneratorInterface::ABSOLUTE_URL), new \DateTime(), Sitemap\UrlConcrete::CHANGEFREQ_WEEKLY, 0.9 ); // 1st wrap: Mobile designation $url = new Sitemap\GoogleMobileUrlDecorator($url); // 2nd wrap: Add images $url = new Sitemap\GoogleImageUrlDecorator($url); $url->addImage(new Sitemap\GoogleImage('https://acme.com/products/100/main.jpg')); $url->addImage(new Sitemap\GoogleImage('https://acme.com/products/100/gallery-1.jpg')); $url->addImage(new Sitemap\GoogleImage('https://acme.com/products/100/gallery-2.jpg')); // 3rd wrap: Add multilingual alternates $url = new Sitemap\GoogleMultilangUrlDecorator($url); $url->addLink($router->generate('product_show', ['id' => 100, '_locale' => 'fr'], UrlGeneratorInterface::ABSOLUTE_URL), 'fr'); $url->addLink($router->generate('product_show', ['id' => 100, '_locale' => 'de'], UrlGeneratorInterface::ABSOLUTE_URL), 'de'); // 4th wrap: Add product video $video = new Sitemap\GoogleVideo( 'https://acme.com/products/100/video-thumb.jpg', 'Product 100 Demo', 'Watch our product demonstration video', ['content_loc' => 'https://acme.com/videos/product-100-demo.mp4'] ); $video->addTag('product')->addTag('demo'); $url = new Sitemap\GoogleVideoUrlDecorator($url); $url->addVideo($video); // Register the fully decorated URL $urls->addUrl($url, 'products'); ``` -------------------------------- ### Dispatch Sitemap Refresh Job (Specific Section) Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Dispatch a `DumpSitemapMessage` to queue the generation of a specific sitemap section with custom options. This allows for targeted updates. ```php dispatch(new DumpSitemapMessage( $section, // Section name 'https://acme.com', // Base URL '/var/www/acme/public/sitemaps', // Target directory ['gzip' => true] // Options )); return $this->json(['status' => "Section '$section' refresh queued"]); } // ... other methods ``` -------------------------------- ### Decorate URLs with Google Video metadata Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Use GoogleVideoUrlDecorator to add comprehensive video metadata, including tags, pricing, and platform restrictions. ```php generate('video_watch', ['id' => 456], UrlGeneratorInterface::ABSOLUTE_URL) ); // Create video with required parameters and options $video = new GoogleVideo( 'https://acme.com/thumbnails/video-456.jpg', // Thumbnail (required) 'How to Use Our Product', // Title (required) 'Complete tutorial showing all features', // Description (required) [ // Must have either content_loc or player_loc 'content_loc' => 'https://acme.com/videos/tutorial.mp4', 'player_loc' => 'https://acme.com/embed/456', 'player_location_allow_embed' => GoogleVideo::PLAYER_LOC_ALLOW_EMBED_YES, 'duration' => 360, // Seconds (0-28800) 'expiration_date' => new \DateTime('+1 year'), 'rating' => 4.5, // 0.0 to 5.0 'view_count' => 15000, 'publication_date' => new \DateTime('2024-01-01'), 'family_friendly' => GoogleVideo::FAMILY_FRIENDLY_YES, 'category' => 'Tutorial', // Max 256 chars 'restriction_allow' => ['US', 'CA', 'GB'], 'requires_subscription' => GoogleVideo::REQUIRES_SUBSCRIPTION_NO, 'uploader' => 'Acme Corp', 'uploader_info' => 'https://acme.com/channel', 'live' => GoogleVideo::LIVE_NO, 'platforms' => [GoogleVideo::PLATFORM_WEB, GoogleVideo::PLATFORM_MOBILE], 'platform_relationship' => GoogleVideo::PLATFORM_RELATIONSHIP_ALLOW, ] ); // Add tags (max 32) $video->addTag('tutorial') ->addTag('product') ->addTag('howto'); // Add pricing $video->addPrice( 9.99, // Amount 'USD', // Currency (ISO 4217) GoogleVideo::PRICE_TYPE_OWN, // Type: rent or own GoogleVideo::PRICE_RESOLUTION_HD // Resolution: HD or SD ); // Wrap URL with video decorator $decoratedUrl = new GoogleVideoUrlDecorator($url); $decoratedUrl->addVideo($video); $urls->addUrl($decoratedUrl, 'videos'); ``` -------------------------------- ### Decorate URLs with Google Image metadata Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Use GoogleImageUrlDecorator to attach image information to a URL. Supports up to 1000 images per URL. ```php generate('product_show', ['id' => 123], UrlGeneratorInterface::ABSOLUTE_URL) ); // Wrap with image decorator $decoratedUrl = new GoogleImageUrlDecorator($url); // Add images with all optional parameters $decoratedUrl->addImage(new GoogleImage( 'https://acme.com/images/product-front.jpg', // Location (required) 'Front view of the product', // Caption (optional) 'New York, USA', // Geo location (optional) 'Premium Widget - Front View', // Title (optional) 'https://acme.com/license' // License URL (optional) )); // Add more images (simpler) $decoratedUrl->addImage(new GoogleImage('https://acme.com/images/product-side.jpg')); $decoratedUrl->addImage(new GoogleImage('https://acme.com/images/product-back.jpg')); // Register URL $urls->addUrl($decoratedUrl, 'products'); // Generated XML output: // // https://acme.com/product/123 // // https://acme.com/images/product-front.jpg // // // // // // // https://acme.com/images/product-side.jpg // // ``` -------------------------------- ### Add Multilingual hreflang URLs Source: https://context7.com/prestaconcept/prestasitemapbundle/llms.txt Use GoogleMultilangUrlDecorator to associate alternate language versions and an x-default URL with a primary sitemap entry. ```php generate('product_show', ['_locale' => 'en', 'slug' => 'widget'], UrlGeneratorInterface::ABSOLUTE_URL) ); // Wrap with multilang decorator $decoratedUrl = new GoogleMultilangUrlDecorator($url); // Add alternate language URLs $decoratedUrl->addLink( $router->generate('product_show', ['_locale' => 'fr', 'slug' => 'widget'], UrlGeneratorInterface::ABSOLUTE_URL), 'fr' ); $decoratedUrl->addLink( $router->generate('product_show', ['_locale' => 'de', 'slug' => 'widget'], UrlGeneratorInterface::ABSOLUTE_URL), 'de' ); $decoratedUrl->addLink( $router->generate('product_show', ['_locale' => 'es', 'slug' => 'widget'], UrlGeneratorInterface::ABSOLUTE_URL), 'es' ); // Add x-default for language/region selector page $decoratedUrl->addLink( $router->generate('product_show', ['slug' => 'widget'], UrlGeneratorInterface::ABSOLUTE_URL), 'x-default' ); $urls->addUrl($decoratedUrl, 'products'); // Generated XML output: // // https://acme.com/en/product/widget // // // // // ```