Magento2: Ajouter un modèle personnalisé à la page de détails du produit ci-dessous ajouter à la section panier

10

J'essaie d'ajouter un modèle personnalisé à la page du produit dans la section de partage social. Dans mon module, j'ai le code suivant dans le fichier de disposition default.xml

 <body>
 <referenceContainer name="product.info.social">
  <block class="Magento\Framework\View\Element\Template" name="product.info.custom" template="Lapisbard_Product::social.phtml" after="product.info.addtocart">
  </block>
 </referenceContainer>
</body>

contenu social.phtml

<p>Hey there !</p>
<?php //$_product = $block->getProduct();

Cela fonctionne bien et affiche le contenu du modèle sur la page du produit. Lorsque j'utilise la classe de bloc au Magento\Catalog\Block\Product\Viewlieu de Magento\Framework\View\Element\Templatepour que je puisse obtenir un objet produit dans mon modèle $block->getProduct();, cela montre une page vierge.

1. Quelle erreur je fais ici?
2. Quelle est la meilleure façon de modifier la page produit?
3. Existe-t-il un fichier de mise en page de référence que je peux utiliser pour ajouter de nouveaux modèles à n'importe quelle section de la page produit écrivant le code de mise en page dans mon module?

amitshree
la source
@amiteshree peut être votre fichier phtml comprend des fonctions définies dans le fichier de bloc Magento \ Catalog \ Block \ Product \ View
Shaheer Ali
@ShaheerAli: Dans mon fichier phtml, j'essaie d'obtenir l'objet produit en utilisant $_product = $block->getProduct();lorsque j'utilise le Magento\Catalog\Block\Product\Viewbloc.
amitshree
Alors pourquoi attribuez-vous le bloc Magento \ Framework \ View \ Element \ Template à votre modèle.
Shaheer Ali du
1
@amiteshree si vous souhaitez utiliser les fonctions d'affichage des produits, vous devez affecter Magento \ Catalog \ Block \ Product \ View à votre modèle phtml. Et votre méthode pour ajouter un modèle personnalisé à la page du produit est correcte
Shaheer Ali
1
Une page blanche signifie généralement qu'une erreur s'est produite. Avez-vous regardé dans votre error.log? journal des exceptions de magento? Quel mode utilisez-vous?
Anton Kril

Réponses:

24

L'erreur "page blanche" vient parce que nous Magento\Framework\View\Element\Templaten'avons pas de getProduct()méthode.

Je pense donc que la façon la plus "propre" de le faire est de créer un module personnalisé avec un bloc, une disposition et un modèle personnalisés (ne vous inquiétez pas, cela ne prend que quelques minutes et vous avez fait quelques parties)

Fichiers de module:

entrez la description de l'image ici

(Je vais sauter /etc/module.xmlet registration.phpparce que c'est trivial, cependant vous pouvez trouver l'exemple complet ici .)

Commençons par le fichier Block php:

Test \ Catalogue \ Block \ Product \ View \ Extra.php

<?php

namespace Test\Catalog\Block\Product\View;

use Magento\Catalog\Block\Product\AbstractProduct;

class Extra extends AbstractProduct
{

}

Comme vous pouvez le voir, ce n'est qu'une classe concrète qui étend (IMO) le bloc abstrait de produit le plus léger. Vous pouvez également étendre, Magento\Framework\View\Element\Templatemais dans ce cas, vous devrez implémenter la getProduct()méthode et modifier le contexte dans le constructeur afin d'accéder au registre.

Permet donc de passer au fichier de mise en page:

Test / Catalogue / view / frontend / layout / catalog_product_view.xml

<?xml version="1.0"?>
<body>
    <referenceContainer name="product.info.social">
        <block class="Test\Catalog\Block\Product\View\Extra"
            name="product.view.extra"
            template="Test_Catalog::product/view/extra.phtml"
            after="-">
        </block>
    </referenceContainer>
</body>

Et enfin le fichier modèle:

Test / Catalogue / vue / frontend / modèles / produit / vue / extra.phtml

<?php /* @var $block \Test\Catalog\Block\Product\View\Extra */?>
<?php $_product = $block->getProduct() ?>
<h3><?php echo 'My Product Name Is: ' . $_product->getName(); ?></h3>

Comme vous pouvez le voir, c'est assez simple, plus simple que M1-

N'oubliez pas que toute votre logique personnalisée doit être implémentée dans la Extra.phpclasse de bloc afin de garder la vue propre.

c'est à dire:

Dans la classe Extra.php :

public function getSomething()
{
    return 'something'
}

dans la vue extra.phtml :

<?php echo $block->getSomething() ?>
MauroNigrele
la source
2
Ainsi, la mise en page catalog_product_view.xml de mon module se charge automatiquement lorsque je suis sur la page du produit?
amitshree
2
Absolument! il est très similaire à M1 mais maintenant chaque handle est dans un fichier séparé.
MauroNigrele
5

Un supplément pour la réponse acceptée

La réponse acceptée est bonne, mais elle AbstractProductest désormais obsolète .

/**
 * Class AbstractProduct
 * @api
 * @deprecated 101.1.0
 * @SuppressWarnings(PHPMD.NumberOfChildren)
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @since 100.0.2
 */
class AbstractProduct extends \Magento\Framework\View\Element\Template

Donc, nous devons utiliser le Magento\Framework\Registrypour obtenir le bloc , l'exemple de bloc est ci-dessous:

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\Registry;

class ProductView extends Template
{
    /**
     * @var Registry
     */
    protected $registry;

    /**
     * @var \Magento\Catalog\Model\Product
     */
    protected $product;

    /**
     * ProductView constructor.
     * @param Template\Context $context
     * @param array $data
     * @param Registry $registry
     */
    public function __construct(
        Template\Context $context,
        array $data = [],
        Registry $registry
    )
    {
        $this->registry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
        if (is_null($this->product)) {
            $this->product = $this->registry->registry('product');
        }

        return $this->product;
    }
}
Key Shang
la source