Afficher le montant total sur le lien panier du header (top.links)
- Par Magentix le 12/10/2009
- Difficulté : 2/4
Voici comment modifier le lien "Mon panier" de la référence top.links du block header afin d'y insérer le montant total du panier à la place du nombre de produits ajoutés.
De nombreuse demandes m'ont été adressées pour une explication sur la manière de substituer dans le lien "Mon panier" du header le nombre de produits ajoutés par le montant total du panier. Voici comment procéder.
Pour afficher la donnée sur le nombre d'articles présents dans le panier, Magento utilise la méthode addCartLink de la classe Mage_Checkout_Block_Links :
app/design/frontend/default/{interface}/{theme}/layout/checkout.xml
<reference name="top.links">
<block type="checkout/links" name="checkout_cart_link">
<action method="addCartLink"></action>
<action method="addCheckoutLink"></action>
</block>
</reference>
Une idée serait donc de surcharger le block checkout/links et d'apporter les modifications nécessaires. Je préfère cependant éviter de manière général d'employer la surcharge (une habitude). Nous allons dans un premier temps utiliser la méthode "créer un nouveau bloc". Nous verrons tout de même dans un second temps la méthode "surcharge". A vous de choisir.
Architecture du module
- app/code/local/Magentix/CartLink/Block/
- Links.php
- app/code/local/Magentix/CartLink/etc/
- config.xml
- app/etc/modules/
- Magentix_CartLink.xml
Développement du module
Notre nouveau block ne contient qu'une seul méthode dont le but est de récupérer le montant total cumulé des produits du panier. Afin de simplifier au maximum, nous considérerons que la taxe est appliquée (montant affiché en TTC).
app/code/local/Magentix/CartLink/Block/Links.php
<?php
class Magentix_CartLink_Block_Links extends Mage_Core_Block_Template {
public function addCartLink()
{
if ($parentBlock = $this->getParentBlock()) {
$totals = $this->helper('checkout/cart')->getQuote()->getTotals();
if (isset($totals['subtotal']) && intval($totals['subtotal']->getValue())) {
$amount = number_format($totals['subtotal']->getValue()+$totals['tax']->getValue(),2,',','.');
$text = $this->__('My Cart (%s €)', $amount);
} else {
$text = $this->__('My Cart');
}
$parentBlock->addLink($text, 'checkout/cart', $text, true, array(), 50, null, 'class="top-link-cart"');
}
return $this;
}
}
Il ne reste plus qu'à éditer notre fichier config.xml...
app/code/local/Magentix/CartLink/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_CartLink>
<version>1.1</version>
</Magentix_CartLink>
</modules>
<global>
<blocks>
<magentix_cartlink>
<class>Magentix_CartLink_Block</class>
</magentix_cartlink>
</blocks>
</global>
</config>
Après avoir déclaré à Magento le nouveau module depuis le fichier Magentix_CartLink.xml (et actualisé le cache...), nous sommes en mesure d'utiliser le nouveau block magentix_cartlink/links. Depuis les layouts nous pouvons supprimer la déclaration initiale de la méthode addCartLink et ajouter celle du block de notre module :
app/design/frontend/default/{interface}/{theme}/layout/checkout.xml
<reference name="top.links">
<block type="checkout/links" name="checkout_link">
<action method="addCheckoutLink"></action>
</block>
<block type="magentix_cartlink/links" name="cart_link">
<action method="addCartLink"></action>
</block>
</reference>
Pour les traductions cela se passe dans le fichier de langue checkout.csv.
Architecture du module
- app/code/local/Magentix/CartLink/Block/
- Links.php
- app/code/local/Magentix/CartLink/etc/
- config.xml
- app/etc/modules/
- Magentix_CartLink.xml
Jusque là rien de bien différent... La classe Magentix_CartLink_Block_Links sera strictement identique, mise à part qu'elle héritera cette fois ci de la classe Mage_Checkout_Block_Links (block surchargé) :
app/code/local/Magentix/CartLink/Block/Links.php
<?php
class Magentix_CartLink_Block_Links extends Mage_Checkout_Block_Links {
public function addCartLink()
{
if ($parentBlock = $this->getParentBlock()) {
$totals = $this->helper('checkout/cart')->getQuote()->getTotals();
if (isset($totals['subtotal']) && intval($totals['subtotal']->getValue())) {
$amount = number_format($totals['subtotal']->getValue()+$totals['tax']->getValue(),2,',','.');
$text = $this->__('My Cart (%s €)', $amount);
} else {
$text = $this->__('My Cart');
}
$parentBlock->addLink($text, 'checkout/cart', $text, true, array(), 50, null, 'class="top-link-cart"');
}
return $this;
}
}
Dans le fichier de configuration il ne reste plus qu'à spécifier la surcharge :
app/code/local/Magentix/CartLink/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Magentix_CartLink>
<version>1.2</version>
</Magentix_CartLink>
</modules>
<global>
<blocks>
<checkout>
<rewrite>
<links>Magentix_CartLink_Block_Links</links>
</rewrite>
</checkout>
</blocks>
</global>
</config>
La méthode bonus pour le fun ;). Nous allons ajouter à la méthode n°2 un Observer afin d'éviter la modification manuelle du fichier layout checkout.xml du thème.
Architecture du module
- app/code/local/Magentix/CartLink/Block/
- Links.php
- app/code/local/Magentix/CartLink/etc/
- config.xml
- app/code/local/Magentix/CartLink/Model/
- Observer.php
- app/etc/modules/
- Magentix_CartLink.xml
L'observer surveillera l'événement controller_action_layout_generate_blocks_before. Nous allons ainsi pouvoir agir sur le layout avant que les blocs ne soit générés. L'objectif est de supprimer la déclaration de la méthode addCheckoutLink du block checkout/links puis d'ajouter le nouveau bloc, enfant de la référence top.links :
app/code/local/Magentix/CartLink/Model/Observer.php
<?php
class Magentix_CartLink_Model_Observer {
public function CartLinkBlock($observer) {
$layout = $observer->getLayout();
$toplinks = $layout->getXpath("//reference[@name='top.links']");
$addCartLink = $layout->getXpath("//action[@method='addCartLink']");
if (!$toplinks) return $this;
if($addCartLink) $addCartLink[0]->addAttribute('ignore', true);
$block = $toplinks[0]->addChild('block');
$block->addAttribute('type', 'magentix_cartlink/links');
$block->addAttribute('name', 'cartlink_link');
$block->addAttribute('as', 'cartlink_link');
$action = $block->addChild('action');
$action->addAttribute('method','addCartLink');
return $this;
}
}
Ajoutons pour finir l'observer dans le fichier de configuration :
app/code/local/Magentix/CartLink/Model/Observer.php
<?xml version="1.0"?>
<config>
<modules>
<Magentix_CartLink>
<version>1.3</version>
</Magentix_CartLink>
</modules>
<global>
<blocks>
<magentix_cartlink>
<class>Magentix_CartLink_Block</class>
</magentix_cartlink>
</blocks>
<models>
<cartlink>
<class>Magentix_CartLink_Model</class>
</cartlink>
</models>
<events>
<controller_action_layout_generate_blocks_before>
<observers>
<magentix_cartlink_observer>
<type>singleton</type>
<class>cartlink/observer</class>
<method>CartLinkBlock</method>
</magentix_cartlink_observer>
</observers>
</controller_action_layout_generate_blocks_before>
</events>
</global>
</config>
Nice post!! :D
petite remarque : il me semble qu'il est possible d'utiliser
$totals['grand_total']->getValue()
au lieu de
$totals['subtotal']->getValue()+$totals['tax']->getValue()
utilisé dans le block (Links.php).
Merci pour le post.
Dee
juste pour une explication
j'ai 150 produits dans mon catalogue et je veux afficher 15 produits par page et mettre des numéro de page en bas pour visualiser les reste (c'est à dire faire un affichage page par page) en php simple je sais le fais avec la requête LIMIT de sql mais avec magento je sèche
Pouvez- vous m'aider?
merci
je vais fouiller çà car j'étais là bas tout à l'heure
merci
c'est bon c'est que j'avais désactivé la fonction car je remplace le code par mon propre code
merci encore de m'avoir remis sur la bonne voie
juste pour une idée
voilà
j'aimerai afficher en bas de la page vue produit (category/product/view.phtml) le reste des produits de la même catégorie (comme sur la page list produit list.phtml) que je vais défiler au moyen d'un jquery (là n'est pas le pb)
le pb est la récupération de l'objet $_productCollection=$this->getLoadedProductCollection() ds la page view.phtml
aviez vous une idée de la faisabilité?
merci
$categories = $_product->getCategoryIds();
if(count($categories)) {
$category = Mage::getModel('catalog/category')->load($categories);
$_collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('name')
->addAttributeToSelect('small_image')
->addAttributeToFilter('status', 1)
->setOrder('name','asc')
->addCategoryFilter($category);
}
En fait il faut éviter de passer par un "Mage::registry('current_category')" pour récupérer la catégorie en cours. Sa valeur diffère selon la page d'où provient l'internaute (accueil, catégorie...).
Dans la méthode proposée le seul problème que l'on pourrait rencontrer c'est le cas ou le produit est associé à plusieurs catégories... Mais on a pas trop le choix.
je ne sais pas qui répond aux questions mais vos réponses me sont d'un grand secours
merci et encore grand merci
juste pour avoir une information
j'ai un produit qui est décliné en divers taille, couleur ..(comme sur le site de décathlon) je cherche à récupérer la valeur du choix du client l'hors de ces achats (par exemple s'il choisit taille XL ,couleur noire que je puisse la récupérer) en php simple je l'ai fait avec les formulaire mais ici je n'y arrive pas du tout j'ai créé des modules pour mais rien n'y fi
si vous aviez une idée je suis preneur
merci
juste pour savoir quel est la méthode utilisée par magento pour récupérer les valeurs des attributs où options choisis par le client dans le panier
merci