Sitemap ======= The ``SonataSeoBundle`` provides a support for static sitemap generation. You can either create services or provide raw SQL queries. Service Definition ------------------ The service must implement the ``SourceIteratorInterface`` from the ``sonata-project/exporter`` library. The iterator will be used to generate the file. The iterator must not store all data as property to avoid memory issue. Data must be fetch one by one using a buffered connection (from mysql and not php which is not default behavior):: class MyCustomSitemapIterator implements SourceIteratorInterface { protected $key; protected $stop; protected $current; public function __construct($stop = 1000) { $this->stop = $stop; } public function current() { return $this->current; } public function next() { $this->key++; $this->current = [ 'url' => '/the/path/to/target', 'lastmod' => '01.01.2020', 'changefreq' => 'weekly', 'priority' => 0.5 ]; } public function key() { return $this->key; } public function valid() { return $this->key < $this->stop; } public function rewind() { $this->key = 0; } } Raw Performance with Query -------------------------- You will need to configure: - a Doctrine connection - a route - default parameters used by the route - the query which must contains all information required by a sitemap: lastmod, changefreq and priority The url is generated by using ``route`` and ``parameters`` settings. For performance reasons and memory usage there is no model hydrated while generating the sitemap. So if the sitemap requires specific rules, they must be expressed in the ``WHERE`` condition. The query must select fields to be used in the route. The following code is an extract of the query required to generate a valid sitemap for the ``SonataNewsBundle`` .. code-block:: sql SELECT CONCAT_WS('/', YEAR(created_at), MONTH(created_at), DAY(created_at), slug) as url , DATETIME(updated_at) as lastmod, 'weekly' as changefreq, '0.5' as priority FROM news__post WHERE enabled = 1 AND (publication_date_start IS NULL OR publication_date_start <= NOW()) Please note: the ``changefreq`` and the ``priority`` fields are optional. Configuration example --------------------- Sitemap configuration obviously depends on the bundle, page types & custom routes you choose to expose. .. code-block:: yaml service: app.my_custom_sitemap_service: class: MyCustomSitemapIterator sonata_seo: # ... sitemap: services: - app.my_custom_sitemap_service doctrine_orm: # media - types: [image] connection: doctrine.dbal.default_connection route: sonata_media_view parameters: {id: null} query: | SELECT id, updated_at as lastmod, 'weekly' as changefreq, '0.5' as priority FROM media__media WHERE enabled = true # blog post - group: "news" connection: doctrine.dbal.default_connection route: sonata_news_view parameters: {url: null} query: | SELECT CONCAT_WS('/', YEAR(created_at), MONTH(created_at), DAY(created_at), slug) as url , updated_at as lastmod, 'weekly' as changefreq, '0.5' as priority FROM news__post WHERE enabled = true AND (publication_date_start IS NULL OR publication_date_start <= NOW()) # page - works only for one site, please adapt the code if required - connection: doctrine.dbal.default_connection route: page_slug parameters: {path: null} query: | SELECT url as path, updated_at as lastmod, 'weekly' as changefreq, '0.5' as priority FROM page__snapshot WHERE route_name = 'page_slug' AND enabled = true AND (publication_date_start IS NULL OR publication_date_start <= NOW()) AND (publication_date_end IS NULL OR publication_date_end >= NOW()) # product categories - connection: doctrine.dbal.default_connection route: sonata_catalog_category parameters: {category_id: null, category_slug: null} query: | SELECT id as category_id, slug as category_slug, updated_at as lastmod, 'weekly' as changefreq, '0.5' as priority FROM classification__category WHERE enabled = true # products - connection: doctrine.dbal.default_connection route: sonata_product_view parameters: {productId: null, slug: null} query: | SELECT id as productId, slug, updated_at as lastmod, 'weekly' as changefreq, '0.5' as priority FROM product__product WHERE enabled = true Usage ----- - Generate the sitemap:: bin/console sonata:seo:sitemap web sonata-project.org .. note:: The command will generate all files in a temporary directory to avoid issue will files are indexed. Once the files are generated then the files will be copied to the ``web`` directory. The ``sonata-project.org`` argument will be used to prefix url with the provided domain.