Generowanie mapy witryny dla modelu niestandardowego

12

Opracowałem na zamówienie moduł, który wymienia szereg osób na stronie. Każda osoba ma własny adres URL (specjalnie zaprojektowany kontroler Magento, który wykonuje podstawowe CRUD w modelach Person) i muszę podać te publiczne adresy URL do pliku XML Google Sitemap.

Chcę użyć generowania map witryn Magento i crona, jeśli mogę.

Mage_Sitemap_Model_ObserverJuż ściąga wszystkie rekordy witryny z sitemapstabeli i jeden po drugim nazywa swoje generateXml()metody.

$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();
    }
}

Myślę, że muszę dodać nową mapę witryny do sitemapstabeli, która zostanie następnie wywołana w celu wygenerowania (osobnego) pliku XML dla rekordów modelu niestandardowego. Nie wiem jednak, jak powiedzieć Magento, aby używał mojego rozszerzonego My_Module_Model_Sitemapzamiast zwykłego Mage_Sitemap_Model_Sitemap, z którego ten ostatni da mi tylko plik XML z listą wszystkich tych samych kategorii, produktów i stron CMS jako głównych map witryn.

sitemapsTabela ma sitemap_typekolumnę, ale to nigdy nie jest wymieniony w Magento CODEBASE ile mogę powiedzieć.

Jak mogę korzystać z wbudowanego silnika mapy witryny Magento, nadpisując przy tym Mage_Sitemap_Model_Sitemapswoją własną generateXml()metodę? A może muszę tutaj zbudować alternatywny system map witryn tylko do własnych celów?

Aaron Pollock
źródło
chcesz przedłużyć Mage_Sitemap_Model_Sitemapklasę i zastąpić, generateXml()prawda? czego próbowałeś
FlorinelChis
Próbowałem tego, ale Magento po prostu używa Mage_Sitemap_Model_Sitemapi daje mi kolejną mapę witryny zawierającą produkty, kategorie, strony CMS - nie używa mojej rozszerzonej wersji. Nie jestem pewien, jak to powiedzieć.
Aaron Pollock
Być może pracuję nad przepisaniem całej Mage_Sitemap_Model_Sitemapwitryny i dodaniem własnego modelu w ramach kategorii i wywołań produktów. Zaktualizuje wkrótce z postępem.
Aaron Pollock

Odpowiedzi:

6

Kroki, na których się ostatecznie skończyłem, były następujące, a komentarze i odpowiedzi do tej pory doprowadziły mnie do właściwego kierunku.

Najpierw dodałem wiersz do tabeli „mapy witryny”. Ponieważ skonfigurowaliśmy wiele sklepów, a ponieważ chcę zachować agnostyk magazynu modułów, nie wstawiłem tego kodu INSERT do migracji MySQL, ale po prostu uruchomiłem go ręcznie w sklepie:

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

Następnie nadpisałem Mage_Sitemap_Model_Sitemapmodel w sekcji global / models w pliku config.xml mojego modułu:

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

To zastępuje wszelkie wywołania do Mage_Sitemap_Model_Sitemapcałej witryny moim niestandardowym modelem, ale nie chciałem tam kopiować i wklejać zbyt dużo kodu. Korzystając z sugestii Petara Dzhambazova, użyłem warunku, aby odroczyć się do klasy nadrzędnej, chyba że sitemap_typesą to „ludzie”.

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;
    }
}

Czy istnieje lepszy sposób, który pozwala uniknąć kopiowania i wklejania tak dużo z klasy nadrzędnej?

Aaron Pollock
źródło
1

Możesz albo rozszerzyć Mage_Sitemap_Model_Sitemapi sprawdzić, sitemap_typeczy to twój typ, wygenerować xml, w przeciwnym razie wygenerować xml nadrzędny. Możesz też dodać obserwatora do load_afterwydarzenia kolekcji i dodać model mapy witryny do kolekcji.

Petar Dzhambazov
źródło
0

Czy istnieje lepszy sposób, który pozwala uniknąć kopiowania i wklejania tak dużo z klasy nadrzędnej?

Jeśli masz Magento> = 1.9.0.0 i nie przejmujesz się używaniem produktów lub priorytetem katalogu / zmianą częstotliwości, możesz użyć obserwatora na 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);
    }
}

Jeśli chcesz zakończyć różne zachowanie na stronach z mapami witryn, przeczytaj Sitemap.xml zmień stronę główną i / lub wywołaj bardziej ogólne zdarzenie .

sv3n
źródło