É bom instanciar uma classe getModel em modelos phtml?

14

Esta é uma pergunta sobre boas práticas de programação no Magento.

Preciso mostrar (na lista de produtos da categoria) o produto com seus produtos relacionados em miniaturas. Então eu editei mypackage/mytheme/template/catalog/product/list.phtmlcom algo assim

<?php 
    $related=$_product->getRelatedProductIds();
    if(count($related)>0){
        echo '<div class="a'.$ap.'"></div>';
        echo '<div class="li_p"><ul>';
        foreach($related as $rela){
            $rela_nom=Mage::getModel('catalog/product')->load($rela);
            echo '<li><a href="'.$rela_nom->getProductUrl().'"> <img src="'.$this->helper('catalog/image')->init($rela_nom, 'small_image')->resize(20).'" width="20" height="20"> </a><li>';
        }
        echo '</ul></div>';
    }
?>

E funciona muito bem.

Mas minha pergunta é: está correto instanciar uma classe de modelo nos arquivos phtml?

Caso contrário, qual seria a melhor maneira de obter essa funcionalidade? Quero dizer, qual arquivo é melhor editar ou que classe é melhor adicionar, onde? Um ajudante?

Você pode dar um pequeno exemplo ou dar uma olhada em quais arquivos são melhores para editar.

user604
fonte

Respostas:

10

Quero discordar da resposta de Sonassi :)

Iniciar um modelo no modelo é uma prática ruim. Às vezes é necessário e às vezes eu também faço. Mas, se for possível, evite adicionar código aos arquivos pHTML e apenas algumas echocoisas.

É separação de preocupações . Não misture html e material de codificação. Isso deve estar na classe Block.

Fabian Blechschmidt
fonte
3
Também concordo com sua discordância :) Mas carregar um único modelo fora de um loop não é o fim do mundo. Caso contrário, torna-se um caso de abstração infinita - adicionando classes adicionais existentes apenas para a separação de uma única linha de código da visualização. Isso apenas contribui para reescrever as despesas gerais, sem mencionar a manutenção.
Ben Lessani - Sonassi
Você tem tempo demasiado mich se você quer consertar todos os erros de ortografia, obrigado por isso :-)
Fabian Blechschmidt
Btw, você está certo sonassi :-) É apenas algo que devemos ter cuidado. Vi querys SQL em PHTML-arquivos ... NÃO NÃO :-)
Fabian Blechschmidt
4

Não há nada errado em carregar um modelo em um phtmlarquivo. Mas depende de por que você está fazendo isso.

Se você precisar de todo o modelo e de todos os dados associados, também poderá carregar o modelo inteiro.

Mas se você apenas precisar do URL do produto (do seu exemplo), poderá carregar a coleção correta

$_product->getRelatedProductCollection();

Em seguida, repita isso conforme necessário

<?php $_relatedCollection = $_product->getRelatedProductCollection(); ?>
<?php foreach ($_relatedCollection as $_item): ?>
<li>
  <a href="<?php echo $_item->getProductUrl(); ?>">
    <img src="<?php echo $this->helper('catalog/image')->init($_item, 'small_image')->resize(20); ?>" width="20" height="20">
  </a>
<li>
<?php endforeach; ?>
Ben Lessani - Sonassi
fonte
3

Quer colocar meus 5 centavos aqui. Devemos respeitar os princípios da arquitetura que são usados ​​no Magento. O principal padrão arquitetural usado no Magento é o MVC. No caso do Magento "View", a parte contém várias coisas (bloco, modelo, layout). Os blocos foram criados para mover a lógica de preparação de dados do modelo para outra classe para tornar os modelos mais limpos e legíveis para os desenvolvedores de front-end. Aqui eu quero concordar com Fabian.

Quanto às preocupações de Sonassi sobre muitas classes desnecessárias, sugiro esperar ansiosamente por MVC baseado em push. Nesse caso, consideramos o controlador como comandante que define qual bloco e quais dados devem ter. A ação no controlador pode conter o código necessário para carregar os dados e colocá-los em bloco (por meio de setters mágicos) antes da renderização.

Dmitriy Vasilenko
fonte
3

Concordo com Fabian Blechschmidt que é uma prática ruim e você deve respeitar a Separação de Preocupações.

Para adicionar uma sugestão construtiva:

Isso é algo para o qual as classes Block são destinadas. No seu caso, você teria que reescrever Mage_Catalog_Block_Product_List para adicionar a funcionalidade desejada:

public function hasRelatedProducts()
{
    return count($this->getRelatedProductIds()) > 0;
}
public function getRelatedProducts()
{
    $products = array();
    foreach ($this->getRelatedProductIds() as $id) {
        $products[] = Mage::getModel('catalog/product')->load($id);
    }
    return $products;
}

Deve ser óbvio como usar esses métodos no modelo.

Nota: Reescrever não significa editar o arquivo principal. Siga o tutorial de customização se você não souber reescrever um bloco.

Fabian Schmengler
fonte