5. Sitemap
The SonataSeoBundle
provides a support for static sitemap generation.
You can either create services or provide raw SQL queries.
5.1. 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;
}
}
5.2. 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
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.
5.3. Configuration example
Sitemap configuration obviously depends on the bundle, page types & custom routes you choose to expose.
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
5.4. 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.