¿Es bueno crear una instancia de una clase getModel en plantillas phtml?

14

Esta es una pregunta sobre buenas prácticas de programación en Magento.

Necesito mostrar (en la lista de categorías de productos) el producto con sus productos relacionados en miniaturas. Así que edité mypackage/mytheme/template/catalog/product/list.phtmlcon algo como esto

<?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>';
    }
?>

Y trabaja muy bien.

Pero mi pregunta es: ¿es correcto crear instancias de una clase de modelo en los archivos phtml?

Si no es así, ¿cuál sería la mejor manera de lograr esta funcionalidad? Quiero decir, ¿qué archivo es mejor editar o qué clase es mejor agregar, dónde? Un ayudante?

¿Puede proporcionar un pequeño ejemplo o darme un vistazo de qué archivos son mejores para editar?

usuario604
fuente

Respuestas:

10

Quiero estar en desacuerdo con la respuesta de Sonassi :)

Iniciar un modelo en la plantilla es una mala práctica. A veces es necesario y a veces también lo hago. Pero si es posible, debe evitar agregar código a sus archivos pHTML y solo echodar cosas.

Es la separación de las preocupaciones . No mezcles html y cosas de codificación. Esto debería estar en la clase Block.

Fabian Blechschmidt
fuente
3
También estoy de acuerdo con tu desacuerdo :) Pero cargar un solo modelo fuera de un bucle no es el fin del mundo. De lo contrario, se convierte en un caso de abstracción infinita , agregando clases adicionales existentes simplemente para la separación de una sola línea de código de la vista. Simplemente agrega reescribir los gastos generales, sin mencionar el mantenimiento.
Ben Lessani - Sonassi
Tienes demasiado tiempo si quieres corregir todos mis errores ortográficos, gracias por eso :-)
Fabian Blechschmidt
Por cierto, tienes razón sonassi :-) Es algo con lo que debemos tener cuidado. Vi consultas SQL en archivos phtml ... NO NO :-)
Fabian Blechschmidt
4

No hay nada de malo en cargar un modelo en un phtmlarchivo. Pero depende de por qué lo estás haciendo.

Si necesita todo el modelo y todos los datos asociados con él, también puede cargar todo el modelo.

Pero si solo necesita la URL del producto (de su ejemplo), entonces podría cargar la colección correcta

$_product->getRelatedProductCollection();

Luego repita eso según sea necesario

<?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
fuente
3

Quiero poner mis 5 centavos aquí. Debemos respetar los principios de arquitectura que se usan en Magento. El patrón arquitectónico principal utilizado en Magento es MVC. En el caso de Magento, la parte "Ver" contiene varias cosas (bloque, plantilla, diseño). Se crearon bloques para mover la lógica de preparación de datos de la plantilla a otra clase para hacer que las plantillas sean más limpias y legibles para los desarrolladores frontend. Aquí quiero estar de acuerdo con Fabian.

En cuanto a las preocupaciones de Sonassi sobre demasiadas clases innecesarias, sugiero que espere impulsar MVC basado. En este caso, consideramos al controlador como un comandante que define qué bloque y qué datos debe tener. La acción en el controlador podría contener el código requerido para cargar datos y ponerlo en bloque (a través de setters mágicos) antes de renderizar.

Dmitriy Vasilenko
fuente
3

Estoy de acuerdo con Fabian Blechschmidt en que es una mala práctica y debe respetar la Separación de preocupaciones.

Para agregar una sugerencia constructiva:

Esto es algo para lo que están destinadas las clases Block. En su caso, tendría que volver Mage_Catalog_Block_Product_List a escribir para agregar la funcionalidad deseada:

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;
}

Debería ser obvio cómo usar estos métodos en la plantilla.

Nota: Reescribir no significa editar el archivo principal. Siga el tutorial de personalización si no sabe cómo reescribir un bloque.

Fabian Schmengler
fuente