Yii2 динамический sitemap
Хочу подлиться с читателями Хабр очередным своим открытием, что все сложное просто. Задачу создания динамического 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.