Generazione di una Sitemap per un modello personalizzato


12

Ho sviluppato un modulo su misura che elenca una serie di persone sul sito. Ogni persona ha il proprio URL (un controller Magento su misura, che esegue CRUD di base sui modelli Person) e ho bisogno di inserire questi URL pubblici in un file XML di Google Sitemap.

Voglio usare la generazione di sitemap di Magento e il cron, se posso.

Il Mage_Sitemap_Model_Observergià estrae tutti i record della Sitemap dalla sitemapstabella e uno a uno chiama i loro generateXml()metodi.

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

Penso di dover aggiungere la mia nuova Sitemap nella sitemapstabella che verrà quindi chiamata per generare il mio file XML (separato) per i miei record del modello personalizzato. Tuttavia, non so come dire Magento di usare la mia esteso My_Module_Model_Sitemapanziché solo Mage_Sitemap_Model_Sitemap, l'ultima delle quali sarà solo darmi un file XML che elenca tutte le stesse categorie, i prodotti e le pagine CMS come le principali Sitemap.

La sitemapstabella ha una sitemap_typecolonna, ma questo non è mai indicato nella base di codice Magento per quanto ne so.

Come posso usare il motore di sitemap integrato di Magento mentre sovrascrivo il Mage_Sitemap_Model_Sitemapper avere il mio generateXml()metodo? O devo creare un sistema sitemap alternativo solo per i miei scopi qui?


vuoi estendere la Mage_Sitemap_Model_Sitemapclasse e sovrascrivere generateXml()giusto? cosa hai provato
FlorinelChis

Ci ho provato, ma Magento usa solo il Mage_Sitemap_Model_Sitemape mi dà un'altra sitemap contenente i prodotti, le categorie, le pagine CMS - non usa la mia versione estesa. Non sono sicuro di come dirlo come farlo.
Aaron Pollock il

Sto lavorando forse riscrivendo l'intero Mage_Sitemap_Model_Sitemapsito e aggiungendo il mio modello sotto la categoria e le chiamate di prodotto. Si aggiornerà presto con progressi.
Aaron Pollock il

Risposte:


6

I passaggi che ho finito per usare sono stati i seguenti e i commenti e le risposte finora mi hanno fatto iniziare nella giusta direzione.

Per prima cosa ho aggiunto una riga alla tabella "Sitemap". Dal momento che abbiamo configurato il multi-store e poiché voglio mantenere agnostico il mio store di moduli, non ho programmato questo INSERT in una migrazione MySQL, ma l'ho eseguito manualmente nel negozio:

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

Quindi ho sovrascritto il Mage_Sitemap_Model_Sitemapmodello all'interno della sezione global / models nel file config.xml del mio modulo:

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

Questo sovrascrive qualsiasi chiamata a livello di Mage_Sitemap_Model_Sitemapsito con il mio modello personalizzato, ma non volevo copiare e incollare troppo codice lì. Usando il suggerimento di Petar Dzhambazov, ho usato un condizionale per rinviare alla classe genitore a meno che non si sitemap_typetratti di "persone".

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

C'è un modo migliore, che evita di copiare e incollare così tanto dalla classe genitore?


1

Puoi estendere Mage_Sitemap_Model_Sitemape in esso verificare sitemap_typese è il tuo tipo, generare il tuo xml, altrimenti generare il genitore xml. Oppure puoi aggiungere un osservatore per l' load_afterevento di raccolta e aggiungere il tuo modello di sitemap alla raccolta.


0

C'è un modo migliore, che evita di copiare e incollare così tanto dalla classe genitore?

Se hai Magento> = 1.9.0.0 e non ti interessa utilizzare i prodotti o le priorità di catalogo / modifica della frequenza, puoi utilizzare un osservatore su 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);
    }
}

Se vuoi completare un comportamento diverso per le pagine delle Sitemap, potresti leggere Sitemap.xml cambiare home e / o inviare un evento più generico .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.