Eu tento encontrar a melhor maneira de renderizar HTML através do AJAX no Magento 2.
Caminho 1: Usando o Controller sem layout
Arquivo Foo/Bar/Controller/Popin/Content.php
<?php
namespace Foo\Bar\Controller\Popin;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
/**
* Class Content
*/
class Content extends Action
{
/**
* Content constructor.
*
* @param Context $context
*/
public function __construct(
Context $context
) {
parent::__construct($context);
}
/**
*
*/
public function execute()
{
/** @var \Magento\Framework\View\Layout $layout */
$layout = $this->_view->getLayout();
/** @var \Foo\Bar\Block\Popin\Content $block */
$block = $layout->createBlock(\Foo\Bar\Block\Popin\Content::class);
$block->setTemplate('Foo_Bar::popin/content.phtml');
$this->getResponse()->setBody($block->toHtml());
}
}
Caminho 2: Usando o Controller com layout personalizado
Arquivo Foo/Bar/Controller/Popin/Content.php
<?php
namespace Foo\Bar\Controller\Popin;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
/**
* Class Content
*/
class Content extends Action
{
/**
* Content constructor.
*
* @param Context $context
*/
public function __construct(
Context $context
) {
parent::__construct($context);
}
/**
*
*/
public function execute()
{
$this->_view->loadLayout();
$this->_view->renderLayout();
}
}
Arquivo Foo/Bar/view/frontend/page_layout/ajax-empty.xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
<container name="root"/>
</layout>
Arquivo Foo/Bar/view/frontend/layout/foo_bar_popin_content.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="ajax-empty" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="root">
<block class="Foo\Bar\Block\Popin\Content" name="foo_bar_popin_content" template="Foo_Bar::popin/content.phtml" cacheable="false"/>
</referenceContainer>
</body>
</page>
Na IMO, a melhor prática parece ser o Caminho 2 porque separa a lógica do Controlador.
Mas o problema com o Way 2 é que o <body>
e <head>
com CSS
/ JS
são gerados, portanto, não é um HTML totalmente limpo, apenas com o meu modelo de bloco.
- estou usando o layout personalizado da maneira errada?
- O Caminho 1 é considerado uma boa prática?
- Existem outras maneiras de fazer isso?
fonte
Pronto para uso, o Magento não usa nenhum desses métodos para renderizar HTML via AJAX.
Pelo que vi, sempre que isso precisa ser feito, o JSON é usado para transportar o resultado.
Exemplo do
Magento/Checkout/Controller/Cart/Add
:Então o Magento 2 usa um novo mecanismo chamado seções, para manipular os dados no frontend e atualizar os blocos específicos que precisam ser atualizados. Você pode aprender mais sobre as seções nesta seção de perguntas e respostas: /magento//a/ 143381/2380
EDIT sobre a segunda parte da minha resposta: como afirma Max no comentário, as seções são usadas apenas com dados específicos do cliente e o uso dessa funcionalidade em vez de todas as chamadas AJAX não é a solução certa.
fonte
No meu exemplo, não posso usar
sections
porque não écustomer data
e não é depois de uma açãoPUT
/POST
, mas usando aRaphael at Digital Pianism
resposta, descobri como o Magento renderiza seções.Se usarmos o exemplo de
cart
seção, use o método\Magento\Customer\CustomerData\SectionPool::getSectionDataByNames
para recuperar dados de seções. Isso nos leva a\Magento\Checkout\CustomerData\Cart::getSectionData
uma única matriz contendo áreas da seção, incluindo$this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml()
Dependendo disso, aqui está a classe final Controller:
fonte