demi/ sitemap-generator
用于生成 sitemap.xml 文件的 Yii2 组件。
1.2.0
2020-06-26 13:23 UTC
Requires
- php: >=5.4.0
- yiisoft/yii2: *
README
用于生成 sitemap.xml 文件的 Yii2 组件
安装
运行
composer require "demi/sitemap-generator" "~1.0"
配置
编辑 "/console/config/main.php"
return [ 'controllerMap' => [ 'sitemap' => [ 'class' => 'demi\sitemap\SitemapController', 'modelsPath' => '@console/models/sitemap', // Sitemap-data models directory 'modelsNamespace' => 'console\models\sitemap', // Namespace in [[modelsPath]] files 'savePathAlias' => '@frontend/web', // Where would be placed the generated sitemap-files 'sitemapFileName' => 'sitemap.xml', // Name of main sitemap-file in [[savePathAlias]] directory ], ], ];
因为生成器在控制台运行,Yii 创建绝对 URL 应该知道网站基本 URL,因此进行配置:“./environments/prod/console/config/main-local.php”
'components' => [ // fix console create url 'urlManager' => [ 'baseUrl' => 'http://example.com', ], ],
"./environments/dev/console/config/main-local.php"
'components' => [ // fix console create url 'urlManager' => [ 'baseUrl' => 'http://example.local', ], ],
重新初始化项目本地配置
php ./init
或者将相同的配置应用到您的 "/console/config/main-local.php" 文件中
您还可以合并前端(或公共)配置到控制台配置中的 urlManager 规则。
只需更改 "/console/config/main.php" 文件即可
// get config of urlManager from frontend for correctly create urls in console app $frontend = require(__DIR__ . '/../../frontend/config/main.php'); return [ 'id' => 'app-console', 'components' => [ 'urlManager' => $frontend['components']['urlManager'], ], ];
还有,为忽略所有生成的 sitemap 文件,添加 .gitignore 也是很有用的。
# sitemaps
/frontend/web/sitemap*.xml
sitemap-data 模型(重要!)
您应该为每个需要在结果 sitemap.xml 中显示的模型创建特殊的 sitemap 模型。
所以让我们创建一个从您的 Post
模型扩展并附加接口的最大 sitemap 模型
/console/models/sitemap/SitemapPost.php
<?php namespace console\models\sitemap; use Yii; use yii\helpers\Url; use common\models\Post; use demi\sitemap\interfaces\Basic; use demi\sitemap\interfaces\GoogleAlternateLang; use demi\sitemap\interfaces\GoogleImage; class SitemapPost extends Post implements Basic, GoogleImage, GoogleAlternateLang { /** * Handle materials by selecting batch of elements. * Increase this value and got more handling speed but more memory usage. * * @var int */ public $sitemapBatchSize = 10; /** * List of available site languages * * @var array [langId => langCode] */ public $sitemapLanguages = [ 'en', 'ru-RU', ]; /** * If TRUE - Yii::$app->language will be switched for each sitemapLanguages and restored after. * * @var bool */ public $sitemapSwithLanguages = true; /* BEGIN OF Basic INTERFACE */ /** * @inheritdoc */ public function getSitemapItems($lang = null) { // Add to sitemap.xml links to regular pages return [ // site/index [ 'loc' => Url::to(['/site/index', 'lang' => $lang]), 'lastmod' => time(), 'changefreq' => static::CHANGEFREQ_DAILY, 'priority' => static::PRIORITY_10, 'alternateLinks' => [ 'en' => Url::to(['/site/index', 'lang' => 'en']), 'ru' => Url::to(['/site/index', 'lang' => 'ru']), ], ], // post/index [ 'loc' => Url::to(['/post/index', 'lang' => $lang]), 'lastmod' => time(), 'changefreq' => static::CHANGEFREQ_DAILY, 'priority' => static::PRIORITY_10, 'alternateLinks' => [ 'en' => Url::to(['/post/index', 'lang' => 'en']), 'ru' => Url::to(['/post/index', 'lang' => 'ru']), ], ], // ... you can add more regular pages if needed, but I recommend // separate pages related only for current model class ]; } /** * @inheritdoc */ public function getSitemapItemsQuery($lang = null) { // Base select query for current model return static::find() ->select(['id', 'title', 'date', 'updated_at']) ->where(['status' => Post::STATUS_ACTIVE]) ->orderBy(['date' => SORT_DESC]); } /** * @inheritdoc */ public function getSitemapLoc($lang = null) { // Return absolute url to Post model view page return Url::to(['/post/view', 'id' => $this->id], true); } /** * @inheritdoc */ public function getSitemapLastmod($lang = null) { return $this->updated_at; } /** * @inheritdoc */ public function getSitemapChangefreq($lang = null) { return static::CHANGEFREQ_MONTHLY; } /** * @inheritdoc */ public function getSitemapPriority($lang = null) { return static::PRIORITY_8; } /* END OF Basic INTERFACE */ /* BEGIN OF GoogleImage INTERFACE */ /** * @inheritdoc * * @param self $material */ public function getSitemapMaterialImages($material, $lang = null) { // List of Post related images without scheme (news logo eg.) $images = []; // "/uploads/post/1.jpg" $images[] = $this->logo; // You can add more images (if Post have a photo gallery etc.) // !important! You can return array of any elements(Objects eg. $this->images relation), because its elements // will be foreached and become as $image argument for $this->getSitemapImageLoc($image) return $images; } /** * @inheritdoc */ public function getSitemapImageLoc($image, $lang = null) { // Return absolute url to each Post image // @see $image argument becomes from $this->getSitemapMaterialImages() return Yii::$app->urlManager->baseUrl . $image; } /** * @inheritdoc */ public function getSitemapImageGeoLocation($image, $lang = null) { // Location name string, for example: "Limerick, Ireland" return null; } /** * @inheritdoc */ public function getSitemapImageCaption($image, $lang = null) { // Image caption, simply use Post title return $this->title; } /** * @inheritdoc */ public function getSitemapImageTitle($image, $lang = null) { // Image title, simply use Post title return $this->title; } /** * @inheritdoc */ public function getSitemapImageLicense($image, $lang = null) { return null; } /* END OF GoogleImage INTERFACE */ /* BEGIN OF GoogleAlternateLang INTERFACE */ /** * @inheritdoc */ public function getSitemapAlternateLinks() { // Generate altername links for all site language versions for this Post $buffer = []; foreach ($this->sitemapLanguages as $langCode) { $buffer[$langCode] = $this->getSitemapLoc($langCode); // or eg.: $buffer[$langCode] = Url::to(['post/view', 'id' => $this->id, 'lang' => $langCode]); } return $buffer; } /* END OF GoogleAlternateLang INTERFACE */ }
如果您的 sitemap 模型没有图像或只有一个站点语言,只需移除接口 GoogleImage
和/或 GoogleAlternateLang
及其函数。
生成器会自动通过配置路径搜索您所有的 sitemap 模型:/console/models/sitemap/*
用法
在项目根目录中运行 Yii 控制台命令
./yii sitemap
然后检查 "http://site/sitemap.xml" 文件