We use an XML sitemap to allow search engines to find website content. You may have pages that are not linked, so a sitemap provides a method for search engine web crawlers to identify these pages.

Now rather than manually maintain a sitemap, we are going to use the Yii2 extension called himiklab/yii2-sitemap-module that will automatically create and update our sitemap page.

In this example we are going to add the sitemap to the frontend of our Yii2 web application. The idea is to automatically create the XML entries for our site by looping through each active article.

Install Extension using Composer

In your console type the following command to add and install the sitemap module to your Yii2 application:

sudo composer require --prefer-dist "himiklab/yii2-sitemap-module" "*"

Add Sitemap to Frontend Config File

Update frontend/config/main.php; add link to SitemapBehavior (line 2) and add the sitemap settings to the modules section of your config file (lines 19-51).

<?php
use himiklab\sitemap\behaviors\SitemapBehavior;

$params = array_merge(
    require __DIR__ . '/../../common/config/params.php',
    require __DIR__ . '/../../common/config/params-local.php',
    require __DIR__ . '/params.php',
    require __DIR__ . '/params-local.php'
);

return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    'bootstrap' => [
        'log',
        'coderius\hitCounter\config\Bootstrap',
    ],
    'controllerNamespace' => 'frontend\controllers',
    'modules' => [
        'sitemap' => [
            'class' => himiklab\sitemap\Sitemap::class,
            'models' => [
                // Urls generated by models
                common\models\PostRecord::class,
            ],
            'urls'=> [
                // Additional urls
                [
                    'loc' => '/home',
                    'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
                    'priority' => 0.7,
                ],
                [
                    'loc' => '/post',
                    'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
                    'priority' => 0.6,
                ],
                [
                    'loc' => '/about',
                    'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
                    'priority' => 0.5,
                ],
                [
                    'loc' => '/contact',
                    'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
                    'priority' => 0.5,
                ],
            ],
            'enableGzip' => true,
            'cacheExpire' => 86400,     // 24 hours
        ],

There are two main parts to declaring what pages are to be included in the sitemap. The first is the models section (lines 22-25), this is where we tell the sitemap module to use our common\models\PostRecord to generate content. The second section is urls (lines 26-48), this is where we manually provide the urls to be included. In this case the home, post, about and contact pages.

Also note we can also provided additional data for each page. Here we have specified the changefreq and proirity. More information about these and other tags can be found at https://www.sitemaps.org/protocol.html.

The sitemap is held in cache and in our example will expired after 86,400 seconds (24 hours) but you can reset the sitemap cache by running the following command within a web controller or after a Post record is created, updated or deleted.

Yii::$app->cache->delete('sitemap');

Still in our config file we need to create a rule to allow access to our sitemap. This is performed by adding lines 12-16 to our urlManager in the components section:

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => false,
            'rules' => [
                'contact' => 'site/contact',
                'home' => 'site/index',
                'index' => 'site/index',
                'about' => 'site/about',
                'post/index' => 'post/index',
                'post/<slug:[A-Za-z0-9 -_.]+>' => 'post/view',
                [
                    'pattern' => 'sitemap',
                    'route' => 'sitemap/default/index',
                    'suffix' => 'xml',
                ],
            ],
        ],

Update Active Record with Sitemap Behaviour

Add SitemapBehavior to the beginning of your active record model (common/models/PostRecord.php)

use himiklab\sitemap\behaviors\SitemapBehavior;

Then update the behaviors function (lines 17-32) with the rules to be used to create the sitemap content for all our active posts.

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'blameable' => [
                'class' => BlameableBehavior::class,
                'createdByAttribute' => !isset($_SESSION) ? false : 'created_by',
                'updatedByAttribute' => !isset($_SESSION) ? false : 'updated_by',
            ],
            'sluggable' => [
                'class' => SluggableBehavior::class,
                'attribute' => 'name',
                'slugAttribute' => 'slug',
            ],
            'sitemap' => [
                'class' => SitemapBehavior::class,
                'scope' => function ($model) {
                    /** @var \yii\db\ActiveQuery $model */
                    $model->where(['status' => PostRecord::STATUS_ACTIVE]);
                },
                'dataClosure' => function ($model) {
                    /** @var PostRecord $model */
                    return [
                        'loc' => Url::to($model->url, true),
                        'lastmod' => $model->updated_at,
                        'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
                        'priority' => 0.8
                    ];
                }
            ],
            'timestamp' => [
                'class' => TimestampBehavior::class,
            ],
        ];
    }

The scope section (line 19-22) tells our sitemap module to only include our active Posts. And lines 23-31 provides the information to be included for each active Post. In this case we are providing the url, lastmod, changefreq and priority.

You can view this website's sitemap by going to https://www.davidl.co.uk/sitemap