В October CMS есть замечательный плагин Rainlab.Sitemap. Он позволяет создать страницу с XML-картой сайт, настроив выдачу нужных страниц. Его поддерживает в т.ч. и плагин блога, позволяя вывести в карту сайта записи и категории блога.

Но в документации размыто описано как добавить в плагин возможность вывода страниц своего плагина в sitemap. Особенно это не понятно тем, кто не использовал плагин Rainlab.Pages, т.к. плагин карты сайта использует те же данные, что и компонент вывода меню в Rainlab.Pages.

Итак, потребуется подписаться на три события в файле регистрации плагина (plugin.php) в методе boot:

use Event;

//...

public function boot()
{
    Event::listen('pages.menuitem.listTypes', function() {
        return [
            'test-plugin-categories' => 'Test Plugin Categories',
            'test-plugin-element' => 'Test Plugin Elements',
        ];
    });

    Event::listen('pages.menuitem.getTypeInfo', function($type) {
        if ($type == 'test-plugin-categories') {
            return Models\Category::getMenuTypeInfo($type);
        }
        elseif ($type == 'test-plugin-element') {
            return Models\Element::getMenuTypeInfo($type);
        }
    });

    Event::listen('pages.menuitem.resolveItem', function($type, $item, $url, $theme) {
        if ($type == 'test-plugin-categories') {
            return Models\Category::resolveMenuItem($item, $url, $theme);
        }
        elseif ($type == 'test-plugin-element') {
            return Models\Element::resolveMenuItem($item, $url, $theme);
        }
    });
}
  1. pages.menuitem.listTypes - событие получения списка типов меню
  2. pages.menuitem.getTypeInfo - событие получения информации о типах меню
  3. pages.menuitem.resolveItem - событие получения списка элементов меню

В классы моделей добавляем соответствующие методы:

public static function getMenuTypeInfo($type)
{
    // получаем текущую тему сайта
    $theme = \Cms\Classes\Theme::getActiveTheme();

    $result = [
        'dynamicItems' => true,
        // выберем все страницы сайта:
        'cmsPages' => \Cms\Classes\Page::listInTheme($theme, true),
    ];

    return $result;
}
// ...
public static function resolveMenuItem($item, $url, $theme)
{
    $result = [
        'items' => []
    ];

    $page = \Cms\Classes\Page::loadCached($theme, $item->cmsPage);
    $rows = self::orderBy('title')->get();

    foreach ($rows as $row) {
        $item = [
            // Название страницы в карте сайта
            'title' => $row->title,
            // URL страницы в карте сайта (напр. "/element/:slug")
            // Создаем URL с помощью хелпера url()
            'url'   => url($page->getBaseFileName(), ['slug' => $row->slug]),
            // Параметр lastmod в карте сайта
            'mtime' => $row->updated_at,
        ];

        $result['items'][] = $item;
    }

    return $result;
}

Таким образом получаем новый тип меню, а в нашем случае – типа элемента карты сайта: Sitemap.png