Карта сайта — это специальный xml файл, в котором отражены ссылки на все важные страницы сайта.
Карту сайта будем создавать при помощи пакета thepixeldeveloper/sitemap-bundle.
К сожалению, тестовый проект у нас сегодня старый, на Symfony 3.4, но, я думаю, на более свежих версиях фреймворка не будет больших отличий.
$ 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'
<?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 должна создаваться карта сайта.
Полученная таким образом карта сайта имеет один существенный недостаток — её оглавление содержит не полные пути:
<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>
Это — проблема, так как Яндекс.Вебмастер показывает ошибку:
Я предлагаю такое решение:
<?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%'
Не забываем очистить кэш и перегенерировать карту, и вот что мы получили в результате: