Gerando um Sitemap para um Modelo Customizado

12

Eu desenvolvi um módulo sob medida que lista uma série de pessoas no site. Cada pessoa tem seu próprio URL (um controlador Magento sob medida, que faz CRUD básico nos modelos Person) e eu preciso alimentar esses URLs públicos em um arquivo XML do Google Sitemap.

Eu quero usar a geração do mapa do site do Magento e o cron, se puder.

O Mage_Sitemap_Model_Observerjá puxa todos os registros do Sitemap da sitemapstabela e um a um chama seus generateXml()métodos.

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

Acho que preciso adicionar meu novo Sitemap na sitemapstabela que será chamada para gerar meu arquivo XML (separado) para meus registros de modelo personalizados. No entanto, não sei como dizer ao Magento para usar meu estendido em My_Module_Model_Sitemapvez de apenas Mage_Sitemap_Model_Sitemap, o último dos quais me fornecerá um arquivo XML listando todas as mesmas categorias, produtos e páginas CMS dos principais sitemaps.

A sitemapstabela possui uma sitemap_typecoluna, mas isso nunca é mencionado na base de código Magento, até onde eu sei.

Como posso usar o mecanismo de sitemap embutido do Magento enquanto sobrescrito Mage_Sitemap_Model_Sitemappara ter meu próprio generateXml()método? Ou devo criar um sistema de sitemap alternativo apenas para meus próprios fins aqui?

Aaron Pollock
fonte
você deseja estender a Mage_Sitemap_Model_Sitemapclasse e substituir, generateXml()certo? o que você tentou?
precisa saber é o seguinte
Tentei isso, mas o Magento apenas usa o Mage_Sitemap_Model_Sitemape me fornece outro sitemap contendo os produtos, categorias, páginas do CMS - ele não usa minha versão estendida. Não sei bem como dizer como fazê-lo.
Aaron Pollock
Trabalhando em talvez reescrever todo o Mage_Sitemap_Model_Sitemapsite e adicionar meu próprio modelo na categoria e nas chamadas de produtos. Será atualizado em breve com o progresso.
Aaron Pollock

Respostas:

6

As etapas que acabei usando foram as seguintes, e os comentários e respostas até agora me levaram a começar na direção certa.

Primeiro, adicionei uma linha à tabela "sitemap". Como temos a configuração de várias lojas e como quero manter meu armazenamento de módulos independente, não codifiquei esse INSERT em uma migração do MySQL, mas apenas o executei manualmente na loja:

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

Em seguida, substitui o Mage_Sitemap_Model_Sitemapmodelo na seção global / models no arquivo config.xml do meu próprio módulo:

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

Isso substitui todas as chamadas para todo o Mage_Sitemap_Model_Sitemapsite com o meu modelo personalizado, mas eu não queria copiar e colar muito código lá. Usando a sugestão de Petar Dzhambazov, usei um condicional para adiar a classe dos pais, a menos que sitemap_typesejam "pessoas".

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

Existe uma maneira melhor, que evite copiar e colar muito da classe pai?

Aaron Pollock
fonte
1

Você pode estender Mage_Sitemap_Model_Sitemape verificar sitemap_typese é do seu tipo, gerar seu xml e gerar outro xml pai. Ou você pode adicionar um observador para um load_afterevento de coleção e adicionar seu modelo de sitemap à coleção.

Petar Dzhambazov
fonte
0

Existe uma maneira melhor, que evite copiar e colar muito da classe pai?

Se você possui Magento> = 1.9.0.0 e não se preocupa em usar produtos ou prioridade de catálogo / alterar a configuração de frequência, pode usar um observador em 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 você deseja concluir um comportamento diferente nas páginas do mapa do site, leia Sitemap.xml change home e / ou envie um evento mais genérico .

sv3n
fonte