Хочу подлиться с читателями Хабр очередным своим открытием, что все сложное просто. Задачу создания динамического sitemap на Yii2 мне поставил СЕО специалист. Мне нужно было создать sitemap на основе результата запроса из базы данных.

Поиск решений сводился к расширению пула зависимостей и установкой новых библиотек. Однако нашлось решение в рамках Yii2 без сторонних зависимостей. При этом решение довольно гибкое и применимо в разных интерпретациях.


И так приступим:
Сначала создадим экшэн метод в контроллере SiteController который будет брать данные из модели и отдавать рендеру. При этом приложению задаем формат ответа и добавляем заголовок для клиента.

class SiteController extends \yii\web\Controller

…
 public function actionSitemap()
{
    Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
    Yii::$app->response->headers->add('Content-Type', 'text/xml');
    $articles = Articles::find()->all();
    return $this->renderPartial('sitemap', ['articles' => $articles]);
}

Теперь создадим такой виджет frontend/views/site/sitemap.php

<?php

/** @var \common\models\Articles[] $articles */

echo '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL ?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://site.org/</loc>
        <priority>0.0</priority>
        <changefreq>daily</changefreq>
        <lastmod>2022-11-15</lastmod>
    </url>
    <?php foreach ($articles as $article): ?>
        <url>
            <loc>https://site.org/articles/<?= $article->tag ?></loc>
            <lastmod><?= date('Y-m-d', strtotime($article->created_at)) ?></lastmod>
        </url>
    <?php endforeach; ?>
</urlset>

На этом этапе можно сделать отладку и увидеть желаемый результат. И настроить маршрутизацию для динамического sitemap Yii2. Для этого в main.php например для всего приложения common/config/main.php добавить или изменить конфигурацию urlManager примерно так.

'urlManager' => [
    'rules' => [
        'sitemap.xml' => 'site/sitemap'
    ],
],

Это решение позволит решить 99% подобных задач, в том числе построения сложных динамических деревьев sitemap Yii2.

Комментарии (8)


  1. FanatPHP
    05.11.2022 21:19
    +5

    А какие варианты рассматривались в плане "расширения пула зависимостей и установки новых библиотек"?


    Вообще, по моему опыту, самое сложное в построении сайтмапов — это не XML вывести, а выковырять из базы все типы страниц. То есть построить такую виртуальную структуру приложения.


    1. Krivodanov Автор
      05.11.2022 21:51
      -1

      Разве данное решение мешает построить sitemap сложной вложенности? Если у вас есть другое решение давайте рассмотрим...


      1. FanatPHP
        06.11.2022 09:41
        +4

        Ну то есть статья не про то, как построить sitemap, а про то как в Yii добавить виджет?


      1. fijj
        06.11.2022 18:31
        +3

        Честно говоря ожидал решение в видео готового модуля с возможностью конфигурирования, который на основе имеющихся контролеров генерирует карту, дабы каждый раз не лазить во вьюху генерации xml карты при добавление новых экшенов или контролеров. Так что в чём открытие не пойму. Это решение не решает главную проблему, которую описал FanatPHP.


  1. SDKiller
    06.11.2022 08:30
    +2

    Зачем во вьюхе echo?

    Зачем в контроллере renderPartial?


    1. SDKiller
      06.11.2022 08:33
      +1

      Зачем Response::FORMAT_RAW?


  1. mozg3000tm
    06.11.2022 11:05
    +1

    Не знаком с темой, поэтому хочу спросить. Под этим решением способным решить 99% задач, подразумевается использование urlset ? Или вообще все что вы написали?


  1. Hett
    06.11.2022 23:20
    +2

    Статья ради статьи. Берем докуменьацию по Yii, HTML заменям на XML, рендерим 3 тега, статья готова, выдаем за гениальное изобретение. Уровень 9 класса где-то. Ну не серьезно тут такое постить.