Generando un mapa del sitio para un modelo personalizado

12

Desarrollé un módulo a medida que enumera una serie de personas en el sitio. Cada persona tiene su propia URL (un controlador Magento a medida, que hace CRUD básico en modelos Personales) y necesito alimentar estas URL públicas en un archivo XML de Google Sitemap.

Quiero usar la generación del mapa del sitio de Magento y el cron si puedo.

El Mage_Sitemap_Model_Observerya extrae todos los registros de Sitemap de la sitemapstabla y uno por uno llama a sus 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();
    }
}

Creo que necesito agregar mi nuevo Sitemap en la sitemapstabla que luego se llamará para generar mi archivo XML (separado) para mis registros de modelos personalizados. Sin embargo, no sé cómo decirle a Magento que use mi extendido en My_Module_Model_Sitemaplugar de solo Mage_Sitemap_Model_Sitemap, el último de los cuales solo me dará un archivo XML con las mismas categorías, productos y páginas CMS que los mapas de sitio principales.

La sitemapstabla tiene una sitemap_typecolumna, pero por lo que puedo decir, esto nunca se menciona en la base de código de Magento.

¿Cómo puedo usar el motor de mapa del sitio incorporado de Magento mientras sobrescribo Mage_Sitemap_Model_Sitemappara tener mi propio generateXml()método? ¿O debo construir un sistema de mapa de sitio alternativo solo para mis propios fines aquí?

Aaron Pollock
fuente
quieres extender la Mage_Sitemap_Model_Sitemapclase y sobrescribir, generateXml()¿verdad? que has intentado
FlorinelChis
Lo he intentado, pero Magento solo usa el Mage_Sitemap_Model_Sitemapy me da otro mapa del sitio que contiene los productos, categorías, páginas CMS, no usa mi versión extendida. No estoy seguro de cómo decirle cómo hacerlo.
Aaron Pollock el
Trabajando para quizás reescribir todo el Mage_Sitemap_Model_Sitemapsitio y agregar mi propio modelo en la categoría y llamadas de productos. Se actualizará pronto con el progreso.
Aaron Pollock el

Respuestas:

6

Los pasos que terminé usando fueron los siguientes, y los comentarios y respuestas hasta ahora me ayudaron a comenzar en la dirección correcta.

Primero agregué una fila a la tabla "mapa del sitio". Como tenemos una configuración de varias tiendas y porque quiero mantener mi tienda de módulos independiente, no codifiqué este INSERT en una migración de MySQL, sino que simplemente lo ejecuté en la tienda manualmente:

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

Luego sobrescribí el Mage_Sitemap_Model_Sitemapmodelo dentro de la sección global / models en el archivo config.xml de mi propio módulo:

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

Esto sobrescribe cualquier llamada a todo el Mage_Sitemap_Model_Sitemapsitio con mi modelo personalizado, pero no quería copiar y pegar demasiado código allí. Usando la sugerencia de Petar Dzhambazov, utilicé un condicional para diferir a la clase principal a menos que sitemap_typesea ​​"personas".

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

¿Hay una mejor manera, que evite copiar y pegar tanto de la clase principal?

Aaron Pollock
fuente
1

Puede ampliar Mage_Sitemap_Model_Sitemapy, en él, verificar sitemap_typesi es su tipo, generar su xml, de lo contrario generar xml principal. O puede agregar un observador para el load_afterevento de colección y agregar su modelo de mapa del sitio a la colección.

Petar Dzhambazov
fuente
0

¿Hay una mejor manera, que evite copiar y pegar tanto de la clase principal?

Si tiene Magento> = 1.9.0.0 y no le importa usar productos o la configuración de prioridad de cambio / prioridad del catálogo, puede usar un observador en 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);
    }
}

Si desea completar un comportamiento diferente para las páginas del mapa del sitio, puede leer Sitemap.xml cambiar a casa y / o enviar un evento más genérico .

sv3n
fuente