in-square / pimcore-sitemap-bundle
Static XML sitemap generator for Pimcore (Documents + DataObjects).
Package info
github.com/in-square/pimcore-simple-sitemap-bundle
Type:pimcore-bundle
pkg:composer/in-square/pimcore-sitemap-bundle
Requires
- php: ^8.1
- elements/process-manager-bundle: ^5.0
- pimcore/pimcore: ^11.0
- symfony/console: ^6.4
- symfony/framework-bundle: ^6.4
- symfony/messenger: ^6.4
- symfony/routing: ^6.4
This package is not auto-updated.
Last update: 2026-07-28 11:06:35 UTC
README
Static XML sitemap generator for Pimcore (Documents + DataObjects) with multi-site and multi-locale support.
Requirements
- PHP 8.1+
- Pimcore 11 / Symfony 6.4
- Symfony Messenger (for queue processing)
- Elements Process Manager (commands integrate with Process Manager)
Installation
composer require in-square/pimcore-sitemap-bundle
Enable the bundle in config/bundles.php:
return [ InSquare\PimcoreSitemapBundle\InSquarePimcoreSitemapBundle::class => ['all' => true], ];
Configuration
Create config/packages/in_square_pimcore_sitemap.yaml:
in_square_pimcore_sitemap: sites: - id: 0 host: 'example.com' languages: ['pl'] objects: - 'Pimcore\Model\DataObject\Post' - 'Pimcore\Model\DataObject\PostCategory' - id: 1 host: 'example.org' languages: ['pl', 'en'] objects: - 'Pimcore\Model\DataObject\Product' object_generators: post: 'App\\Sitemap\\PostGenerator' postCategory: 'App\\Sitemap\\PostCategoryGenerator' product: 'App\\Sitemap\\ProductGenerator' output: dir: '%kernel.project_dir%/public/sitemap' max_urls_per_file: 50000 hreflang: enabled: true x_default_language: 'en' x_default_fallback_language: 'pl'
Notes:
sites[*].objectsdefines DataObject classes to collect for each site.object_generatorskeys must match the generator'sgetId(); keys are used in sitemap filenames.hreflang.enabledcontrols generation of<xhtml:link rel="alternate" ... />entries.hreflang.x_default_languageselects the preferred locale forx-default.hreflang.x_default_fallback_languageis used only when the preferred locale is missing.
Commands
bin/console insquare:sitemap:install– createsitemap_itemtable.bin/console insquare:sitemap:collect– dispatch sitemap messages to Messenger.bin/console insquare:sitemap:dump– generate XML files from database.bin/console insquare:sitemap:delete– delete XML files and truncate the table.
For an existing installation, run Doctrine migrations after updating the bundle:
bin/console doctrine:migrations:migrate
Run collect, wait until Messenger finishes processing the dispatched messages, and then run
dump. Collection uses a run token, so the dump can remove rows which were not seen during the
latest completed collection without truncating the table while workers are active.
Add routing for Messenger in config/packages/framework.yaml:
framework: messenger: routing: 'InSquare\PimcoreSitemapBundle\Message\SitemapItemCreateMessage': async
Run Messenger worker for the queue:
bin/console messenger:consume async
Controller
The bundle exposes /sitemap.xml. The controller selects the correct site and serves the
pre-generated file from public/sitemap/sitemap.{siteId}.xml. The site index links directly to
the locale/type URL sets, for example sitemap.0.pl.documents.xml.
Object generators
Implement InSquare\PimcoreSitemapBundle\Generator\ObjectGeneratorWithContextInterface in your
app to receive the normalized sitemap host:
<?php declare(strict_types=1); namespace App\Sitemap; use InSquare\PimcoreSitemapBundle\Generator\ObjectGeneratorWithContextInterface; use InSquare\PimcoreSitemapBundle\Generator\SitemapGeneratorContext; use InSquare\PimcoreSitemapBundle\Generator\SitemapItemData; use Pimcore\Model\DataObject\Post; final class PostGenerator implements ObjectGeneratorWithContextInterface { public function getId(): string { return 'post'; } public function getObjectClass(): string { return Post::class; } public function buildItem(object $object, SitemapGeneratorContext $context): ?SitemapItemData { if (!$object instanceof Post) { return null; } if (!$object->isPublished()) { return null; } $linkGenerator = $object->getClass()?->getLinkGenerator(); if ($linkGenerator === null) { return null; } $path = $linkGenerator->generate($object, [ 'locale' => $context->getLocale(), 'siteId' => $context->getSiteId(), ]); $url = $context->getHost() . '/' . ltrim((string) $path, '/'); $lastmod = (new \DateTimeImmutable())->setTimestamp($object->getModificationDate()); return new SitemapItemData( $object->getId(), $object::class, $url, $lastmod ); } }
The generator returns a SitemapItemData DTO used to persist rows in sitemap_item.
SitemapGeneratorContext::getHost() is normalized to an absolute host such as
https://example.com. The legacy ObjectGeneratorInterface remains available for backward
compatibility but is deprecated.