Создание карты сайта для пользовательской модели


Я разработал специальный модуль, в котором перечислены несколько человек на сайте. У каждого человека есть свой собственный URL-адрес (индивидуальный контроллер Magento, который выполняет базовую работу с моделями людей), и мне нужно ввести эти общедоступные URL-адреса в XML-файл Google Sitemap.

Я хочу использовать собственное создание карты сайта Magento и cron, если смогу.

Mage_Sitemap_Model_Observer уже извлекает все записи Sitemap из таблицы sitemaps и один за другим вызывает их generateXml() методы.

$collection = Mage::getModel('sitemap/sitemap')->getCollection();
/* @var $collection Mage_Sitemap_Model_Mysql4_Sitemap_Collection */
foreach ($collection as $sitemap) {
    /* @var $sitemap Mage_Sitemap_Model_Sitemap */

    try {
        $sitemap->generateXml();
    }
    catch (Exception $e) {
        $errors[] = $e->getMessage();
    }
}

Я думаю, что мне нужно добавить мою новую карту сайта в таблицу sitemaps, которая затем будет вызвана для создания моего (отдельного) XML-файла для записей моей пользовательской модели. Однако я не знаю, как сказать Magento использовать мой расширенный My_Module_Model_Sitemap вместо просто Mage_Sitemap_Model_Sitemap, последний из которых просто предоставит мне XML-файл со списком всех тех же категорий, продуктов и страниц CMS, что и основные карты сайта.

В таблице sitemaps есть столбец sitemap_type, но на него никогда не ссылаются в кодовой базе Magento как насколько я могу судить.

Как я могу использовать встроенный механизм карты сайта Magento при перезаписи Mage_Sitemap_Model_Sitemap, чтобы иметь свой собственный метод generateXml()? Или я должен создать альтернативную систему sitemap только для своих собственных целей здесь?

Author: Evince Development, 2013-01-23

3 answers

Шаги, которые я в итоге использовал, были следующими, и комментарии и ответы до сих пор помогали мне двигаться в правильном направлении.

Сначала я добавил строку в таблицу "карта сайта". Поскольку у нас настроено несколько магазинов, и поскольку я хочу сохранить свой магазин модулей независимым, я не стал жестко кодировать эту вставку в миграцию MySQL, а просто запустил ее в магазине вручную:

INSERT INTO sitemap (sitemap_type, sitemap_filename, sitemap_path, store_id)
    VALUES ('people', 'people.xml', '/sitemap/', 2);

Затем я переписал модель Mage_Sitemap_Model_Sitemap внутри раздела global/models в моем собственном модуле config.xml файл:

<global>
    <models>
        <sitemap>
            <rewrite>
                <sitemap>Mymod_People_Model_Sitemap</sitemap>
            </rewrite>
        </sitemap>
    </models>
</global>

Это перезаписывает любые вызовы Mage_Sitemap_Model_Sitemap по всему сайту с помощью моей пользовательской модели, но я не хотел копировать и вставлять туда слишком много кода. Используя предложение Петара Джамбазова, я использовал условное условие для переноса на родительский класс, если только sitemap_type не является "людьми".

class Mymod_People_Model_Sitemap extends Mage_Sitemap_Model_Sitemap
{
    const PAGE_REFRESH_FREQUENCY = 'weekly';
    const PAGE_PRIORITY = '1.0';

    public function generateXml()
    {
        if ($this->getSitemapType() != 'people') {
            return parent::generateXml();
        }

        $io = new Varien_Io_File();
        $io->setAllowCreateFolders(true);
        $io->open(array('path' => $this->getPath()));

        if ($io->fileExists($this->getSitemapFilename()) && !$io->isWriteable($this->getSitemapFilename())) {
            Mage::throwException(Mage::helper('sitemap')->__('File "%s" cannot be saved. Please, make sure the directory "%s" is writeable by web server.', $this->getSitemapFilename(), $this->getPath()));
        }

        $io->streamOpen($this->getSitemapFilename());

        $io->streamWrite('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
        $io->streamWrite('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');

        $storeId = $this->getStoreId();
        $date    = Mage::getSingleton('core/date')->gmtDate('Y-m-d');
        $baseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);

        /**
         * Generate people sitemap
         */
        $changefreq = Mymod_People_Model_Sitemap::PAGE_REFRESH_FREQUENCY;
        $priority   = Mymod_People_Model_Sitemap::PAGE_PRIORITY;
        $collection = Mage::getModel('people/person')->getCollection();
        foreach ($collection as $item) {
            $xml = sprintf('<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
                htmlspecialchars($item->getUrl()),
                $date,
                $changefreq,
                $priority
            );
            $io->streamWrite($xml);
        }
        unset($collection);

        $io->streamWrite('</urlset>');
        $io->streamClose();

        $this->setSitemapTime(Mage::getSingleton('core/date')->gmtDate('Y-m-d H:i:s'));
        $this->save();

        return $this;
    }
}

Есть ли лучший способ избежать копирования и вставки так много из родительского класса?

 6
Author: Aaron Pollock, 2013-01-23 14:02:43

Вы можете либо расширить Mage_Sitemap_Model_Sitemap и в нем проверить sitemap_type, если это ваш тип, сгенерируйте свой xml, иначе сгенерируйте родительский xml. Или вы можете добавить наблюдателя для события коллекции load_after и добавить свою модель карты сайта в коллекцию.

 1
Author: Petar Dzhambazov, 2017-08-03 14:27:53

Есть ли лучший способ избежать копирования и вставки так много из родительского класса?

Если у вас есть Magento>=1.9.0.0 и вас не волнует использование продуктов или настройка приоритета/частоты изменения каталога, вы можете использовать наблюдателя на sitemap_products_generating_before

public function addPagesToSitemap(Varien_Event_Observer $observer)
{
    $collection = $observer->getCollection();
    $myPages = # your data: array('url_1', 'url_2')
    foreach ($myPages as $url) {
        $item = new Varien_Data_Object;
        $item->setUrl($url);
        $collection->addItem($item);
    }
}

Если вы хотите завершить различное поведение для страниц карты сайта, возможно, прочитайте Sitemap.xml измените home и/или отправьте более общее событие.

 0
Author: sv3n, 2017-08-03 10:20:28