Génération d'un plan du site pour un modèle personnalisé

12

J'ai développé un module sur mesure qui répertorie une série de personnes sur le site. Chaque personne a sa propre URL (un contrôleur Magento sur mesure, qui fait CRUD de base sur les modèles Personne) et je dois alimenter ces URL publiques dans un fichier XML Google Sitemap.

Je veux utiliser la propre génération de sitemap de Magento et le cron si je le peux.

Le Mage_Sitemap_Model_Observertire déjà tous les enregistrements Sitemap de la sitemapstable et un par un appelle leurs generateXml()méthodes.

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

Je pense que je dois ajouter mon nouveau plan Sitemap dans le sitemapstableau qui sera ensuite appelé pour générer mon fichier XML (séparé) pour mes enregistrements de modèles personnalisés. Cependant, je ne sais pas comment dire à Magento d'utiliser mon extension My_Module_Model_Sitemapau lieu de juste Mage_Sitemap_Model_Sitemap, ce dernier me donnera simplement un fichier XML répertoriant toutes les mêmes catégories, produits et pages CMS que les plans de site principaux.

Le sitemapstableau a une sitemap_typecolonne, mais cela n'est jamais référencé dans la base de code Magento pour autant que je sache.

Comment puis-je utiliser le moteur de sitemap intégré de Magento tout en écrasant le Mage_Sitemap_Model_Sitemappour avoir ma propre generateXml()méthode? Ou dois-je créer un autre système de plan de site juste pour mes propres besoins ici?

Aaron Pollock
la source
vous souhaitez étendre la Mage_Sitemap_Model_Sitemapclasse et écraser à generateXml()droite? qu'as-tu essayé?
FlorinelChis
J'ai essayé, mais Magento utilise juste le Mage_Sitemap_Model_Sitemapet me donne un autre plan du site contenant les produits, les catégories, les pages CMS - il n'utilise pas ma version étendue. Je ne sais pas comment lui dire comment faire.
Aaron Pollock
Travailler sur peut-être la réécriture de l'ensemble du Mage_Sitemap_Model_Sitemapsite et ajouter mon propre modèle dans la catégorie et les appels de produits. Mettra à jour bientôt avec les progrès.
Aaron Pollock

Réponses:

6

Les étapes que j'ai fini par suivre étaient les suivantes, et les commentaires et réponses jusqu'à présent m'ont permis de commencer dans la bonne direction.

J'ai d'abord ajouté une ligne au tableau "plan du site". Étant donné que nous avons mis en place plusieurs magasins et que je veux garder mon magasin de modules agnostique, je n'ai pas codé en dur cet INSERT dans une migration MySQL, mais je l'ai simplement exécuté sur le magasin manuellement:

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

Ensuite, j'ai écrasé le Mage_Sitemap_Model_Sitemapmodèle dans la section global / models du fichier config.xml de mon propre module:

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

Cela remplace tous les appels vers l'ensemble du Mage_Sitemap_Model_Sitemapsite avec mon modèle personnalisé, mais je ne voulais pas copier et coller trop de code là-bas. En utilisant la suggestion de Petar Dzhambazov, j'ai utilisé un conditionnel pour m'en remettre à la classe parent à moins que ce ne sitemap_typesoit "people".

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

Y a-t-il une meilleure façon, qui évite de copier et coller autant de la classe parente?

Aaron Pollock
la source
1

Vous pouvez soit étendre Mage_Sitemap_Model_Sitemapet vérifier sitemap_types'il s'agit de votre type, générer votre XML, sinon générer le XML parent. Ou vous pouvez ajouter un observateur pour l' load_afterévénement de collection et ajouter votre modèle de plan de site à la collection.

Petar Dzhambazov
la source
0

Y a-t-il une meilleure façon, qui évite de copier et coller autant de la classe parente?

Si vous avez Magento> = 1.9.0.0 et que vous ne vous souciez pas de l'utilisation des produits ou de la priorité de catalogue / changement de fréquence, vous pouvez utiliser un observateur sur 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 vous souhaitez compléter le comportement différent sur les pages de sitemap, lisez peut-être Sitemap.xml changer de maison et / ou envoyer un événement plus générique .

sv3n
la source