demi/sitemap-generator

用于生成 sitemap.xml 文件的 Yii2 组件。

安装次数:21,906

依赖: 1

建议者: 0

安全: 0

星标: 14

关注者: 5

分支: 4

开放问题: 1

类型:yii2-extension

1.2.0 2020-06-26 13:23 UTC

This package is auto-updated.

Last update: 2024-09-26 22:23:29 UTC


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" 文件