Создание xml карты сайта

Карта сайта — это специальный xml файл, в котором отражены ссылки на все важные страницы сайта.

Карту сайта будем создавать при помощи пакета thepixeldeveloper/sitemap-bundle.

К сожалению, тестовый проект у нас сегодня старый, на Symfony 3.4, но, я думаю, на более свежих версиях фреймворка не будет больших отличий.

1. Устанавливаем

$ composer require thepixeldeveloper/sitemap-bundle
// app/AppKernel.php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
 
class AppKernel extends Kernel
{
     public function registerBundles()
     {
         $bundles = [
         ...,
         new Thepixeldeveloper\SitemapBundle\ThepixeldeveloperSitemapBundle(),
         ];
      }
}
# app/config/routing.yml
...
thepixeldeveloper_sitemap_bundle:
    resource: "@ThepixeldeveloperSitemapBundle/Resources/config/routing.yml"
    prefix:   /
# app/config/services.yml 
...
thepixeldeveloper_sitemap:
    directory: '%kernel.project_dir%/var/sitemaps'
# upd. Symfony 4.4:
services:
    Thepixeldeveloper\SitemapBundle\Interfaces\DumperInterface: '@Thepixeldeveloper\SitemapBundle\Dumper\SitemapDumper'
    Thepixeldeveloper\Sitemap\Interfaces\DriverInterface: '@Thepixeldeveloper\Sitemap\Drivers\XmlWriterDriver'

2. Подписываемся на событие создания карты сайта

<?php
namespace AppBundle\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Thepixeldeveloper\Sitemap\Urlset;
use Thepixeldeveloper\Sitemap\Url;
use Thepixeldeveloper\Sitemap\ChunkedUrlset;
use Thepixeldeveloper\SitemapBundle\Event\SitemapPopulateEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class SitemapGenerationSubscriber implements EventSubscriberInterface
{
    private $router;
    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return [
            SitemapPopulateEvent::NAME => [
                ['onSitemapGeneration'0]
            ],
        ];
    }
    public function onSitemapGeneration(SitemapPopulateEvent $event)
    {
        // Добавляем к карте сайта наши url
        $event->getUrlset()->add(new Url($this->router->generate('sample_route', [], UrlGeneratorInterface::ABSOLUTE_URL)));
    }
}

После этого по команде «php bin/console thepixeldeveloper:sitemap:dump» по адресу /sitemap.xml должна создаваться карта сайта.

3. Полные пути в оглавлении карты

Полученная таким образом карта сайта имеет один существенный недостаток — её оглавление содержит не полные пути:

<sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">
<sitemap>
<loc>/urlset-0.xml</loc>
<lastmod>2020-03-18T22:15:51+03:00</lastmod>
</sitemap>
</sitemapindex>

Это — проблема, так как Яндекс.Вебмастер показывает ошибку:

Я предлагаю такое решение:

  • создать сервис, который по умолчанию будет создавать полные пути;
  • передать этот сервис вместо стандартного роутера классу Thepixeldeveloper\SitemapBundle\Dumper\SitemapDumper.
<?php
// src/AppBundle/Service/AbsoluteRouter.php
namespace AppBundle\Service;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
class AbsoluteRouter implements UrlGeneratorInterface
{
    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }
    public function generate($name$parameters = [], $referenceType = UrlGeneratorInterface::ABSOLUTE_URL)
    {
        return $this->router->generate($name$parameters$referenceType);
    }
    public function setContext(RequestContext $context) {}
    public function getContext() {}
}
# app/config/services.yml 
parameters:
    sitemap_directory:
        '%kernel.project_dir%/var/sitemaps'
# upd: Symfony 4.4
# Прописываем реальный адрес сайта
    router.request_context.host: 'mydomain.com'
    router.request_context.scheme: 'https'
thepixeldeveloper_sitemap:
    directory: '%sitemap_directory%'
services:
    ...
    Thepixeldeveloper\SitemapBundle\Dumper\SitemapDumper:
        - '@Thepixeldeveloper\Sitemap\Drivers\XmlWriterDriver'
        - '@Symfony\Component\Filesystem\Filesystem'
        - '@AppBundle\Service\AbsoluteRouter'
        - '%sitemap_directory%'

Не забываем очистить кэш и перегенерировать карту, и вот что мы получили в результате: