36 votes

Comment puis-je inclure un bloc dynamique dans la page du produit avec la mise en cache pleine page activée?

Nous aimerions ajouter un bloc dynamique à la page du produit. Le problème est que la page du produit a pleine page en cache (et on ne peut pas désactiver cette fonction en raison de problèmes de vitesse). Nous voulons afficher des informations différentes sur chaque page de produit basé sur l'enregistrés dans le compte de l'utilisateur, et elle varie d'un produit à l'autre.

J'ai créé un bloc séparé qui dispose de sa propre mise en cache, mais cela affiche le même pâté de maisons de la précédente page du produit. Je suis en train de modifier la méthode de mise en cache afin de ne pas enregistrer le cache de la précédente page du produit.

Il fonctionne de la premières fois que je vais à la page produits, mais tout à coup commence à afficher un Magento page d'erreur qui dit que, "Le site web a rencontré une erreur lors de la récupération http://www.mycompany.com/productpage.html. Il peut être arrêté pour maintenance ou configuré de manière incorrecte."

Voici ce que j'ai fait jusqu'à présent. J'ai créé app/code/local/MyCompany/MyModule/PageCache/etc/config.xml pour ajouter MyCompany_PageCache_Model.

Puis j'ai créé le fichier qui contrôle la mise en cache dans app/code/local/MyCompany/MyModule/PageCache/Model/Container/MyFile.php avec ces fonctions:

protected function _getCacheId()
{
    return 'CONSTANT_CACHE' . md5($this->_placeholder->getAttribute('cache_id'));
}

protected function _saveCache($data, $id, $tags = array(), $lifetime = null)
{
    return false;
}

protected function _renderBlock()
{
    $blockClass = $this->_placeholder->getAttribute('block');
    $template = $this->_placeholder->getAttribute('template');

    $block = new $blockClass;
    $block->setTemplate($template);
    $block->setLayout(Mage::app()->getLayout());
    return $block->toHtml();
}

J'ai également créé cache.xml en vertu de Catalogue/etc avec mon espace réservé pour CONSTANT_CACHE.

Est la syntaxe ci-dessus incorrecte, ou est-il un moyen plus facile de faire cela?

124voto

Vinai Points 9789

Vue d'ensemble

Afin de répondre j'ai besoin d'expliquer un peu d'abord. Le Magento FPC processus connaît quatre états.

  1. Page en cache, pas de blocs dynamiques
  2. La Page dans le cache de blocs dynamiques mises en cache
  3. La Page dans le cache de blocs dynamiques, pas de mise en cache
  4. De la Page dans le cache

L'état 1 et 2 sont traitées sans la pleine Magento application en cours d'initialisation. L'état 3 et 4 nécessitent l'application d'être initialisé et le routage pour être traitées. Pour cette raison, visent à répondre à des demandes de l'état 1 et 2, si possible, sinon vous perdez une grande partie des améliorations possibles de la FPC.

L'état 1

L'état 1 est ennuyeux à partir d'un développeur point de vue, rien à faire, donc permet de passer à...

L'état 2

Dans l'état 2 un page contient des blocs dynamiques. Maintenant, Magento n'a pas été entièrement initialisé.
La FPC processeur de chargement d'une page en cache et trouve un espace réservé pour un bloc dynamique dans il.
Par l'analyse de l'espace réservé, le processeur est capable d'identifier la classe de conteneur pour le bloc dynamique, instancie et appelle applyWithoutApp($content) sur il. (Le nom de la méthode se réfère au fait que le Magento application n'a pas été initialisé à ce jour). Le conteneur, puis tente de charger le bloc dynamique le contenu du bloc de cache, à l'aide de la clé de cache retourné par la méthode $this->_getCacheId().
Si une clé de cache est retourné et une entrée de cache peut être chargé, de la classe container remplace l'espace réservé à l' $content avec la mise en cache de sortie du bloc et de la FPC est fait.
Pour l'instant, pas beaucoup de frais généraux n'a été produit.

L'état 3

Donc, applyWithoutApp($content) dans l'état 2 a été impossible de récupérer et livrer la dynamique de bloquer le contenu, de sorte que le bloc de contenu doit être générée, même si le reste de la page a été trouvée dans la FPC.
Pour cette raison, la FPC module définit la demande d' pagecache/request/process, et le régulier Magento d'initialisation de l'application et de routage est suivie.
Cela signifie beaucoup plus de surcharge est produit ensuite avec l'état 2, même si elle est un peu plus ordinaire de chargement de la page sans la FPC, parce que par exemple, l'URL rewriting est ignorée.
Enfin, le contrôleur frontal et routeur standard délégué de la demande à l' RequestController::processAction()méthode.
La méthode extrait précédemment instancié classe de conteneur pour les blocs dynamiques, et des appels applyInApp($content) sur il.
Cette méthode s'exécute $this->_renderBlock() d'instancier la réelle d'un bloc de classe et de retour il est de sortie. Vous avez déjà mis cette méthode en fonction de votre question. La FPC pouvez maintenant remplacer l'espace réservé avec le bloc de contenu et de livrer la page.
Une chose d'être conscient de , c'est que ce n'est pas un produit de la page de détail de la demande, de sorte que par exemple, Mage::registry('current_product') n'est pas disponible! En fonction de votre bloc de mise en œuvre, cela pourrait influer sur le niveau de l'îlot de la mise en cache ou que le contenu du bloc dynamique. Je soupçonne que cela pourrait être l'endroit où votre problème vient du fait que, mais je vais arriver à une solution un peu plus bas.

