Задачу создания динамического 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.