État 4

Dans cet état de la FPC n'ai pas trouvé l'enregistrement de cache de la page demandée, de sorte que Magento génère la page comme d'habitude, par exemple, la page détaillée du produit de sortie est créé par l' Mage_Catalog_ProductController::viewAction().
Tous les blocs qui sont configurés pour être dynamique, selon l' cache.xml, sont enveloppés dans l'espace réservé aux tags.
L'espace réservé balises contiennent des arguments, qui sont ensuite transmises à l'objet conteneur pour l'étape 2 et 3. Les seuls arguments qui sont toujours ensemble sont le conteneur et le bloc de la classe des noms. Mais, presque toujours, une cache_id et template sont définies ainsi.
Dans la classe conteneur, ces valeurs peuvent être accédées en utilisant $this->_placeholder->getAttribute('cache_id') (comme vous l'avez fait dans la _getCacheId() la méthode de votre récipient).

Même si vous où dissimuler la plupart de cette longue réponse, c'est là que ça peut devenir intéressant pour vous. Si vous avez besoin d'autres valeurs pour générer les blocs de cache d'id ou de la sortie du bloc, (par exemple, l'id du produit ou le numéro de client), vous pouvez les définir comme des arguments de l'espace réservé.

Pour ce faire, vous devez les fixer sur le tableau retourné par le bloc getCacheKeyInfo() méthode avec une chaîne en un tableau de clés. Si vous utilisez un tableau numérique de l'indice qu'ils ne seront pas fixés comme arguments sur l'espace réservé.

public function getCacheKeyInfo() {
    $info = parent::getCacheKeyInfo();
    $info['current_product_id'] = Mage::registry('current_product')->getId();
    $info['customer_id'] = Mage::getSingleton('customer/session')->getCustomerId();
    return $info;
}

Ces valeurs sont désormais accessibles dans la classe de conteneur à l'aide de $this->_placeholder->getAttribute('current_product_id').

Conclusion

Vous ne voulez probablement pas à remplacer _saveCache() dans votre classe de conteneur pour revenir false. Au lieu de cela, inclure le numéro de client et l'id du produit dans la chaîne de caractères retournée par _getCacheId(). De cette façon, chaque client a sa propre entrée de cache. Des coûts seront réduits, car applyWithoutApp() pouvez sauvegarder et charger le bloc dynamique de la mémoire cache (si une page est affichée deux fois par le même client).

En _renderBlock() aux valeurs que vous avez besoin pour le bloc pour être en mesure de générer du contenu sur elle, par exemple

$block->setProductId($this->_placeholder->getAttribute('current_product_id'));

Sur le bloc côté des choses, y compris l'id de produit et l'id du client en cache info matrice de s'assurer que chaque client est à la sortie correcte de la page demandée, même lorsque le bloc est mis en cache.

Je ne peux pas savoir pour assurer que, (vous n'avez pas fourni le bloc de code), mais je soupçonne que le cache d'id que vous utilisez ne contient pas tous les arguments qu'il a besoin de mettre en correspondance l'enregistrement de cache pour le bloc à droite du produit.

L'utilisation de la procédure et de savoir comment passer des arguments à une dynamique de bloc conteneur, il est possible de conserver la majorité de la FPC gain de performance, même lors de la création de blocs dynamiques. J'espère que cette information est assez pour vous d'être en mesure de traquer le problème que vous décrivez et de le corriger.

5voto

Jim OHalloran Points 4034

En général, il existe deux approches que vous pouvez utiliser si vous souhaitez personnaliser une page qui est destiné à être stocké dans une pleine page en cache.

  1. Si votre reverse proxy prend en charge, vous pouvez utiliser ESI (Edge Side includes) et de marquer votre modèle approprié. ESI vous permet d'insérer un marqueur dans votre code HTML généré lorsque le contenu personnalisé devrait aller, puis votre proxy demande juste le contenu personnalisé à partir de votre serveur d'application est approprié contrôleur de chemin d'accès, lorsque nécessaire. Si vous êtes à l'aide de Vernis, ESI est disponible pour utilisation. La Lightspeed extension pour Magento dispose d'une fonction appelée "perforation" qui fait une chose semblable.
  2. Si ESI ou la perforation n'est pas disponible pour vous, alors l'autre option est de permettre la page principale pour être mis en cache dans votre pleine cache de la page, et utiliser un peu de javascript pour faire un autre requête Ajax et aller chercher les informations dont vous avez besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X